aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpetrs2016-09-27 22:02:22 +0200
committerpetrs2016-09-27 22:02:22 +0200
commita01a56822281c7821a39903f35905eedd9191fd2 (patch)
tree7ee6477d775f7e39cb1e14e8b9850e39e960cb1d
parenta550c093ad6d28020b135fa33580c8d2fbc71048 (diff)
downloadECTester-a01a56822281c7821a39903f35905eedd9191fd2.tar.gz
ECTester-a01a56822281c7821a39903f35905eedd9191fd2.tar.zst
ECTester-a01a56822281c7821a39903f35905eedd9191fd2.zip
-rw-r--r--src/applets/SimpleECCApplet.java158
-rw-r--r--src/simpleapdu/SimpleAPDU.java56
2 files changed, 205 insertions, 9 deletions
diff --git a/src/applets/SimpleECCApplet.java b/src/applets/SimpleECCApplet.java
index 8332b3c..6f734ac 100644
--- a/src/applets/SimpleECCApplet.java
+++ b/src/applets/SimpleECCApplet.java
@@ -22,6 +22,8 @@ public class SimpleECCApplet extends javacard.framework.Applet
final static byte INS_TESTECSUPPORTALL_FP = (byte) 0x5e;
final static byte INS_TESTECSUPPORTALL_F2M = (byte) 0x5f;
+ final static byte INS_TESTEC_GENERATEINVALID_FP = (byte) 0x70;
+
@@ -53,7 +55,8 @@ public class SimpleECCApplet extends javacard.framework.Applet
public final static short FLAG_ECTEST_ALL = (short) 0x00ff;
- public final static short SW_SKIPPED = (short) 0x0ee1;
+ public final static short SW_SKIPPED = (short) 0x0ee1;
+ public final static short SW_KEYPAIR_GENERATED_INVALID = (short) 0x0ee2;
/*
public static final byte[] EC192_FP_PUBLICW = new byte[]{
(byte) 0x04, (byte) 0xC9, (byte) 0xC0, (byte) 0xED, (byte) 0xFB, (byte) 0x27,
@@ -95,6 +98,7 @@ public class SimpleECCApplet extends javacard.framework.Applet
private ECPrivateKey ecPrivKey256 = null;
private KeyAgreement dhKeyAgreement = null;
+ private RandomData randomData = null;
// TEMPORARRY ARRAY IN RAM
private byte m_ramArray[] = null;
@@ -118,6 +122,8 @@ public class SimpleECCApplet extends javacard.framework.Applet
m_dataArray = new byte[ARRAY_LENGTH];
Util.arrayFillNonAtomic(m_dataArray, (short) 0, ARRAY_LENGTH, (byte) 0);
+
+ randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
}
register();
@@ -159,6 +165,9 @@ public class SimpleECCApplet extends javacard.framework.Applet
case INS_DERIVEECDHSECRET:
DeriveECDHSecret(apdu);
break;
+ case INS_TESTEC_GENERATEINVALID_FP:
+ TestEC_FP_GenerateInvalidCurve(apdu);
+ break;
/*
case INS_ALLOCATEKEYPAIRS:
@@ -406,7 +415,7 @@ public class SimpleECCApplet extends javacard.framework.Applet
Util.setShort(buffer, bufferOffset, SW_SKIPPED);
bufferOffset += 2;
}
-
+
return (short) (bufferOffset - baseOffset);
}
@@ -440,7 +449,150 @@ public class SimpleECCApplet extends javacard.framework.Applet
apdu.setOutgoingAndSend((short) 0, dataOffset);
}
- void AllocateKeyPairReturnDefCourve(APDU apdu) {
+ void TestEC_FP_GenerateInvalidCurve(APDU apdu) {
+ byte[] apdubuf = apdu.getBuffer();
+ short len = apdu.setIncomingAndReceive();
+
+ short dataOffset = 0;
+
+ // FP
+ dataOffset += TestECSupportInvalidCurve(KeyPair.ALG_EC_FP, (short) 160, apdubuf, dataOffset, apdubuf[ISO7816.OFFSET_P1]);
+
+ apdu.setOutgoingAndSend((short) 0, dataOffset);
+ }
+
+ short TestECSupportInvalidCurve(byte keyClass, short keyLen, byte[] buffer, short bufferOffset, short repeats) {
+ short baseOffset = bufferOffset;
+
+ short testFlags = FLAG_ECTEST_ALL;
+
+ ecKeyPair = null;
+ ecPubKey = null;
+ ecPrivKey = null;
+
+ buffer[bufferOffset] = ECTEST_SEPARATOR;
+ bufferOffset++;
+ buffer[bufferOffset] = keyClass;
+ bufferOffset++;
+ Util.setShort(buffer, bufferOffset, keyLen);
+ bufferOffset += 2;
+
+ //
+ // 1. Allocate KeyPair object
+ //
+ buffer[bufferOffset] = ECTEST_ALLOCATE_KEYPAIR;
+ bufferOffset++;
+ if ((testFlags & FLAG_ECTEST_ALLOCATE_KEYPAIR) != (short) 0) {
+ try {
+ ecKeyPair = new KeyPair(keyClass, keyLen);
+ ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
+ ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
+ // Some implementation wil not return valid pub key until ecKeyPair.genKeyPair() is called
+ // Other implementation will fail with exception if same is called => try catch
+ try {
+ if (ecPubKey == null) {
+ ecKeyPair.genKeyPair();
+ }
+ } catch (Exception e) {
+ } // do intentionally nothing
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_NO_ERROR);
+ bufferOffset += 2;
+ } catch (CryptoException e) {
+ Util.setShort(buffer, bufferOffset, e.getReason());
+ bufferOffset += 2;
+ testFlags = 0; // Can't continue if keypair was not allocated
+ } catch (Exception e) {
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_UNKNOWN);
+ bufferOffset += 2;
+ testFlags = 0; // Can't continue if keypair was not allocated
+ }
+ } else {
+ Util.setShort(buffer, bufferOffset, SW_SKIPPED);
+ bufferOffset += 2;
+ }
+
+ //
+ // 2. Set invalid custom curve (many times)
+ //
+ EC_Consts.m_random = randomData;
+ EC_Consts.setValidECKeyParams(ecPubKey, ecPrivKey, keyClass, keyLen, m_ramArray);
+ short lenB = ecPubKey.getB(m_ramArray, (short) 0); // store valid B
+
+ short startOffset = bufferOffset;
+// for (short i = 0; i < repeats; i++) {
+ for (short i = 0; i < (short) 1000; i++) {
+ if ((testFlags & FLAG_ECTEST_SET_INVALIDCURVE) != (short) 0) {
+ bufferOffset = startOffset;
+
+ // set invalid curve
+ buffer[bufferOffset] = ECTEST_SET_INVALIDCURVE;
+ bufferOffset++;
+ randomData.generateData(m_ramArray2, (short) 0, lenB);
+ ecPubKey.setB(m_ramArray2, (short) 0, lenB);
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_NO_ERROR);
+ bufferOffset += 2;
+
+ // Gen key pair with invalid curve
+ try {
+ buffer[bufferOffset] = ECTEST_GENERATE_KEYPAIR_INVALIDCUSTOMCURVE;
+ bufferOffset++;
+ // Should fail
+ ecKeyPair.genKeyPair();
+ // If this line is reached, we generated valid key pair - what should not happen
+ Util.setShort(buffer, bufferOffset, SW_KEYPAIR_GENERATED_INVALID);
+ bufferOffset += 2;
+ // if we reach this line, we are interested in value of B
+ Util.arrayCopyNonAtomic(m_ramArray2, (short) 0, buffer, bufferOffset, lenB);
+ bufferOffset += lenB;
+ break; // stop execution, return B
+ } catch (CryptoException e) {
+ Util.setShort(buffer, bufferOffset, e.getReason());
+ bufferOffset += 2;
+ } catch (Exception e) {
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_UNKNOWN);
+ bufferOffset += 2;
+ }
+
+ //
+ // Generate keypair with valid curve
+ //
+ // set valid curve
+ buffer[bufferOffset] = ECTEST_SET_VALIDCURVE;
+ bufferOffset++;
+ ecPubKey.setB(m_ramArray, (short) 0, lenB); // valid B
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_NO_ERROR);
+ bufferOffset += 2;
+
+ // Gen key pair with valid curve
+ try {
+ buffer[bufferOffset] = ECTEST_GENERATE_KEYPAIR_CUSTOMCURVE;
+ bufferOffset++;
+ // Should succeed
+ ecKeyPair.genKeyPair();
+ // If this line is reached, we generated valid key pair
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_NO_ERROR);
+ bufferOffset += 2;
+ } catch (CryptoException e) {
+ Util.setShort(buffer, bufferOffset, e.getReason());
+ bufferOffset += 2;
+ } catch (Exception e) {
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_UNKNOWN);
+ bufferOffset += 2;
+ }
+
+ // If we reach this line => everything was as expected
+ // Rewind offset in array back (no storage of info about expected runs)
+ // bufferOffset = startOffset; done at beginning
+ } else {
+ Util.setShort(buffer, bufferOffset, SW_SKIPPED);
+ bufferOffset += 2;
+ }
+ }
+
+ return (short) (bufferOffset - baseOffset);
+ }
+
+ void AllocateKeyPairReturnDefCourve(APDU apdu) {
byte[] apdubuf = apdu.getBuffer();
apdu.setIncomingAndReceive();
diff --git a/src/simpleapdu/SimpleAPDU.java b/src/simpleapdu/SimpleAPDU.java
index 11ccaf1..5898916 100644
--- a/src/simpleapdu/SimpleAPDU.java
+++ b/src/simpleapdu/SimpleAPDU.java
@@ -1,6 +1,8 @@
package simpleapdu;
import applets.SimpleECCApplet;
+import static applets.SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_CUSTOMCURVE;
+import static applets.SimpleECCApplet.ECTEST_SET_INVALIDCURVE;
import javacard.framework.ISO7816;
import javacard.security.CryptoException;
import javacard.security.KeyPair;
@@ -13,12 +15,12 @@ import javax.smartcardio.ResponseAPDU;
public class SimpleAPDU {
static CardMngr cardManager = new CardMngr();
- private final static byte SELECT_SIMPLEAPPLET[] = {(byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x0b,
- (byte) 0x4C, (byte) 0x61, (byte) 0x62, (byte) 0x61, (byte) 0x6B,
- (byte) 0x41, (byte) 0x70, (byte) 0x70, (byte) 0x6C, (byte) 0x65, (byte) 0x74};
+ private final static byte SELECT_ECTESTERAPPLET[] = {(byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x0a,
+ (byte) 0x45, (byte) 0x43, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x30, (byte) 0x31};
private static byte TESTECSUPPORTALL_FP[] = {(byte) 0xB0, (byte) 0x5E, (byte) 0x00, (byte) 0x00, (byte) 0x00};
private static byte TESTECSUPPORTALL_F2M[] = {(byte) 0xB0, (byte) 0x5F, (byte) 0x00, (byte) 0x00, (byte) 0x00};
+ private static byte TESTECSUPPORTALL_FP_KEYGEN_INVALIDCURVEB[] = {(byte) 0xB0, (byte) 0x70, (byte) 0x10, (byte) 0x00, (byte) 0x00};
static short getShort(byte[] array, int offset) {
return (short) (((array[offset] & 0xFF) << 8) | (array[offset + 1] & 0xFF));
@@ -31,13 +33,19 @@ public class SimpleAPDU {
//
if (cardManager.ConnectToCard()) {
// Select our application on card
- cardManager.sendAPDU(SELECT_SIMPLEAPPLET);
+ cardManager.sendAPDU(SELECT_ECTESTERAPPLET);
+ // Test setting invalid curves
+ ResponseAPDU resp_fp_keygen = cardManager.sendAPDU(TESTECSUPPORTALL_FP_KEYGEN_INVALIDCURVEB);
+ PrintECKeyGenInvalidCurveB(resp_fp_keygen);
+
// Test support for different types of curves
ResponseAPDU resp_fp = cardManager.sendAPDU(TESTECSUPPORTALL_FP);
ResponseAPDU resp_f2m = cardManager.sendAPDU(TESTECSUPPORTALL_F2M);
PrintECSupport(resp_fp);
PrintECSupport(resp_f2m);
+
+
cardManager.DisconnectFromCard();
} else {
System.out.println("Failed to connect to card");
@@ -81,7 +89,10 @@ public class SimpleAPDU {
MUST_FAIL
}
static int VerifyPrintResult(String message, byte expectedTag, byte[] buffer, int bufferOffset, ExpResult expRes) {
- assert (buffer[bufferOffset] == expectedTag);
+ if (buffer[bufferOffset] != expectedTag) {
+ System.out.println("ERROR: mismatched tag");
+ assert(buffer[bufferOffset] == expectedTag);
+ }
bufferOffset++;
short resCode = getShort(buffer, bufferOffset);
bufferOffset += 2;
@@ -128,10 +139,43 @@ public class SimpleAPDU {
bufferOffset = VerifyPrintResult("Generate key with valid curve:", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_CUSTOMCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEDD);
bufferOffset = VerifyPrintResult("ECDH agreement with valid point:", SimpleECCApplet.ECTEST_ECDH_AGREEMENT_VALID_POINT, buffer, bufferOffset, ExpResult.SHOULD_SUCCEDD);
bufferOffset = VerifyPrintResult("ECDH agreement with invalid point (fail is good):", SimpleECCApplet.ECTEST_ECDH_AGREEMENT_INVALID_POINT, buffer, bufferOffset, ExpResult.MUST_FAIL);
- bufferOffset = VerifyPrintResult("Set invalid custom curve (fail is good):", SimpleECCApplet.ECTEST_SET_INVALIDCURVE, buffer, bufferOffset, ExpResult.MUST_FAIL);
+ bufferOffset = VerifyPrintResult("Set invalid custom curve (my fail):", SimpleECCApplet.ECTEST_SET_INVALIDCURVE, buffer, bufferOffset, ExpResult.MAY_FAIL);
bufferOffset = VerifyPrintResult("Generate key with invalid curve (fail is good):", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_INVALIDCUSTOMCURVE, buffer, bufferOffset, ExpResult.MUST_FAIL);
System.out.println();
}
}
+ static void PrintECKeyGenInvalidCurveB(ResponseAPDU resp) {
+ byte[] buffer = resp.getData();
+
+ System.out.println();
+ System.out.println();
+ int bufferOffset = 0;
+ while (bufferOffset < buffer.length) {
+ assert (buffer[bufferOffset] == SimpleECCApplet.ECTEST_SEPARATOR);
+ bufferOffset++;
+ String ecType = "unknown";
+ if (buffer[bufferOffset] == KeyPair.ALG_EC_FP) {
+ ecType = "ALG_EC_FP";
+ }
+ if (buffer[bufferOffset] == KeyPair.ALG_EC_F2M) {
+ ecType = "ALG_EC_F2M";
+ }
+ System.out.println(String.format("%-53s%s", "EC type:", ecType));
+ bufferOffset++;
+ short keyLen = getShort(buffer, bufferOffset);
+ System.out.println(String.format("%-53s%d bits", "EC key length (bits):", keyLen));
+ bufferOffset += 2;
+
+ bufferOffset = VerifyPrintResult("KeyPair object allocation:", SimpleECCApplet.ECTEST_ALLOCATE_KEYPAIR, buffer, bufferOffset, ExpResult.SHOULD_SUCCEDD);
+ while (bufferOffset < buffer.length) {
+ bufferOffset = VerifyPrintResult("Set invalid custom curve:", SimpleECCApplet.ECTEST_SET_INVALIDCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEDD);
+ bufferOffset = VerifyPrintResult("Generate key with invalid curve (fail is good):", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_INVALIDCUSTOMCURVE, buffer, bufferOffset, ExpResult.MUST_FAIL);
+ bufferOffset = VerifyPrintResult("Set valid custom curve:", SimpleECCApplet.ECTEST_SET_VALIDCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEDD);
+ bufferOffset = VerifyPrintResult("Generate key with valid curve:", SimpleECCApplet.ECTEST_GENERATE_KEYPAIR_CUSTOMCURVE, buffer, bufferOffset, ExpResult.SHOULD_SUCCEDD);
+ }
+
+ System.out.println();
+ }
+ }
}