summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2017-06-02 00:47:35 +0200
committerJ08nY2017-06-02 00:47:35 +0200
commit7cc7c46edc4fc788c4ce2e7aaf64d01b645629d0 (patch)
tree97ca0ca568a0afe11884fed999602a2d02132a1f
parentdc05a5025543f14c633f663f2b366ab3b53b45da (diff)
downloadECTester-7cc7c46edc4fc788c4ce2e7aaf64d01b645629d0.tar.gz
ECTester-7cc7c46edc4fc788c4ce2e7aaf64d01b645629d0.tar.zst
ECTester-7cc7c46edc4fc788c4ce2e7aaf64d01b645629d0.zip
-rw-r--r--!uploader/ectester.capbin14882 -> 15878 bytes
-rw-r--r--dist/ECTester.jarbin715834 -> 721244 bytes
-rw-r--r--src/cz/crcs/ectester/applet/AppletUtil.java1
-rw-r--r--src/cz/crcs/ectester/applet/ECKeyTester.java45
-rw-r--r--src/cz/crcs/ectester/applet/ECTesterApplet.java65
-rw-r--r--src/cz/crcs/ectester/applet/EC_Consts.java85
-rw-r--r--src/cz/crcs/ectester/reader/Command.java35
-rw-r--r--src/cz/crcs/ectester/reader/TestSuite.java12
8 files changed, 220 insertions, 23 deletions
diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap
index cf783e5..689610b 100644
--- a/!uploader/ectester.cap
+++ b/!uploader/ectester.cap
Binary files differ
diff --git a/dist/ECTester.jar b/dist/ECTester.jar
index 5544cfd..ff5c75f 100644
--- a/dist/ECTester.jar
+++ b/dist/ECTester.jar
Binary files differ
diff --git a/src/cz/crcs/ectester/applet/AppletUtil.java b/src/cz/crcs/ectester/applet/AppletUtil.java
index 296541d..532b44e 100644
--- a/src/cz/crcs/ectester/applet/AppletUtil.java
+++ b/src/cz/crcs/ectester/applet/AppletUtil.java
@@ -51,7 +51,6 @@ public class AppletUtil {
sum += read;
read = apdu.receiveBytes((short) 0);
} while (sum < total);
- // TODO figure this out, in buffer + out buffer(apdubuf) or just send each param on its own?
return 0;
}
}
diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java
index 7664c72..b18073f 100644
--- a/src/cz/crcs/ectester/applet/ECKeyTester.java
+++ b/src/cz/crcs/ectester/applet/ECKeyTester.java
@@ -66,6 +66,21 @@ public class ECKeyTester {
return length;
}
+ private short testKA_direct(KeyAgreement ka, KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) {
+ short length = 0;
+ try {
+ sw = AppletUtil.kaCheck(ka);
+ sw = AppletUtil.keypairCheck(privatePair);
+
+ ka.init(privatePair.getPrivate());
+ pubkeyLength = EC_Consts.corruptParameter(corruption, pubkey, pubkeyOffset, pubkeyLength);
+ length = ka.generateSecret(pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset);
+ } catch (CardRuntimeException ce) {
+ sw = ce.getReason();
+ }
+ return length;
+ }
+
/**
* Tests ECDH secret generation with keys from given {@code privatePair} and {@code publicPair}.
* Uses {@code pubkeyBuffer} at {@code pubkeyOffset} for computations.
@@ -84,6 +99,10 @@ public class ECKeyTester {
return testKA(ecdhKeyAgreement, privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption);
}
+ public short testECDH_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) {
+ return testKA_direct(ecdhKeyAgreement, privatePair, pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset, corruption);
+ }
+
/**
* Tests ECDHC secret generation with keys from given {@code privatePair} and {@code publicPair}.
* Uses {@code pubkeyBuffer} at {@code pubkeyOffset} for computations.
@@ -102,6 +121,10 @@ public class ECKeyTester {
return testKA(ecdhcKeyAgreement, privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption);
}
+ public short testECDHC_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) {
+ return testKA_direct(ecdhcKeyAgreement, privatePair, pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset, corruption);
+ }
+
/**
* @param privatePair KeyPair from which the private key is used
* @param publicPair KeyPair from which the public key is used
@@ -126,7 +149,22 @@ public class ECKeyTester {
sw = ECTesterApplet.SW_DH_DHC_MISMATCH;
}
return length;
+ }
+ public short testBOTH_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outputBuffer, short outputOffset, short corruption) {
+ short ecdhLength = testECDH_direct(privatePair, pubkey, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset, corruption);
+ if (sw != ISO7816.SW_NO_ERROR) {
+ return ecdhLength;
+ }
+ short ecdhcLength = testECDHC_direct(privatePair, pubkey, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset, corruption);
+ short length = (short) (ecdhLength + ecdhcLength);
+ if (sw != ISO7816.SW_NO_ERROR) {
+ return length;
+ }
+ if (javacard.framework.Util.arrayCompare(outputBuffer, outputOffset, outputBuffer, (short) (outputOffset + ecdhLength), ecdhLength) != 0) {
+ sw = ECTesterApplet.SW_DH_DHC_MISMATCH;
+ }
+ return length;
}
/**
@@ -146,6 +184,13 @@ public class ECKeyTester {
return testECDHC(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption);
}
+ public short testANY_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outputBuffer, short outputOffset, short corruption) {
+ short ecdhLength = testECDH_direct(privatePair, pubkey, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset, corruption);
+ if (sw == ISO7816.SW_NO_ERROR)
+ return ecdhLength;
+ return testECDHC_direct(privatePair, pubkey, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset, corruption);
+ }
+
/**
* Uses {@code signKey} to sign data from {@code inputBuffer} at {@code inputOffset} with {@code inputOffset}.
* Then checks for correct signature length.
diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java
index a7d8537..c2e2c63 100644
--- a/src/cz/crcs/ectester/applet/ECTesterApplet.java
+++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java
@@ -51,9 +51,10 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
public static final byte INS_GENERATE = (byte) 0x5e;
public static final byte INS_EXPORT = (byte) 0x5f;
public static final byte INS_ECDH = (byte) 0x60;
- public static final byte INS_ECDSA = (byte) 0x61;
- public static final byte INS_CLEANUP = (byte) 0x62;
- public static final byte INS_SUPPORT = (byte) 0x63;
+ public static final byte INS_ECDH_DIRECT = (byte) 0x61;
+ public static final byte INS_ECDSA = (byte) 0x62;
+ public static final byte INS_CLEANUP = (byte) 0x63;
+ public static final byte INS_SUPPORT = (byte) 0x64;
// PARAMETERS for P1 and P2
public static final byte KEYPAIR_LOCAL = (byte) 0x01;
@@ -164,6 +165,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
case INS_ECDH:
length = insECDH(apdu);
break;
+ case INS_ECDH_DIRECT:
+ length = insECDH_direct(apdu);
+ break;
case INS_ECDSA:
length = insECDSA(apdu);
break;
@@ -358,6 +362,26 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
}
/**
+ *
+ * @param apdu P1 = byte privkey (KEYPAIR_*)
+ * @return P2 = byte export (EXPORT_TRUE || EXPORT_FALSE)
+ * DATA = short corruption (EC_Consts.CORRUPTION_* | ...)
+ * byte type (EC_Consts.KA_* | ...)
+ * short length
+ * byte[] pubkey
+ */
+ private short insECDH_direct(APDU apdu) {
+ byte privkey = apduArray[ISO7816.OFFSET_P1];
+ byte export = apduArray[ISO7816.OFFSET_P2];
+ short cdata = apdu.getOffsetCdata();
+ short corruption = Util.getShort(apduArray, cdata);
+ byte type = apduArray[(short) (cdata + 2)];
+ short length = Util.getShort(apduArray, (short) (cdata + 3));
+
+ return ecdh_direct(privkey, export, corruption, type, (short) (cdata + 5), length, apdu.getBuffer(), (short) 0);
+ }
+
+ /**
* Performs ECDSA signature and verification on data provided or random, using the keyPair in P1(local/remote).
* returns ecdsa SW, {@code if(export == EXPORT_TRUE)} => short signature_length, byte[] signature
*
@@ -581,6 +605,41 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
return length;
}
+ private short ecdh_direct(byte privkey, byte export, short corruption, byte type, short keyOffset, short keyLength, byte[] outBuffer, short outOffset) {
+ short length = 0;
+
+ KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair;
+
+ short secretLength = 0;
+ switch (type) {
+ case EC_Consts.KA_ECDH:
+ secretLength = keyTester.testECDH_direct(priv, apduArray, keyOffset, keyLength, outBuffer, outOffset, corruption);
+ break;
+ case EC_Consts.KA_ECDHC:
+ secretLength = keyTester.testECDHC_direct(priv, apduArray, keyOffset, keyLength, outBuffer, outOffset, corruption);
+ break;
+ case EC_Consts.KA_BOTH:
+ secretLength = keyTester.testBOTH_direct(priv, apduArray, keyOffset, keyLength, outBuffer, outOffset, corruption);
+ break;
+ case EC_Consts.KA_ANY:
+ secretLength = keyTester.testANY_direct(priv, apduArray, keyOffset, keyLength, outBuffer, outOffset, corruption);
+ break;
+ default:
+ ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
+ }
+
+ Util.setShort(outBuffer, outOffset, keyTester.getSW());
+ length += 2;
+
+ if ((export == EXPORT_TRUE)) {
+ Util.setShort(outBuffer, (short) (outOffset + length), secretLength);
+ length += 2;
+ Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), secretLength);
+ length += secretLength;
+ }
+ return length;
+ }
+
/**
* @param sign keyPair to use for signing and verification
* @param export whether to export ECDSA signature
diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java
index 53eab41..04cd55e 100644
--- a/src/cz/crcs/ectester/applet/EC_Consts.java
+++ b/src/cz/crcs/ectester/applet/EC_Consts.java
@@ -68,6 +68,45 @@ public class EC_Consts {
public static RandomData randomData = null;
+ // secp112r1
+ public static final byte[] EC112_FP_P = new byte[]{
+ (byte) 0xdb, (byte) 0x7c, (byte) 0x2a, (byte) 0xbf,
+ (byte) 0x62, (byte) 0xe3, (byte) 0x5e, (byte) 0x66,
+ (byte) 0x80, (byte) 0x76, (byte) 0xbe, (byte) 0xad,
+ (byte) 0x20, (byte) 0x8b};
+
+ public static final byte[] EC112_FP_A = new byte[]{
+ (byte) 0xdb, (byte) 0x7c, (byte) 0x2a, (byte) 0xbf,
+ (byte) 0x62, (byte) 0xe3, (byte) 0x5e, (byte) 0x66,
+ (byte) 0x80, (byte) 0x76, (byte) 0xbe, (byte) 0xad,
+ (byte) 0x20, (byte) 0x88};
+
+ public static final byte[] EC112_FP_B = new byte[]{
+ (byte) 0x65, (byte) 0x9e, (byte) 0xf8, (byte) 0xba,
+ (byte) 0x04, (byte) 0x39, (byte) 0x16, (byte) 0xee,
+ (byte) 0xde, (byte) 0x89, (byte) 0x11, (byte) 0x70,
+ (byte) 0x2b, (byte) 0x22};
+
+ public static final byte[] EC112_FP_G_X = new byte[]{
+ (byte) 0x09, (byte) 0x48, (byte) 0x72, (byte) 0x39,
+ (byte) 0x99, (byte) 0x5a, (byte) 0x5e, (byte) 0xe7,
+ (byte) 0x6b, (byte) 0x55, (byte) 0xf9, (byte) 0xc2,
+ (byte) 0xf0, (byte) 0x98};
+
+ public static final byte[] EC112_FP_G_Y = new byte[]{
+ (byte) 0xa8, (byte) 0x9c, (byte) 0xe5, (byte) 0xaf,
+ (byte) 0x87, (byte) 0x24, (byte) 0xc0, (byte) 0xa2,
+ (byte) 0x3e, (byte) 0x0e, (byte) 0x0f, (byte) 0xf7,
+ (byte) 0x75, (byte) 0x00};
+
+ public static final byte[] EC112_FP_R = new byte[]{
+ (byte) 0xdb, (byte) 0x7c, (byte) 0x2a, (byte) 0xbf,
+ (byte) 0x62, (byte) 0xe3, (byte) 0x5e, (byte) 0x76,
+ (byte) 0x28, (byte) 0xdf, (byte) 0xac, (byte) 0x65,
+ (byte) 0x61, (byte) 0xc5};
+
+ public static final short EC112_FP_K = 1;
+
// secp128r1 from http://www.secg.org/sec2-v2.pdf
public static final byte[] EC128_FP_P = new byte[]{
@@ -971,31 +1010,34 @@ public class EC_Consts {
public static final byte CURVE_external = (byte) 0xff;
// SECP recommended curves over FP
- public static final byte CURVE_secp128r1 = (byte) 1;
- public static final byte CURVE_secp160r1 = (byte) 2;
- public static final byte CURVE_secp192r1 = (byte) 3;
- public static final byte CURVE_secp224r1 = (byte) 4;
- public static final byte CURVE_secp256r1 = (byte) 5;
- public static final byte CURVE_secp384r1 = (byte) 6;
- public static final byte CURVE_secp521r1 = (byte) 7;
+ public static final byte CURVE_secp112r1 = (byte) 1;
+ public static final byte CURVE_secp128r1 = (byte) 2;
+ public static final byte CURVE_secp160r1 = (byte) 3;
+ public static final byte CURVE_secp192r1 = (byte) 4;
+ public static final byte CURVE_secp224r1 = (byte) 5;
+ public static final byte CURVE_secp256r1 = (byte) 6;
+ public static final byte CURVE_secp384r1 = (byte) 7;
+ public static final byte CURVE_secp521r1 = (byte) 8;
- public static final byte FP_CURVES = (byte) 7;
+ public static final byte FP_CURVES = (byte) 8;
// SECP recommended curves over F2M
- public static final byte CURVE_sect163r1 = (byte) 8;
- public static final byte CURVE_sect233r1 = (byte) 9;
- public static final byte CURVE_sect283r1 = (byte) 10;
- public static final byte CURVE_sect409r1 = (byte) 11;
- public static final byte CURVE_sect571r1 = (byte) 12;
+ public static final byte CURVE_sect163r1 = (byte) 9;
+ public static final byte CURVE_sect233r1 = (byte) 10;
+ public static final byte CURVE_sect283r1 = (byte) 11;
+ public static final byte CURVE_sect409r1 = (byte) 12;
+ public static final byte CURVE_sect571r1 = (byte) 13;
- public static final byte F2M_CURVES = (byte) 12;
+ public static final byte F2M_CURVES = (byte) 13;
- public static final short[] FP_SIZES = new short[]{112, 128, 160, 192, 224, 256, 384, 512, 521};
+ public static final short[] FP_SIZES = new short[]{112, 128, 160, 192, 224, 256, 384, 521};
public static final short[] F2M_SIZES = new short[]{163, 233, 283, 409, 571};
public static byte getCurve(short keyLength, byte keyClass) {
if (keyClass == KeyPair.ALG_EC_FP) {
switch (keyLength) {
+ case (short) 112:
+ return CURVE_secp112r1;
case (short) 128:
return CURVE_secp128r1;
case (short) 160:
@@ -1037,6 +1079,19 @@ public class EC_Consts {
public static short getCurveParameter(byte curve, short param, byte[] outputBuffer, short outputOffset) {
byte alg = getCurveType(curve);
switch (curve) {
+ case CURVE_secp112r1: {
+ EC_FP_P = EC112_FP_P;
+ EC_A = EC112_FP_A;
+ EC_B = EC112_FP_B;
+ EC_G_X = EC112_FP_G_X;
+ EC_G_Y = EC112_FP_G_Y;
+ EC_R = EC112_FP_R;
+ EC_K = EC112_FP_K;
+ EC_W_X = null;
+ EC_W_Y = null;
+ EC_S = null;
+ break;
+ }
case CURVE_secp128r1: {
EC_FP_P = EC128_FP_P;
EC_A = EC128_FP_A;
diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java
index 6c2b769..5b7be01 100644
--- a/src/cz/crcs/ectester/reader/Command.java
+++ b/src/cz/crcs/ectester/reader/Command.java
@@ -429,6 +429,41 @@ public abstract class Command {
}
}
+ /**
+ *
+ */
+ public static class ECDH_direct extends Command {
+ private byte privkey;
+ private byte export;
+ private short corruption;
+ private byte type;
+ private byte[] pubkey;
+
+ protected ECDH_direct(CardMngr cardManager, byte privkey, byte export, short corruption, byte type, byte[] pubkey) {
+ super(cardManager);
+ this.privkey = privkey;
+ this.export = export;
+ this.corruption = corruption;
+ this.type = type;
+ this.pubkey = pubkey;
+
+ byte[] data = new byte[3 + pubkey.length];
+ Util.setShort(data, 0, corruption);
+ data[2] = type;
+ System.arraycopy(pubkey, 0, data, 3, pubkey.length);
+
+ this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH_DIRECT, privkey, export, data);
+ }
+
+ @Override
+ public Response.ECDH send() throws CardException {
+ long elapsed = -System.nanoTime();
+ ResponseAPDU response = cardManager.send(cmd);
+ elapsed += System.nanoTime();
+ return new Response.ECDH(response, elapsed, ECTesterApplet.KEYPAIR_REMOTE, privkey, export, corruption, type);
+ }
+ }
+
public static class ECDSA extends Command {
private byte keyPair;
private byte export;
diff --git a/src/cz/crcs/ectester/reader/TestSuite.java b/src/cz/crcs/ectester/reader/TestSuite.java
index 958c51d..7118dd8 100644
--- a/src/cz/crcs/ectester/reader/TestSuite.java
+++ b/src/cz/crcs/ectester/reader/TestSuite.java
@@ -232,8 +232,11 @@ public abstract class TestSuite {
tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS));
tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY));
tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY));
- tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY));
- tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE));
+
+ //tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY));
+ //tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE));
+ tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten()), Test.Result.FAILURE));
+
tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY));
}
}
@@ -277,8 +280,9 @@ public abstract class TestSuite {
tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS));
tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS));
for (EC_Key.Public pub : keys) {
- tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY));
- tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE));
+ // tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY));
+ // tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY), Test.Result.FAILURE));
+ tests.add(new Test(new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten()), Test.Result.FAILURE));
}
tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY));
}