aboutsummaryrefslogtreecommitdiff
path: root/src/applets
diff options
context:
space:
mode:
Diffstat (limited to 'src/applets')
-rw-r--r--src/applets/EC_Consts.java115
-rw-r--r--src/applets/SimpleECCApplet.java394
2 files changed, 356 insertions, 153 deletions
diff --git a/src/applets/EC_Consts.java b/src/applets/EC_Consts.java
index 7923c91..996766b 100644
--- a/src/applets/EC_Consts.java
+++ b/src/applets/EC_Consts.java
@@ -3,11 +3,13 @@
*/
package applets;
+import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
import javacard.security.ECPrivateKey;
import javacard.security.ECPublicKey;
import javacard.security.KeyBuilder;
+import javacard.security.KeyPair;
public class EC_Consts {
public static byte[] EC_FP_P = null;
@@ -130,55 +132,76 @@ public class EC_Consts {
// TODO: add parameters for longer lengths
- public static void setECKeyParams(ECPublicKey ecPubKey, ECPrivateKey ecPrivKey, short ecLength, byte[] auxBuffer) {
- // Select proper courve parameters
- switch (ecLength) {
- case (short) 192: {
- EC_FP_P = EC192_FP_P;
- EC_FP_A = EC192_FP_A;
- EC_FP_B = EC192_FP_B;
- EC_FP_G_X = EC192_FP_G_X;
- EC_FP_G_Y = EC192_FP_G_Y;
- EC_FP_R = EC192_FP_R;
- EC_FP_K = EC192_FP_K;
- break;
+ public static void setValidECKeyParams(ECPublicKey ecPubKey, ECPrivateKey ecPrivKey, byte ecClass, short ecLength, byte[] auxBuffer) {
+ setECKeyParams(ecPubKey, ecPrivKey, ecClass, ecLength, auxBuffer, false);
+ }
+ public static void setInValidECKeyParams(ECPublicKey ecPubKey, ECPrivateKey ecPrivKey, byte ecClass, short ecLength, byte[] auxBuffer) {
+ setECKeyParams(ecPubKey, ecPrivKey, ecClass, ecLength, auxBuffer, true);
+ }
+ private static void setECKeyParams(ECPublicKey ecPubKey, ECPrivateKey ecPrivKey, byte ecClass, short ecLength, byte[] auxBuffer, boolean bInvalidCurve) {
+ if (ecClass == KeyPair.ALG_EC_FP) {
+ // Select proper courve parameters
+ switch (ecLength) {
+ case (short) 192: {
+ EC_FP_P = EC192_FP_P;
+ EC_FP_A = EC192_FP_A;
+ EC_FP_B = EC192_FP_B;
+ EC_FP_G_X = EC192_FP_G_X;
+ EC_FP_G_Y = EC192_FP_G_Y;
+ EC_FP_R = EC192_FP_R;
+ EC_FP_K = EC192_FP_K;
+ break;
+ }
+ case (short) 256: {
+ EC_FP_P = EC256_FP_P;
+ EC_FP_A = EC256_FP_A;
+ EC_FP_B = EC256_FP_B;
+ EC_FP_G_X = EC256_FP_G_X;
+ EC_FP_G_Y = EC256_FP_G_Y;
+ EC_FP_R = EC256_FP_R;
+ EC_FP_K = EC256_FP_K;
+ break;
+ }
+ default: {
+ ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
+ }
}
- case (short) 256: {
- EC_FP_P = EC256_FP_P;
- EC_FP_A = EC256_FP_A;
- EC_FP_B = EC256_FP_B;
- EC_FP_G_X = EC256_FP_G_X;
- EC_FP_G_Y = EC256_FP_G_Y;
- EC_FP_R = EC256_FP_R;
- EC_FP_K = EC256_FP_K;
- break;
- }
- default: {
- ISOException.throwIt((short) -1);
+
+ // prepare an ANSI X9.62 uncompressed EC point representation for G
+ short gSize = (short) 1;
+ gSize += (short) EC_FP_G_X.length;
+ gSize += (short) EC_FP_G_Y.length;
+ auxBuffer[0] = 0x04;
+ short off = 1;
+ off = Util.arrayCopyNonAtomic(EC_FP_G_X, (short) 0, auxBuffer, off, (short) EC_FP_G_X.length);
+ Util.arrayCopyNonAtomic(EC_FP_G_Y, (short) 0, auxBuffer, off, (short) EC_FP_G_Y.length);
+
+ // pre-set basic EC parameters:
+ ecPubKey.setFieldFP(EC_FP_P, (short) 0, (short) EC_FP_P.length);
+ ecPubKey.setA(EC_FP_A, (short) 0, (short) EC_FP_A.length);
+ ecPubKey.setB(EC_FP_B, (short) 0, (short) EC_FP_B.length);
+ if (bInvalidCurve) { // corrupt curve
+ Util.arrayCopyNonAtomic(EC_FP_B, (short) 0, auxBuffer, (short) 0, (short) EC_FP_B.length);
+ auxBuffer[(byte) 10] = (byte) 0xcc;
+ auxBuffer[(byte) 11] = (byte) 0xcc;
+ ecPubKey.setB(auxBuffer, (short) 0, (short) EC_FP_B.length);
}
- }
- // prepare an ANSI X9.62 uncompressed EC point representation for G
- short gSize = (short) 1;
- gSize += (short) EC_FP_G_X.length;
- gSize += (short) EC_FP_G_Y.length;
- auxBuffer[0] = 0x04;
- short off = 1;
- off = Util.arrayCopy(EC_FP_G_X, (short) 0, auxBuffer, off, (short) EC_FP_G_X.length);
- Util.arrayCopy(EC_FP_G_Y, (short) 0, auxBuffer, off, (short) EC_FP_G_Y.length);
+
+ ecPubKey.setG(auxBuffer, (short) 0, gSize);
+ ecPubKey.setR(EC_FP_R, (short) 0, (short) EC_FP_R.length);
+ ecPubKey.setK(EC_FP_K);
- // pre-set basic EC parameters:
- ecPubKey.setFieldFP(EC_FP_P, (short) 0, (short) EC_FP_P.length);
- ecPubKey.setA(EC_FP_A, (short) 0, (short) EC_FP_A.length);
- ecPubKey.setB(EC_FP_B, (short) 0, (short) EC_FP_B.length);
- ecPubKey.setG(auxBuffer, (short) 0, gSize);
- ecPubKey.setR(EC_FP_R, (short) 0, (short) EC_FP_R.length);
- ecPubKey.setK(EC_FP_K);
+ ecPrivKey.setFieldFP(EC_FP_P, (short) 0, (short) EC_FP_P.length);
+ ecPrivKey.setA(EC_FP_A, (short) 0, (short) EC_FP_A.length);
+ ecPrivKey.setB(EC_FP_B, (short) 0, (short) EC_FP_B.length);
+ ecPrivKey.setG(auxBuffer, (short) 0, gSize);
+ ecPrivKey.setR(EC_FP_R, (short) 0, (short) EC_FP_R.length);
+ ecPrivKey.setK(EC_FP_K);
+ }
+ if (ecClass == KeyPair.ALG_EC_F2M) {
+ // Not supported yet
+ ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
+ }
- ecPrivKey.setFieldFP(EC_FP_P, (short) 0, (short) EC_FP_P.length);
- ecPrivKey.setA(EC_FP_A, (short) 0, (short) EC_FP_A.length);
- ecPrivKey.setB(EC_FP_B, (short) 0, (short) EC_FP_B.length);
- ecPrivKey.setG(auxBuffer, (short) 0, gSize);
- ecPrivKey.setR(EC_FP_R, (short) 0, (short) EC_FP_R.length);
- ecPrivKey.setK(EC_FP_K);
}
}
diff --git a/src/applets/SimpleECCApplet.java b/src/applets/SimpleECCApplet.java
index 325d834..ab6eede 100644
--- a/src/applets/SimpleECCApplet.java
+++ b/src/applets/SimpleECCApplet.java
@@ -16,9 +16,13 @@ public class SimpleECCApplet extends javacard.framework.Applet
// INSTRUCTIONS
final static byte INS_GENERATEKEY = (byte) 0x5a;
final static byte INS_ALLOCATEKEYPAIRS = (byte) 0x5b;
+
final static byte INS_ALLOCATEKEYPAIR = (byte) 0x5c;
final static byte INS_DERIVEECDHSECRET = (byte) 0x5d;
+ final static byte INS_TESTECSUPPORTALL = (byte) 0x5e;
+
+
final static short ARRAY_LENGTH = (short) 0xff;
final static byte AES_BLOCK_LENGTH = (short) 0x16;
@@ -26,6 +30,16 @@ public class SimpleECCApplet extends javacard.framework.Applet
final static short EC_LENGTH_BITS = KeyBuilder.LENGTH_EC_FP_192;
//final static short EC_LENGTH_BITS = KeyBuilder.LENGTH_EC_FP_160;
//final static short EC_LENGTH_BITS = (short) 256;
+
+ public final static byte ECTEST_SEPARATOR = (byte) 0xff;
+ public final static byte ECTEST_ALLOCATE_KEYPAIR = (byte) 0xc1;
+ public final static byte ECTEST_GENERATE_KEYPAIR_DEFCURVE = (byte) 0xc2;
+ public final static byte ECTEST_SET_VALIDCURVE = (byte) 0xc3;
+ 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 short SW_SKIPPED = (short) 0x0ee1;
/*
public static final byte[] EC192_FP_PUBLICW = new byte[]{
(byte) 0x04, (byte) 0xC9, (byte) 0xC0, (byte) 0xED, (byte) 0xFB, (byte) 0x27,
@@ -118,6 +132,9 @@ public class SimpleECCApplet extends javacard.framework.Applet
if (apduBuffer[ISO7816.OFFSET_CLA] == CLA_SIMPLEECCAPPLET) {
switch ( apduBuffer[ISO7816.OFFSET_INS] ) {
+ case INS_TESTECSUPPORTALL:
+ TestECSupportAllLengths(apdu);
+ break;
case INS_ALLOCATEKEYPAIR:
AllocateKeyPairReturnDefCourve(apdu);
break;
@@ -141,6 +158,274 @@ public class SimpleECCApplet extends javacard.framework.Applet
else ISOException.throwIt( ISO7816.SW_CLA_NOT_SUPPORTED);
}
+
+ void AllocateKeyPairReturnDefCourve(APDU apdu) {
+ byte[] apdubuf = apdu.getBuffer();
+ apdu.setIncomingAndReceive();
+
+ short bitLen = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA);
+
+ // Note: all locations shoudl happen in constructor. But here it is intentional
+ // as we like to test for result of allocation
+ ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, bitLen);
+
+ // If required, generate also new key pair
+ if (apdubuf[ISO7816.OFFSET_P1] == (byte) 1) {
+ ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
+ ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
+ // 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 nothing
+
+ // If required, initialize curve parameters first
+ if (apdubuf[ISO7816.OFFSET_P2] == (byte) 2) {
+ EC_Consts.setValidECKeyParams(ecPubKey, ecPrivKey, KeyPair.ALG_EC_FP, bitLen, m_ramArray);
+ }
+
+ // Now generate new keypair with either default or custom curve
+ ecKeyPair.genKeyPair();
+ ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
+ ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
+
+ short len = 0;
+ short offset = 0;
+
+ // Export curve public parameters
+ offset += 2; // reserve space for length
+ len = ecPubKey.getField(apdubuf, offset);
+ Util.setShort(apdubuf, (short) (offset - 2), len);
+ offset += len;
+ offset += 2; // reserve space for length
+ len = ecPubKey.getA(apdubuf, offset);
+ Util.setShort(apdubuf, (short) (offset - 2), len);
+ offset += len;
+
+ offset += 2; // reserve space for length
+ len = ecPubKey.getB(apdubuf, offset);
+ Util.setShort(apdubuf, (short) (offset - 2), len);
+ offset += len;
+ offset += 2; // reserve space for length
+ len = ecPubKey.getR(apdubuf, offset);
+ Util.setShort(apdubuf, (short) (offset - 2), len);
+ offset += len;
+ /*
+ offset += 2; // reserve space for length
+ len = ecPubKey.getW(apdubuf, offset);
+ Util.setShort(apdubuf, (short) (offset - 2), len);
+ offset += len;
+ */
+ apdu.setOutgoingAndSend((short) 0, offset);
+ }
+ }
+
+
+
+ void DeriveECDHSecret(APDU apdu) {
+ byte[] apdubuf = apdu.getBuffer();
+ short len = apdu.setIncomingAndReceive();
+
+ // Assumption: proper EC keyPair is already allocated
+ // If public key point is provided, then use it
+ if (len == 0) {
+ // if not provided, use build-in one (valid for for 192 only)
+ Util.arrayCopyNonAtomic(EC192_FP_PUBLICW, (short) 0, apdubuf, ISO7816.OFFSET_CDATA, (short) EC192_FP_PUBLICW.length);
+ len = (short) EC192_FP_PUBLICW.length;
+ }
+
+ // Generate fresh EC keypair
+ ecKeyPair.genKeyPair();
+ ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
+
+ dhKeyAgreement.init(ecPrivKey);
+ short secretLen = 0;
+ // Generate and export secret
+ secretLen = dhKeyAgreement.generateSecret(apdubuf, ISO7816.OFFSET_CDATA, len, m_ramArray, (short) 0);
+ Util.arrayCopyNonAtomic(m_ramArray, (short) 0, apdubuf, (short) 0, secretLen);
+
+ apdu.setOutgoingAndSend((short) 0, secretLen);
+ }
+
+ short TestECSupport(byte keyClass, short keyLen, byte[] buffer, short bufferOffset) {
+ short baseOffset = bufferOffset;
+
+ 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++;
+ try {
+ ecKeyPair = new KeyPair(keyClass, keyLen);
+ 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;
+ }
+
+ //
+ // 2. Test keypair generation without explicit curve (=> default curve preset)
+ //
+ buffer[bufferOffset] = ECTEST_GENERATE_KEYPAIR_DEFCURVE; bufferOffset++;
+ try {
+ ecKeyPair.genKeyPair();
+ 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;
+ }
+
+ //
+ // 3. Set valid custom curve
+ //
+ buffer[bufferOffset] = ECTEST_SET_VALIDCURVE;
+ bufferOffset++;
+ boolean bGenerateKey = false;
+ try {
+ ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
+ ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
+ // 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
+
+ // Initialize curve parameters
+ EC_Consts.setValidECKeyParams(ecPubKey, ecPrivKey, keyClass, keyLen, m_ramArray);
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_NO_ERROR);
+ bufferOffset += 2;
+
+ bGenerateKey = true;
+ } catch (CryptoException e) {
+ Util.setShort(buffer, bufferOffset, e.getReason());
+ bufferOffset += 2;
+ }
+ catch (Exception e) {
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_UNKNOWN);
+ bufferOffset += 2;
+ }
+
+ //
+ // 4. Generate keypair with custom curve
+ //
+ buffer[bufferOffset] = ECTEST_GENERATE_KEYPAIR_CUSTOMCURVE;
+ bufferOffset++;
+ if (bGenerateKey) {
+ try {
+ ecKeyPair.genKeyPair();
+ 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;
+ }
+ }
+ else {
+ Util.setShort(buffer, bufferOffset, SW_SKIPPED);
+ bufferOffset += 2;
+ }
+ //
+ // 5. Set invalid custom curve
+ //
+ buffer[bufferOffset] = ECTEST_SET_INVALIDCURVE;
+ bufferOffset++;
+ bGenerateKey = false;
+ try {
+ // Initialize curve parameters
+ EC_Consts.setInValidECKeyParams(ecPubKey, ecPrivKey, keyClass, keyLen, m_ramArray);
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_NO_ERROR);
+ bufferOffset += 2;
+ bGenerateKey = true;
+ } catch (CryptoException e) {
+ Util.setShort(buffer, bufferOffset, e.getReason());
+ bufferOffset += 2;
+ } catch (Exception e) {
+ Util.setShort(buffer, bufferOffset, ISO7816.SW_UNKNOWN);
+ bufferOffset += 2;
+ }
+
+ //
+ // 6. Generate keypair with invalid custom curve
+ //
+ buffer[bufferOffset] = ECTEST_GENERATE_KEYPAIR_INVALIDCUSTOMCURVE;
+ bufferOffset++;
+ if (bGenerateKey) {
+ try {
+ ecKeyPair.genKeyPair();
+ 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;
+ }
+ } else {
+ Util.setShort(buffer, bufferOffset, SW_SKIPPED);
+ bufferOffset += 2;
+ }
+
+ return (short) (bufferOffset - baseOffset);
+ }
+ void TestECSupportAllLengths(APDU apdu) {
+ byte[] apdubuf = apdu.getBuffer();
+ short len = apdu.setIncomingAndReceive();
+
+ short dataOffset = 0;
+ // FP -
+ dataOffset += TestECSupport(KeyPair.ALG_EC_FP, (short) 128, apdubuf, dataOffset);
+ dataOffset += TestECSupport(KeyPair.ALG_EC_FP, (short) 160, apdubuf, dataOffset);
+ dataOffset += TestECSupport(KeyPair.ALG_EC_FP, (short) 192, apdubuf, dataOffset);
+ dataOffset += TestECSupport(KeyPair.ALG_EC_FP, (short) 224, apdubuf, dataOffset);
+ dataOffset += TestECSupport(KeyPair.ALG_EC_FP, (short) 256, apdubuf, dataOffset);
+ dataOffset += TestECSupport(KeyPair.ALG_EC_FP, (short) 384, apdubuf, dataOffset);
+ dataOffset += TestECSupport(KeyPair.ALG_EC_FP, (short) 521, apdubuf, dataOffset);
+
+ apdu.setOutgoingAndSend((short) 0, dataOffset);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
void AllocateKeyPair(byte algorithm, short bitLen) {
// Select proper attributes
switch (bitLen) {
@@ -185,7 +470,7 @@ public class SimpleECCApplet extends javacard.framework.Applet
ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
// Set required EC parameters
- EC_Consts.setECKeyParams(ecPubKey, ecPrivKey, bitLen, m_ramArray);
+ EC_Consts.setValidECKeyParams(ecPubKey, ecPrivKey, KeyPair.ALG_EC_FP, bitLen, m_ramArray);
}
short TryAllocateKeyPair(byte algorithm, short bitLen, byte[] buffer, short offset) {
@@ -215,114 +500,9 @@ public class SimpleECCApplet extends javacard.framework.Applet
apdu.setOutgoingAndSend((short) 0, offset);
}
- void AllocateKeyPairReturnDefCourve(APDU apdu) {
- byte[] apdubuf = apdu.getBuffer();
- apdu.setIncomingAndReceive();
-
- short bitLen = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA);
-
- // Note: all locations shoudl happen in constructor. But here it is intentional
- // as we like to test for result of allocation
- ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, bitLen);
-
- // If required, generate also new key pair
- if (apdubuf[ISO7816.OFFSET_P1] == (byte) 1) {
- ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
- ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
- // 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 nothing
-
-
- // If required, initialize curve parameters first
- if (apdubuf[ISO7816.OFFSET_P2] == (byte) 2) {
- EC_Consts.setECKeyParams(ecPubKey, ecPrivKey, bitLen, m_ramArray);
- }
-
- // Now generate new keypair with either default or custom curve
- ecKeyPair.genKeyPair();
- ecPubKey = (ECPublicKey) ecKeyPair.getPublic();
- ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
-
- short len = 0;
- short offset = 0;
-
- // Export curve public parameters
- offset += 2; // reserve space for length
- len = ecPubKey.getField(apdubuf, offset);
- Util.setShort(apdubuf, (short) (offset - 2), len);
- offset += len;
- offset += 2; // reserve space for length
- len = ecPubKey.getA(apdubuf, offset);
- Util.setShort(apdubuf, (short) (offset - 2), len);
- offset += len;
- offset += 2; // reserve space for length
- len = ecPubKey.getB(apdubuf, offset);
- Util.setShort(apdubuf, (short) (offset - 2), len);
- offset += len;
- offset += 2; // reserve space for length
- len = ecPubKey.getR(apdubuf, offset);
- Util.setShort(apdubuf, (short) (offset - 2), len);
- offset += len;
-/*
- offset += 2; // reserve space for length
- len = ecPubKey.getW(apdubuf, offset);
- Util.setShort(apdubuf, (short) (offset - 2), len);
- offset += len;
-*/
- apdu.setOutgoingAndSend((short) 0, offset);
- }
- }
-/**
- For a first quick test, this would be the workflow:
- *
- * 1. Import a given ECC public key (i.e. a point that is not on the curve)
- *
- * 2. Generate a fresh ECC keypair
- *
- * 3. Perform a ECDH key-derivation with the keys from steps 1 and 2
- *
- * 4. Repeat steps 2 & 3 a couple of times and record the generated secrets
- *
- *
- *
- * If the card is vulnerable, then the generated secrets will repeat. For
- * example, we have points of order 5. With such a point and a vulnerable
- * card, there are only 5 (or even less) different possible values for the
- * generated secrets. This is pretty obvious, if you do a couple of (e.g.
- * +-10) key-derivations ;)
- * @param apdu
- */
- void DeriveECDHSecret(APDU apdu) {
- byte[] apdubuf = apdu.getBuffer();
- short len = apdu.setIncomingAndReceive();
-
- // Assumption: proper EC keyPair is already allocated
-
- // If public key point is provided, then use it
- if (len == 0) {
- // if not provided, use build-in one
- Util.arrayCopyNonAtomic(EC192_FP_PUBLICW, (short) 0, apdubuf, ISO7816.OFFSET_CDATA, (short) EC192_FP_PUBLICW.length);
- len = (short) EC192_FP_PUBLICW.length;
- }
-
- // Generate fresh EC keypair
- ecKeyPair.genKeyPair();
- ecPrivKey = (ECPrivateKey) ecKeyPair.getPrivate();
-
- dhKeyAgreement.init(ecPrivKey);
- short secretLen = 0;
- // Generate and export secret
- secretLen = dhKeyAgreement.generateSecret(apdubuf, ISO7816.OFFSET_CDATA, len, m_ramArray, (short) 0);
- Util.arrayCopyNonAtomic(m_ramArray, (short) 0, apdubuf, (short) 0, secretLen);
-
- apdu.setOutgoingAndSend((short) 0, secretLen);
- }
+
void GenerateKey(APDU apdu) {