aboutsummaryrefslogtreecommitdiff
path: root/src/applets
diff options
context:
space:
mode:
Diffstat (limited to 'src/applets')
-rw-r--r--src/applets/EC_Consts.java102
-rw-r--r--src/applets/SimpleECCApplet.java72
2 files changed, 168 insertions, 6 deletions
diff --git a/src/applets/EC_Consts.java b/src/applets/EC_Consts.java
index a4164ac..dd58bed 100644
--- a/src/applets/EC_Consts.java
+++ b/src/applets/EC_Consts.java
@@ -279,7 +279,97 @@ public class EC_Consts {
// cofactor of G
public static final short EC256_FP_K = 1;
- // TODO: add parameters for longer lengths
+ // secp384r1 from http://www.secg.org/sec2-v2.pdf
+ public static final byte[] EC384_FP_P = new byte[]{
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+
+ public static final byte[] EC384_FP_A = new byte[]{
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFE,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFC};
+
+ public static final byte[] EC384_FP_B = new byte[]{
+ (byte) 0xB3, (byte) 0x31, (byte) 0x2F, (byte) 0xA7,
+ (byte) 0xE2, (byte) 0x3E, (byte) 0xE7, (byte) 0xE4,
+ (byte) 0x98, (byte) 0x8E, (byte) 0x05, (byte) 0x6B,
+ (byte) 0xE3, (byte) 0xF8, (byte) 0x2D, (byte) 0x19,
+ (byte) 0x18, (byte) 0x1D, (byte) 0x9C, (byte) 0x6E,
+ (byte) 0xFE, (byte) 0x81, (byte) 0x41, (byte) 0x12,
+ (byte) 0x03, (byte) 0x14, (byte) 0x08, (byte) 0x8F,
+ (byte) 0x50, (byte) 0x13, (byte) 0x87, (byte) 0x5A,
+ (byte) 0xC6, (byte) 0x56, (byte) 0x39, (byte) 0x8D,
+ (byte) 0x8A, (byte) 0x2E, (byte) 0xD1, (byte) 0x9D,
+ (byte) 0x2A, (byte) 0x85, (byte) 0xC8, (byte) 0xED,
+ (byte) 0xD3, (byte) 0xEC, (byte) 0x2A, (byte) 0xEF};
+
+ // G in compressed form / first part of ucompressed
+ public static final byte[] EC384_FP_G_X = new byte[]{
+ (byte) 0xAA, (byte) 0x87, (byte) 0xCA, (byte) 0x22,
+ (byte) 0xBE, (byte) 0x8B, (byte) 0x05, (byte) 0x37,
+ (byte) 0x8E, (byte) 0xB1, (byte) 0xC7, (byte) 0x1E,
+ (byte) 0xF3, (byte) 0x20, (byte) 0xAD, (byte) 0x74,
+ (byte) 0x6E, (byte) 0x1D, (byte) 0x3B, (byte) 0x62,
+ (byte) 0x8B, (byte) 0xA7, (byte) 0x9B, (byte) 0x98,
+ (byte) 0x59, (byte) 0xF7, (byte) 0x41, (byte) 0xE0,
+ (byte) 0x82, (byte) 0x54, (byte) 0x2A, (byte) 0x38,
+ (byte) 0x55, (byte) 0x02, (byte) 0xF2, (byte) 0x5D,
+ (byte) 0xBF, (byte) 0x55, (byte) 0x29, (byte) 0x6C,
+ (byte) 0x3A, (byte) 0x54, (byte) 0x5E, (byte) 0x38,
+ (byte) 0x72, (byte) 0x76, (byte) 0x0A, (byte) 0xB7};
+ // second part of G uncompressed
+ public static final byte[] EC384_FP_G_Y = new byte[]{
+ (byte) 0x36, (byte) 0x17, (byte) 0xDE, (byte) 0x4A,
+ (byte) 0x96, (byte) 0x26, (byte) 0x2C, (byte) 0x6F,
+ (byte) 0x5D, (byte) 0x9E, (byte) 0x98, (byte) 0xBF,
+ (byte) 0x92, (byte) 0x92, (byte) 0xDC, (byte) 0x29,
+ (byte) 0xF8, (byte) 0xF4, (byte) 0x1D, (byte) 0xBD,
+ (byte) 0x28, (byte) 0x9A, (byte) 0x14, (byte) 0x7C,
+ (byte) 0xE9, (byte) 0xDA, (byte) 0x31, (byte) 0x13,
+ (byte) 0xB5, (byte) 0xF0, (byte) 0xB8, (byte) 0xC0,
+ (byte) 0x0A, (byte) 0x60, (byte) 0xB1, (byte) 0xCE,
+ (byte) 0x1D, (byte) 0x7E, (byte) 0x81, (byte) 0x9D,
+ (byte) 0x7A, (byte) 0x43, (byte) 0x1D, (byte) 0x7C,
+ (byte) 0x90, (byte) 0xEA, (byte) 0x0E, (byte) 0x5F};
+
+ // Order of G
+ public static final byte[] EC384_FP_R = new byte[]{
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xC7, (byte) 0x63, (byte) 0x4D, (byte) 0x81,
+ (byte) 0xF4, (byte) 0x37, (byte) 0x2D, (byte) 0xDF,
+ (byte) 0x58, (byte) 0x1A, (byte) 0x0D, (byte) 0xB2,
+ (byte) 0x48, (byte) 0xB0, (byte) 0xA7, (byte) 0x7A,
+ (byte) 0xEC, (byte) 0xEC, (byte) 0x19, (byte) 0x6A,
+ (byte) 0xCC, (byte) 0xC5, (byte) 0x29, (byte) 0x73};
+ // cofactor of G
+ public static final short EC384_FP_K = 1;
+
+ // TODO: secp521r1
+
public static void setValidECKeyParams(ECPublicKey ecPubKey, ECPrivateKey ecPrivKey, byte ecClass, short ecLength, byte[] auxBuffer) {
setECKeyParams(ecPubKey, ecPrivKey, ecClass, ecLength, auxBuffer, false);
@@ -341,6 +431,16 @@ public class EC_Consts {
EC_FP_K = EC256_FP_K;
break;
}
+ case (short) 384: {
+ EC_FP_P = EC384_FP_P;
+ EC_FP_A = EC384_FP_A;
+ EC_FP_B = EC384_FP_B;
+ EC_FP_G_X = EC384_FP_G_X;
+ EC_FP_G_Y = EC384_FP_G_Y;
+ EC_FP_R = EC384_FP_R;
+ EC_FP_K = EC384_FP_K;
+ break;
+ }
default: {
ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
}
diff --git a/src/applets/SimpleECCApplet.java b/src/applets/SimpleECCApplet.java
index ab6eede..b9fd347 100644
--- a/src/applets/SimpleECCApplet.java
+++ b/src/applets/SimpleECCApplet.java
@@ -38,6 +38,8 @@ public class SimpleECCApplet extends javacard.framework.Applet
public final static byte ECTEST_GENERATE_KEYPAIR_CUSTOMCURVE = (byte) 0xc4;
public final static byte ECTEST_SET_INVALIDCURVE = (byte) 0xc5;
public final static byte ECTEST_GENERATE_KEYPAIR_INVALIDCUSTOMCURVE = (byte) 0xc6;
+ public final static byte ECTEST_ECDH_AGREEMENT_VALID_POINT = (byte) 0xc7;
+ public final static byte ECTEST_ECDH_AGREEMENT_INVALID_POINT = (byte) 0xc8;
public final static short SW_SKIPPED = (short) 0x0ee1;
/*
@@ -83,7 +85,8 @@ public class SimpleECCApplet extends javacard.framework.Applet
private KeyAgreement dhKeyAgreement = null;
// TEMPORARRY ARRAY IN RAM
- private byte m_ramArray[] = null;
+ private byte m_ramArray[] = null;
+ private byte m_ramArray2[] = null;
// PERSISTENT ARRAY IN EEPROM
private byte m_dataArray[] = null;
@@ -99,10 +102,10 @@ public class SimpleECCApplet extends javacard.framework.Applet
dataOffset++;
m_ramArray = JCSystem.makeTransientByteArray(ARRAY_LENGTH, JCSystem.CLEAR_ON_RESET);
+ m_ramArray2 = JCSystem.makeTransientByteArray(ARRAY_LENGTH, JCSystem.CLEAR_ON_RESET);
+
m_dataArray = new byte[ARRAY_LENGTH];
Util.arrayFillNonAtomic(m_dataArray, (short) 0, ARRAY_LENGTH, (byte) 0);
-
- dhKeyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH, false);
}
register();
@@ -241,6 +244,9 @@ public class SimpleECCApplet extends javacard.framework.Applet
ecKeyPair.genKeyPair();
ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
+ if (dhKeyAgreement == null) {
+ dhKeyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH, false);
+ }
dhKeyAgreement.init(ecPrivKey);
short secretLen = 0;
// Generate and export secret
@@ -347,8 +353,64 @@ public class SimpleECCApplet extends javacard.framework.Applet
Util.setShort(buffer, bufferOffset, SW_SKIPPED);
bufferOffset += 2;
}
+
+ //
+ // 5. ECDH agreement with valid public key
+ //
+ buffer[bufferOffset] = ECTEST_ECDH_AGREEMENT_VALID_POINT;
+ bufferOffset++;
+ try {
+ // Generate fresh EC keypair
+ ecKeyPair.genKeyPair();
+ ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
+ ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
+ if (dhKeyAgreement == null) {
+ dhKeyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH, false);
+ }
+ dhKeyAgreement.init(ecPrivKey);
+
+ short pubKeyLen = ecPubKey.getW(m_ramArray, (short) 0);
+ short secretLen = dhKeyAgreement.generateSecret(m_ramArray, (short) 0, pubKeyLen, m_ramArray2, (short) 0);
+
+ 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;
+ }
+
+ //
+ // 6. ECDH agreement with invalid public key
+ //
+ buffer[bufferOffset] = ECTEST_ECDH_AGREEMENT_VALID_POINT;
+ bufferOffset++;
+ try {
+ // Generate fresh EC keypair
+ ecKeyPair.genKeyPair();
+ ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
+ ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
+ dhKeyAgreement.init(ecPrivKey);
+
+ short pubKeyLen = ecPubKey.getW(m_ramArray, (short) 0);
+ m_ramArray[(byte) 10] = (byte) 0xcc; // Corrupt public key
+ m_ramArray[(byte) 11] = (byte) 0xcc;
+ short secretLen = dhKeyAgreement.generateSecret(m_ramArray, (short) 0, pubKeyLen, m_ramArray2, (short) 0);
+
+ 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;
+ }
+
//
- // 5. Set invalid custom curve
+ // 7. Set invalid custom curve
//
buffer[bufferOffset] = ECTEST_SET_INVALIDCURVE;
bufferOffset++;
@@ -368,7 +430,7 @@ public class SimpleECCApplet extends javacard.framework.Applet
}
//
- // 6. Generate keypair with invalid custom curve
+ // 8. Generate keypair with invalid custom curve
//
buffer[bufferOffset] = ECTEST_GENERATE_KEYPAIR_INVALIDCUSTOMCURVE;
bufferOffset++;