summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cz/crcs/ectester/applet/ECKeyTester.java204
-rw-r--r--src/cz/crcs/ectester/applet/ECTesterApplet.java184
-rw-r--r--src/cz/crcs/ectester/applet/EC_Consts.java7
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_KAResult.java18
-rw-r--r--src/cz/crcs/ectester/common/output/BaseTextTestWriter.java2
-rw-r--r--src/cz/crcs/ectester/common/util/CardUtil.java52
-rw-r--r--src/cz/crcs/ectester/data/EC_Store.java21
-rw-r--r--src/cz/crcs/ectester/reader/ECTesterReader.java45
-rw-r--r--src/cz/crcs/ectester/reader/command/Command.java79
-rw-r--r--src/cz/crcs/ectester/reader/response/Response.java59
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java3
-rw-r--r--src/cz/crcs/ectester/reader/test/CardDefaultSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTestSuite.java14
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java2
15 files changed, 273 insertions, 421 deletions
diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java
index 0b3c1e0..732cb4c 100644
--- a/src/cz/crcs/ectester/applet/ECKeyTester.java
+++ b/src/cz/crcs/ectester/applet/ECKeyTester.java
@@ -3,7 +3,6 @@ package cz.crcs.ectester.applet;
import javacard.framework.CardRuntimeException;
import javacard.framework.ISO7816;
-import javacard.framework.ISOException;
import javacard.security.*;
/**
@@ -13,77 +12,35 @@ import javacard.security.*;
* @author Jan Jancar johny@neuromancer.sk
*/
public class ECKeyTester {
-
- private KeyAgreement ecdhKeyAgreement = null;
- private KeyAgreement ecdhcKeyAgreement = null;
+ private KeyAgreement ecKeyAgreement = null;
+ private short kaType = 0;
private Signature ecdsaSignature = null;
+ private short sigType = 0;
private short sw = ISO7816.SW_NO_ERROR;
- public short allocateECDH(byte algorithm) {
+ public short allocateKA(byte algorithm) {
sw = ISO7816.SW_NO_ERROR;
try {
- ecdhKeyAgreement = KeyAgreement.getInstance(algorithm, false);
+ ecKeyAgreement = KeyAgreement.getInstance(algorithm, false);
+ kaType = algorithm;
} catch (CardRuntimeException ce) {
sw = ce.getReason();
}
return sw;
}
- public short allocateECDHC(byte algorithm) {
+ public short allocateSig(byte algorithm) {
sw = ISO7816.SW_NO_ERROR;
try {
- ecdhcKeyAgreement = KeyAgreement.getInstance(algorithm, false);
+ ecdsaSignature = Signature.getInstance(algorithm, false);
+ sigType = algorithm;
} catch (CardRuntimeException ce) {
sw = ce.getReason();
}
return sw;
}
- public short allocateECDSA() {
- sw = ISO7816.SW_NO_ERROR;
- try {
- ecdsaSignature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
- } catch (CardRuntimeException ce) {
- sw = ce.getReason();
- }
- return sw;
- }
-
- private short testKA(KeyAgreement ka, KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) {
- short length = 0;
- try {
- sw = AppletUtil.kaCheck(ka);
- sw = AppletUtil.keypairCheck(privatePair);
- sw = AppletUtil.keypairCheck(publicPair);
- short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset);
- // reached ok
- ka.init(privatePair.getPrivate()); // throws UNITIALIZED KEY when ALG_EC_SVDP_DHC_PLAIN is used
- //ISOException.throwIt((short) 0x666);
-
- pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength);
- length = ka.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset);
- } catch (CardRuntimeException ce) {
- sw = ce.getReason();
- }
- 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.
@@ -98,100 +55,48 @@ public class ECKeyTester {
* @param corruption (EC_Consts.CORRUPTION_* | ...)
* @return derived secret length
**/
- public short testECDH(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) {
- 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.
- * Output should equal to ECDH output.
- *
- * @param privatePair KeyPair from which the private key is used
- * @param publicPair KeyPair from which the public key is used
- * @param pubkeyBuffer buffer to be used for the public key
- * @param pubkeyOffset offset into pubkeyBuffer that can be used for the public key
- * @param outputBuffer buffer to be used for the secret output
- * @param outputOffset offset into the outputBuffer
- * @param corruption (EC_Consts.CORRUPTION_* | ...)
- * @return derived secret length
- */
- public short testECDHC(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) {
- 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
- * @param pubkeyBuffer buffer to be used for the public key
- * @param pubkeyOffset offset into pubkeyBuffer that can be used for the public key
- * @param outputBuffer buffer to be used for the secret output
- * @param outputOffset offset into the outputBuffer
- * @param corruption (EC_Consts.CORRUPTION_* | ...)
- * @return
- */
- public short testBOTH(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) {
- short ecdhLength = testECDH(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption);
- if (sw != ISO7816.SW_NO_ERROR) {
- return ecdhLength;
- }
- short ecdhcLength = testECDHC(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, (short) (outputOffset + ecdhLength), 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;
- }
+ public short testKA(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) {
+ short length = 0;
+ try {
+ sw = AppletUtil.kaCheck(ecKeyAgreement);
+ sw = AppletUtil.keypairCheck(privatePair);
+ sw = AppletUtil.keypairCheck(publicPair);
+ short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset);
+ // reached ok
+ ecKeyAgreement.init(privatePair.getPrivate()); // throws UNITIALIZED KEY when ALG_EC_SVDP_DHC_PLAIN is used
+ //ISOException.throwIt((short) 0x666);
- 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;
+ pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength);
+ length = ecKeyAgreement.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset);
+ } catch (CardRuntimeException ce) {
+ sw = ce.getReason();
}
return length;
}
/**
- * @param privatePair KeyPair from which the private key is used
- * @param publicPair KeyPair from which the public key is used
- * @param pubkeyBuffer buffer to be used for the public key
- * @param pubkeyOffset offset into pubkeyBuffer that can be used for the public key
- * @param outputBuffer buffer to be used for the secret output
- * @param outputOffset offset into the outputBuffer
- * @param corruption (EC_Consts.CORRUPTION_* | ...)
+ * @param privatePair
+ * @param pubkey
+ * @param pubkeyOffset
+ * @param pubkeyLength
+ * @param outpuBuffer
+ * @param outputOffset
+ * @param corruption
* @return
*/
- public short testANY(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) {
- short ecdhLength = testECDH(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption);
- if (sw == ISO7816.SW_NO_ERROR)
- return ecdhLength;
- return testECDHC(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption);
- }
+ public short testKA_direct(KeyPair privatePair, byte[] pubkey, short pubkeyOffset, short pubkeyLength, byte[] outpuBuffer, short outputOffset, short corruption) {
+ short length = 0;
+ try {
+ sw = AppletUtil.kaCheck(ecKeyAgreement);
+ sw = AppletUtil.keypairCheck(privatePair);
- 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);
+ ecKeyAgreement.init(privatePair.getPrivate());
+ pubkeyLength = EC_Consts.corruptParameter(corruption, pubkey, pubkeyOffset, pubkeyLength);
+ length = ecKeyAgreement.generateSecret(pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset);
+ } catch (CardRuntimeException ce) {
+ sw = ce.getReason();
+ }
+ return length;
}
/**
@@ -227,32 +132,31 @@ public class ECKeyTester {
return length;
}
- public KeyAgreement getECDH() {
- return ecdhKeyAgreement;
+ public KeyAgreement getKA() {
+ return ecKeyAgreement;
}
- public KeyAgreement getECDHC() {
- return ecdhcKeyAgreement;
+ public Signature getSig() {
+ return ecdsaSignature;
}
- public Signature getECDSA() {
- return ecdsaSignature;
+ public boolean hasKA() {
+ return ecKeyAgreement != null;
}
- public boolean hasECDH() {
- return ecdhKeyAgreement != null;
+ public boolean hasSig() {
+ return ecdsaSignature != null;
}
- public boolean hasECDHC() {
- return ecdhcKeyAgreement != null;
+ public short getKaType() {
+ return kaType;
}
- public boolean hasECDSA() {
- return ecdsaSignature != null;
+ public short getSigType() {
+ return sigType;
}
public short getSW() {
return sw;
}
-
}
diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java
index deb3aae..870fb3d 100644
--- a/src/cz/crcs/ectester/applet/ECTesterApplet.java
+++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java
@@ -26,11 +26,7 @@
package cz.crcs.ectester.applet;
import javacard.framework.*;
-import javacard.security.ECPrivateKey;
-import javacard.security.ECPublicKey;
-import javacard.security.KeyAgreement;
-import javacard.security.KeyPair;
-import javacard.security.RandomData;
+import javacard.security.*;
import javacardx.apdu.ExtendedLength;
/**
@@ -55,8 +51,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
public static final byte INS_ECDH_DIRECT = (byte) 0x71;
public static final byte INS_ECDSA = (byte) 0x72;
public static final byte INS_CLEANUP = (byte) 0x73;
- public static final byte INS_SUPPORT = (byte) 0x74;
+ //public static final byte INS_SUPPORT = (byte) 0x74;
public static final byte INS_ALLOCATE_KA = (byte) 0x75;
+ public static final byte INS_ALLOCATE_SIG = (byte) 0x76;
// PARAMETERS for P1 and P2
@@ -88,6 +85,13 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6;
public static final byte KeyAgreement_ALG_DH_PLAIN = 7;
+ // Class javacard.security.Signature
+ // javacard.security.Signature Fields:
+ public static final byte Signature_ALG_ECDSA_SHA = 17;
+ public static final byte Signature_ALG_ECDSA_SHA_256 = 33;
+ public static final byte Signature_ALG_ECDSA_SHA_384 = 34;
+ public static final byte Signature_ALG_ECDSA_SHA_224 = 37;
+ public static final byte Signature_ALG_ECDSA_SHA_512 = 38;
private static final short ARRAY_LENGTH = (short) 0xff;
private static final short APDU_MAX_LENGTH = (short) 1024;
@@ -98,13 +102,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
// PERSISTENT ARRAY IN EEPROM
private byte[] dataArray = null; // unused
-
private RandomData randomData = null;
private ECKeyTester keyTester = null;
- private short ecdhSW;
- private short ecdhcSW;
- private short ecdsaSW;
private ECKeyGenerator keyGenerator = null;
private KeyPair localKeypair = null;
private KeyPair remoteKeypair = null;
@@ -133,11 +133,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
keyGenerator = new ECKeyGenerator();
keyTester = new ECKeyTester();
- ecdhSW = keyTester.allocateECDH(KeyAgreement.ALG_EC_SVDP_DH);
- ecdhcSW = keyTester.allocateECDHC(KeyAgreement.ALG_EC_SVDP_DHC);
- //ecdhSW = keyTester.allocateECDH((byte) 3);
- //ecdhcSW = keyTester.allocateECDHC((byte) 4);
- ecdsaSW = keyTester.allocateECDSA();
}
register();
}
@@ -166,6 +161,9 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
case INS_ALLOCATE_KA:
length = insAllocateKA(apdu);
break;
+ case INS_ALLOCATE_SIG:
+ length = insAllocateSig(apdu);
+ break;
case INS_ALLOCATE:
length = insAllocate(apdu);
break;
@@ -196,9 +194,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
case INS_CLEANUP:
length = insCleanup(apdu);
break;
- case INS_SUPPORT:
- length = insSupport(apdu);
- break;
default:
// The INS code is not supported by the dispatcher
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
@@ -210,7 +205,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
}
/**
- * Allocates KeyAgreement object. returns allocate SW
+ * Allocates KeyAgreement object, returns allocate SW.
*
* @param apdu DATA = byte KeyAgreementType
* @return length of response
@@ -218,35 +213,25 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
private short insAllocateKA(APDU apdu) {
short cdata = apdu.getOffsetCdata();
byte kaType = apduArray[cdata];
-/*
- short sw = SW_KA_UNSUPPORTED;
- switch (kaType) {
- case KeyAgreement_ALG_EC_SVDP_DH: // no break
- case KeyAgreement_ALG_EC_SVDP_DH_PLAIN:
- case KeyAgreement_ALG_EC_PACE_GM:
- case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY:
- sw = keyTester.allocateECDH(kaType);
- break;
- case KeyAgreement_ALG_EC_SVDP_DHC:
- case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN:
- sw = keyTester.allocateECDHC(kaType);
- break;
- default:
- sw = SW_KA_UNSUPPORTED;
- break;
- }
-*/
- // Allocate given type into both DH and DHC objects
- short sw = keyTester.allocateECDH(kaType);
- short offset = 0;
- Util.setShort(apdu.getBuffer(), offset, sw);
- offset += 2;
+ short sw = keyTester.allocateKA(kaType);
+ Util.setShort(apdu.getBuffer(), (short) 0, sw);
+ return 2;
+ }
- //sw = keyTester.allocateECDHC(kaType);
- Util.setShort(apdu.getBuffer(), offset, sw);
- offset += 2;
- return offset;
+ /**
+ * Allocates a Signature object, returns allocate SW.
+ *
+ * @param apdu DATA = byte SignatureType
+ * @return length of response
+ */
+ private short insAllocateSig(APDU apdu) {
+ short cdata = apdu.getOffsetCdata();
+ byte sigType = apduArray[cdata];
+ short sw = keyTester.allocateSig(sigType);
+ Util.setShort(apdu.getBuffer(), (short) 0, sw);
+ return 2;
}
+
/**
* Allocates local and remote keyPairs.
* returns allocate SWs
@@ -449,7 +434,8 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
*
* @param apdu P1 = byte keyPair (KEYPAIR_*)
* P2 = byte export (EXPORT_TRUE || EXPORT_FALSE)
- * DATA = short dataLength (00 = random data generated, !00 = data length)
+ * DATA = byte sigType
+ * short dataLength (00 = random data generated, !00 = data length)
* byte[] data
* @return length of response
*/
@@ -457,13 +443,14 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
byte keyPair = apduArray[ISO7816.OFFSET_P1];
byte export = apduArray[ISO7816.OFFSET_P2];
short cdata = apdu.getOffsetCdata();
+ byte sigType = apduArray[cdata];
short len = 0;
if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += ecdsa(localKeypair, export, apduArray, cdata, apdu.getBuffer(), (short) 0);
+ len += ecdsa(localKeypair, sigType, export, apduArray, cdata, apdu.getBuffer(), (short) 0);
}
if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += ecdsa(remoteKeypair, export, apduArray, cdata, apdu.getBuffer(), len);
+ len += ecdsa(remoteKeypair, sigType, export, apduArray, cdata, apdu.getBuffer(), len);
}
return len;
@@ -482,19 +469,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
}
/**
- * Returns data about card support for various EC related tasks collected on applet
- * install.
- *
- * @param apdu no data
- * @return length of response
- */
- private short insSupport(APDU apdu) {
- byte[] apdubuf = apdu.getBuffer();
-
- return support(apdubuf, (short) 0);
- }
-
- /**
* @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...)
* @param keyLength key length to set
* @param keyClass key class to allocate
@@ -625,7 +599,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
* @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE)
* @param export whether to export ECDH secret
* @param corruption whether to invalidate the pubkey before ECDH
- * @param type KeyAgreement type to test (EC_Consts.KA_* || ...)
+ * @param type KeyAgreement type to test
* @param outBuffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)}
* @param outOffset output offset in buffer
* @return length of data written to the buffer
@@ -637,23 +611,14 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair;
short secretLength = 0;
- switch (type) {
- case EC_Consts.KA_ECDH:
- secretLength = keyTester.testECDH(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption);
- break;
- case EC_Consts.KA_ECDHC:
- secretLength = keyTester.testECDHC(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption);
- break;
- case EC_Consts.KA_BOTH:
- secretLength = keyTester.testBOTH(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption);
- break;
- case EC_Consts.KA_ANY:
- secretLength = keyTester.testANY(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption);
- break;
- default:
- ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
+ if (keyTester.getKaType() == type) {
+ secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption);
+ } else {
+ short allocateSW = keyTester.allocateKA(type);
+ if (allocateSW == ISO7816.SW_NO_ERROR) {
+ secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption);
+ }
}
-
Util.setShort(outBuffer, outOffset, keyTester.getSW());
length += 2;
@@ -673,21 +638,13 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
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);
+ if (keyTester.getKaType() == type) {
+ secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, corruption);
+ } else {
+ short allocateSW = keyTester.allocateKA(type);
+ if (allocateSW == ISO7816.SW_NO_ERROR) {
+ secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, corruption);
+ }
}
Util.setShort(outBuffer, outOffset, keyTester.getSW());
@@ -704,6 +661,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
/**
* @param sign keyPair to use for signing and verification
+ * @param sigType Signature type to use
* @param export whether to export ECDSA signature
* @param inBuffer buffer to read dataLength and data to sign from
* @param inOffset input offset in buffer
@@ -711,7 +669,7 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
* @param outOffset output offset in buffer
* @return length of data written to the buffer
*/
- private short ecdsa(KeyPair sign, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) {
+ private short ecdsa(KeyPair sign, byte sigType, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) {
short length = 0;
short dataLength = Util.getShort(inBuffer, inOffset);
@@ -723,7 +681,15 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
Util.arrayCopyNonAtomic(inBuffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength);
}
- short signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0);
+ short signatureLength = 0;
+ if (keyTester.getSigType() == sigType) {
+ signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0);
+ } else {
+ short allocateSW = keyTester.allocateSig(sigType);
+ if (allocateSW == ISO7816.SW_NO_ERROR) {
+ signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0);
+ }
+ }
Util.setShort(outBuffer, outOffset, keyTester.getSW());
length += 2;
@@ -755,30 +721,4 @@ public class ECTesterApplet extends Applet implements ExtendedLength {
Util.setShort(buffer, offset, sw);
return 2;
}
-
- /**
- * @param buffer buffer to write sw to
- * @param offset output offset in buffer
- * @return length of data written to the buffer
- */
- private short support(byte[] buffer, short offset) {
-
- if (keyTester.hasECDH()) {
- Util.setShort(buffer, offset, ecdhSW);
- } else {
- Util.setShort(buffer, offset, ISO7816.SW_FUNC_NOT_SUPPORTED);
- }
- if (keyTester.hasECDHC()) {
- Util.setShort(buffer, (short) (offset + 2), ecdhcSW);
- } else {
- Util.setShort(buffer, (short) (offset + 2), ISO7816.SW_FUNC_NOT_SUPPORTED);
- }
- if (keyTester.hasECDSA()) {
- Util.setShort(buffer, (short) (offset + 4), ecdsaSW);
- } else {
- Util.setShort(buffer, (short) (offset + 4), ISO7816.SW_FUNC_NOT_SUPPORTED);
- }
-
- return 6;
- }
}
diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java
index 04cd55e..15cb7fa 100644
--- a/src/cz/crcs/ectester/applet/EC_Consts.java
+++ b/src/cz/crcs/ectester/applet/EC_Consts.java
@@ -59,13 +59,6 @@ public class EC_Consts {
public static final byte KEY_PRIVATE = 0x02;
public static final byte KEY_BOTH = KEY_PUBLIC | KEY_PRIVATE;
-
- // Key Agreement test identifiers
- public static final byte KA_ECDH = 0x01;
- public static final byte KA_ECDHC = 0x02;
- public static final byte KA_BOTH = KA_ECDH | KA_ECDHC;
- public static final byte KA_ANY = 0x04;
-
public static RandomData randomData = null;
// secp112r1
diff --git a/src/cz/crcs/ectester/common/ec/EC_KAResult.java b/src/cz/crcs/ectester/common/ec/EC_KAResult.java
index a7b3cd5..8a5fcb4 100644
--- a/src/cz/crcs/ectester/common/ec/EC_KAResult.java
+++ b/src/cz/crcs/ectester/common/ec/EC_KAResult.java
@@ -8,15 +8,14 @@ import cz.crcs.ectester.common.util.CardUtil;
* @author Jan Jancar johny@neuromancer.sk
*/
public class EC_KAResult extends EC_Data {
-
- private byte ka;
+ private String ka;
private String curve;
private String oneKey;
private String otherKey;
private String desc;
- public EC_KAResult(byte ka, String curve, String oneKey, String otherKey) {
+ public EC_KAResult(String ka, String curve, String oneKey, String otherKey) {
super(1);
this.ka = ka;
this.curve = curve;
@@ -24,20 +23,24 @@ public class EC_KAResult extends EC_Data {
this.otherKey = otherKey;
}
- public EC_KAResult(String id, byte ka, String curve, String oneKey, String otherKey) {
+ public EC_KAResult(String id, String ka, String curve, String oneKey, String otherKey) {
this(ka, curve, oneKey, otherKey);
this.id = id;
}
- public EC_KAResult(String id, byte ka, String curve, String oneKey, String otherKey, String desc) {
+ public EC_KAResult(String id, String ka, String curve, String oneKey, String otherKey, String desc) {
this(id, ka, curve, oneKey, otherKey);
this.desc = desc;
}
- public byte getKA() {
+ public String getKA() {
return ka;
}
+ public byte getJavaCardKA() {
+ return CardUtil.getKA(ka);
+ }
+
public String getCurve() {
return curve;
}
@@ -56,8 +59,7 @@ public class EC_KAResult extends EC_Data {
@Override
public String toString() {
- String algo = CardUtil.getKA(ka);
- return "<" + getId() + "> " + algo + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc);
+ return "<" + getId() + "> " + ka + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc);
}
}
diff --git a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java
index 9635d0c..7e0e1a3 100644
--- a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java
+++ b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java
@@ -10,7 +10,7 @@ import java.io.PrintStream;
public abstract class BaseTextTestWriter implements TestWriter {
private PrintStream output;
- public static int BASE_WIDTH = 76;
+ public static int BASE_WIDTH = 80;
public BaseTextTestWriter(PrintStream output) {
this.output = output;
diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java
index edcb510..55c4277 100644
--- a/src/cz/crcs/ectester/common/util/CardUtil.java
+++ b/src/cz/crcs/ectester/common/util/CardUtil.java
@@ -12,6 +12,18 @@ import static cz.crcs.ectester.applet.ECTesterApplet.*;
* @author Jan Jancar johny@neuromancer.sk
*/
public class CardUtil {
+ public static byte getKA(String name) {
+ switch (name) {
+ case "DH":
+ case "ECDH":
+ return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH;
+ case "DHC":
+ case "ECDHC":
+ return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC;
+ }
+ return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH;
+ }
+
public static String getSWSource(short sw) {
switch (sw) {
case ISO7816.SW_NO_ERROR:
@@ -214,22 +226,6 @@ public class CardUtil {
return corrupt;
}
- public static String getKA(byte ka) {
- String algo = "";
- if ((ka & EC_Consts.KA_ECDH) != 0 || ka == EC_Consts.KA_ANY) {
- algo += "ECDH";
- }
- if (ka == EC_Consts.KA_BOTH) {
- algo += "+";
- } else if (ka == EC_Consts.KA_ANY) {
- algo += "/";
- }
- if ((ka & EC_Consts.KA_ECDHC) != 0 || ka == EC_Consts.KA_ANY) {
- algo += "ECDHC";
- }
- return algo;
- }
-
public static String getKATypeString(byte kaType) {
String kaTypeString;
switch (kaType) {
@@ -256,4 +252,28 @@ public class CardUtil {
}
return kaTypeString;
}
+
+ public static String getSigTypeString(byte sigType) {
+ String sigTypeString;
+ switch (sigType) {
+ case Signature_ALG_ECDSA_SHA:
+ sigTypeString = "ALG_ECDSA_SHA";
+ break;
+ case Signature_ALG_ECDSA_SHA_224:
+ sigTypeString = "ALG_ECDSA_SHA_224";
+ break;
+ case Signature_ALG_ECDSA_SHA_256:
+ sigTypeString = "ALG_ECDSA_SHA_256";
+ break;
+ case Signature_ALG_ECDSA_SHA_384:
+ sigTypeString = "ALG_ECDSA_SHA_384";
+ break;
+ case Signature_ALG_ECDSA_SHA_512:
+ sigTypeString = "ALG_ECDSA_SHA_512";
+ break;
+ default:
+ sigTypeString = "unknown";
+ }
+ return sigTypeString;
+ }
}
diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java
index 3103c1d..c25be4e 100644
--- a/src/cz/crcs/ectester/data/EC_Store.java
+++ b/src/cz/crcs/ectester/data/EC_Store.java
@@ -2,6 +2,7 @@ package cz.crcs.ectester.data;
import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.common.ec.*;
+import cz.crcs.ectester.common.util.CardUtil;
import javacard.security.KeyPair;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -217,25 +218,7 @@ public class EC_Store {
descs = descc.item(0).getTextContent();
}
- byte kab = EC_Consts.KA_ANY;
- switch (ka.getTextContent()) {
- case "DH":
- case "ECDH":
- kab = EC_Consts.KA_ECDH;
- break;
- case "DHC":
- case "ECDHC":
- kab = EC_Consts.KA_ECDHC;
- break;
- case "ANY":
- kab = EC_Consts.KA_ANY;
- break;
- case "BOTH":
- kab = EC_Consts.KA_BOTH;
- break;
- }
-
- EC_KAResult kaResult = new EC_KAResult(id.getTextContent(), kab, curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs);
+ EC_KAResult kaResult = new EC_KAResult(id.getTextContent(), ka.getTextContent(), curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs);
InputStream csv = parseDataElement(dir, elem);
if (!kaResult.readCSV(csv)) {
diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java
index f566c9c..4e62f3f 100644
--- a/src/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/src/cz/crcs/ectester/reader/ECTesterReader.java
@@ -47,6 +47,7 @@ import java.nio.file.Files;
import java.util.*;
import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH;
+import static cz.crcs.ectester.applet.ECTesterApplet.Signature_ALG_ECDSA_SHA;
/**
* Reader part of ECTester, a tool for testing Elliptic curve support on javacards.
@@ -218,8 +219,7 @@ public class ECTesterReader {
* -e / --export
* -g / --generate [amount]
* -t / --test [test_suite]
- * -dh / --ecdh [count]
- * -dhc / --ecdhc [count]
+ * -dh / --ecdh [count]]
* -dsa / --ecdsa [count]
* -ln / --list-named [obj]
*
@@ -253,6 +253,7 @@ public class ECTesterReader {
* -s / --simulate
* -y / --yes
* -ka/ --ka-type <type>
+ * -sig/--sig-type <type>
*/
OptionGroup actions = new OptionGroup();
actions.setRequired(true);
@@ -262,8 +263,7 @@ public class ECTesterReader {
actions.addOption(Option.builder("e").longOpt("export").desc("Export the defaut curve parameters of the card(if any).").build());
actions.addOption(Option.builder("g").longOpt("generate").desc("Generate [amount] of EC keys.").hasArg().argName("amount").optionalArg(true).build());
actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. [test_suite]:\n- default:\n- invalid:\n- wrong:\n- composite:\n- test-vectors:").hasArg().argName("test_suite").optionalArg(true).build());
- actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do ECDH, [count] times.").hasArg().argName("count").optionalArg(true).build());
- actions.addOption(Option.builder("dhc").longOpt("ecdhc").desc("Do ECDHC, [count] times.").hasArg().argName("count").optionalArg(true).build());
+ actions.addOption(Option.builder("ka").longOpt("ecka").desc("Do EC KeyAgreement (ECDH...), [count] times.").hasArg().argName("count").optionalArg(true).build());
actions.addOption(Option.builder("dsa").longOpt("ecdsa").desc("Sign data with ECDSA, [count] times.").hasArg().argName("count").optionalArg(true).build());
opts.addOptionGroup(actions);
@@ -308,6 +308,7 @@ public class ECTesterReader {
opts.addOption(Option.builder("y").longOpt("yes").desc("Accept all warnings and prompts.").build());
opts.addOption(Option.builder("ka").longOpt("ka-type").desc("Set KeyAgreement object [type], corresponds to JC.KeyAgreement constants.").hasArg().argName("type").optionalArg(true).build());
+ opts.addOption(Option.builder("sig").longOpt("sig-type").desc("Set Signature object [type], corresponds to JC.Signature constants.").hasArg().argName("type").optionalArg(true).build());
CommandLineParser parser = new DefaultParser();
return parser.parse(opts, args);
@@ -464,7 +465,7 @@ public class ECTesterReader {
private void ecdh() throws IOException, CardException {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
List<Response> prepare = new LinkedList<>();
- prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.kaType).send()); // Prepare KeyAgreement or required type
+ prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.ECKAType).send()); // Prepare KeyAgreement or required type
prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass).send());
Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass);
if (curve != null)
@@ -491,10 +492,10 @@ public class ECTesterReader {
int retry = 0;
int done = 0;
- while (done < cfg.ECDHCount) {
+ while (done < cfg.ECKACount) {
List<Response> ecdh = Command.sendAll(generate);
- Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send();
+ Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECKAType).send();
ecdh.add(perform);
for (Response r : ecdh) {
respWriter.outputResponse(r);
@@ -550,6 +551,7 @@ public class ECTesterReader {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
List<Response> prepare = new LinkedList<>();
+ prepare.add(new Command.AllocateSignature(cardManager, cfg.ECDSAType).send());
prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send());
Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass);
if (curve != null)
@@ -571,7 +573,7 @@ public class ECTesterReader {
List<Response> ecdsa = new LinkedList<>();
ecdsa.add(generate.send());
- Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, data).send();
+ Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.ECDSAType, ECTesterApplet.EXPORT_TRUE, data).send();
ecdsa.add(perform);
for (Response r : ecdsa) {
respWriter.outputResponse(r);
@@ -612,7 +614,7 @@ public class ECTesterReader {
public boolean all;
public boolean primeField = false;
public boolean binaryField = false;
- public byte kaType = KeyAgreement_ALG_EC_SVDP_DH;
+
public String namedCurve;
public String curveFile;
@@ -646,9 +648,10 @@ public class ECTesterReader {
public String listNamed;
public String testSuite;
public int generateAmount;
- public int ECDHCount;
- public byte ECDHKA;
+ public int ECKACount;
+ public byte ECKAType = KeyAgreement_ALG_EC_SVDP_DH;
public int ECDSACount;
+ public byte ECDSAType = Signature_ALG_ECDSA_SHA;
/**
* Reads and validates options, also sets defaults.
@@ -661,7 +664,7 @@ public class ECTesterReader {
all = cli.hasOption("all");
primeField = cli.hasOption("fp");
binaryField = cli.hasOption("f2m");
- kaType = Byte.parseByte(cli.getOptionValue("ka-type", "1"));
+
namedCurve = cli.getOptionValue("named-curve");
customCurve = cli.hasOption("custom");
@@ -779,7 +782,7 @@ public class ECTesterReader {
return false;
}
- } else if (cli.hasOption("ecdh") || cli.hasOption("ecdhc")) {
+ } else if (cli.hasOption("ecka")) {
if (primeField == binaryField) {
System.err.print("Need to specify field with -fp or -f2m. (not both)");
return false;
@@ -789,18 +792,14 @@ public class ECTesterReader {
return false;
}
- if (cli.hasOption("ecdh")) {
- ECDHCount = Integer.parseInt(cli.getOptionValue("ecdh", "1"));
- ECDHKA = EC_Consts.KA_ECDH;
- } else if (cli.hasOption("ecdhc")) {
- ECDHCount = Integer.parseInt(cli.getOptionValue("ecdhc", "1"));
- ECDHKA = EC_Consts.KA_ECDHC;
- }
- if (ECDHCount <= 0) {
- System.err.println("ECDH count cannot be <= 0.");
+ ECKACount = Integer.parseInt(cli.getOptionValue("ecka", "1"));
+ if (ECKACount <= 0) {
+ System.err.println("ECKA count cannot be <= 0.");
return false;
}
+ ECKAType = Byte.parseByte(cli.getOptionValue("ka-type", "1"));
+
} else if (cli.hasOption("ecdsa")) {
if (primeField == binaryField) {
System.err.print("Need to specify field with -fp or -f2m. (but not both)");
@@ -821,6 +820,8 @@ public class ECTesterReader {
System.err.println("ECDSA count cannot be <= 0.");
return false;
}
+
+ ECDSAType = Byte.parseByte(cli.getOptionValue("sig-type", "17"));
}
return true;
}
diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java
index 922a33a..5a6906c 100644
--- a/src/cz/crcs/ectester/reader/command/Command.java
+++ b/src/cz/crcs/ectester/reader/command/Command.java
@@ -252,7 +252,40 @@ public abstract class Command {
public String toString() {
return "AllocateKeyAgreement";
}
- }
+ }
+
+ /**
+ *
+ */
+ public static class AllocateSignature extends Command {
+ private byte sigType;
+
+ /**
+ * Creates the INS_ALLOCATE_SIG instruction.
+ *
+ * @param cardManager cardManager to send APDU through
+ * @param sigType which type of Signature to use
+ */
+ public AllocateSignature(CardMngr cardManager, byte sigType) {
+ super(cardManager);
+ this.sigType = sigType;
+ byte[] data = new byte[]{sigType};
+ this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE_SIG, 0x00, 0x00, data);
+ }
+
+ @Override
+ public Response.AllocateSignature send() throws CardException {
+ long elapsed = -System.nanoTime();
+ ResponseAPDU response = cardManager.send(cmd);
+ elapsed += System.nanoTime();
+ return new Response.AllocateSignature(response, elapsed, sigType);
+ }
+
+ @Override
+ public String toString() {
+ return "AllocateSignature";
+ }
+ }
/**
*
@@ -518,7 +551,7 @@ public abstract class Command {
* @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE)
* @param export whether to export ECDH secret
* @param corruption whether to invalidate the pubkey before ECDH (EC_Consts.CORRUPTION_* | ...)
- * @param type ECDH algorithm type (EC_Consts.KA_* | ...)
+ * @param type EC KeyAgreement type
* @param pubkey pubkey data to do ECDH with.
*/
public ECDH_direct(CardMngr cardManager, byte privkey, byte export, short corruption, byte type, byte[] pubkey) {
@@ -553,6 +586,7 @@ public abstract class Command {
public static class ECDSA extends Command {
private byte keyPair;
+ private byte sigType;
private byte export;
private byte[] raw;
@@ -561,20 +595,23 @@ public abstract class Command {
*
* @param cardManager cardManager to send APDU through
* @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE)
+ * @param sigType Signature type to use
* @param export whether to export ECDSA signature
* @param raw data to sign, can be null, in which case random data is signed.
*/
- public ECDSA(CardMngr cardManager, byte keyPair, byte export, byte[] raw) {
+ public ECDSA(CardMngr cardManager, byte keyPair, byte sigType, byte export, byte[] raw) {
super(cardManager);
this.keyPair = keyPair;
+ this.sigType = sigType;
this.export = export;
this.raw = raw;
int len = raw != null ? raw.length : 0;
- byte[] data = new byte[2 + len];
- ByteUtil.setShort(data, 0, (short) len);
+ byte[] data = new byte[3 + len];
+ data[0] = sigType;
+ ByteUtil.setShort(data, 1, (short) len);
if (raw != null) {
- System.arraycopy(raw, 0, data, 2, len);
+ System.arraycopy(raw, 0, data, 3, len);
}
this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keyPair, export, data);
@@ -585,7 +622,7 @@ public abstract class Command {
long elapsed = -System.nanoTime();
ResponseAPDU response = cardManager.send(cmd);
elapsed += System.nanoTime();
- return new Response.ECDSA(response, elapsed, keyPair, export, raw);
+ return new Response.ECDSA(response, elapsed, keyPair, sigType, export, raw);
}
@Override
@@ -621,33 +658,5 @@ public abstract class Command {
return "Cleanup";
}
}
-
- /**
- *
- */
- public static class Support extends Command {
-
- /**
- * @param cardManager cardManager to send APDU through
- */
- public Support(CardMngr cardManager) {
- super(cardManager);
-
- this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SUPPORT, 0, 0);
- }
-
- @Override
- public Response.Support send() throws CardException {
- long elapsed = -System.nanoTime();
- ResponseAPDU response = cardManager.send(cmd);
- elapsed += System.nanoTime();
- return new Response.Support(response, elapsed);
- }
-
- @Override
- public String toString() {
- return "Support";
- }
- }
}
diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java
index 3b5d98b..cbed3b2 100644
--- a/src/cz/crcs/ectester/reader/response/Response.java
+++ b/src/cz/crcs/ectester/reader/response/Response.java
@@ -133,24 +133,44 @@ public abstract class Response {
*
*/
public static class AllocateKeyAgreement extends Response {
- byte kaType;
+ private byte kaType;
public AllocateKeyAgreement(ResponseAPDU response, long time, byte kaType) {
super(response, time);
this.kaType = kaType;
- parse(2, 0);
+ parse(1, 0);
}
@Override
public String getDescription() {
return String.format("Allocated KeyAgreement(%s) object", CardUtil.getKATypeString(this.kaType));
}
+ }
+
+ /**
+ *
+ */
+ public static class AllocateSignature extends Response {
+ private byte sigType;
+
+ public AllocateSignature(ResponseAPDU response, long time, byte sigType) {
+ super(response, time);
+ this.sigType = sigType;
+ parse(1, 0);
+ }
+
+ @Override
+ public String getDescription() {
+ return String.format("Allocated Signature(%s) object", CardUtil.getSigTypeString(this.sigType));
+ }
}
+ /**
+ *
+ */
public static class Allocate extends Response {
-
private byte keyPair;
private short keyLength;
private byte keyClass;
@@ -184,7 +204,6 @@ public abstract class Response {
*
*/
public static class Clear extends Response {
-
private byte keyPair;
public Clear(ResponseAPDU response, long time, byte keyPair) {
@@ -213,7 +232,6 @@ public abstract class Response {
*
*/
public static class Set extends Response {
-
private byte keyPair;
private byte curve;
private short parameters;
@@ -271,7 +289,6 @@ public abstract class Response {
*
*/
public static class Corrupt extends Response {
-
private byte keyPair;
private byte key;
private short params;
@@ -309,7 +326,6 @@ public abstract class Response {
*
*/
public static class Generate extends Response {
-
private byte keyPair;
public Generate(ResponseAPDU response, long time, byte keyPair) {
@@ -339,7 +355,6 @@ public abstract class Response {
*
*/
public static class Export extends Response {
-
private byte keyPair;
private byte key;
private short parameters;
@@ -448,7 +463,6 @@ public abstract class Response {
*
*/
public static class ECDH extends Response {
-
private byte pubkey;
private byte privkey;
private byte export;
@@ -480,7 +494,7 @@ public abstract class Response {
@Override
public String getDescription() {
- String algo = CardUtil.getKA(type);
+ String algo = CardUtil.getKATypeString(type);
String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote";
String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote";
@@ -499,14 +513,15 @@ public abstract class Response {
*
*/
public static class ECDSA extends Response {
-
private byte keyPair;
+ private byte sigType;
private byte export;
private byte[] raw;
- public ECDSA(ResponseAPDU response, long time, byte keyPair, byte export, byte[] raw) {
+ public ECDSA(ResponseAPDU response, long time, byte keyPair, byte sigType, byte export, byte[] raw) {
super(response, time);
this.keyPair = keyPair;
+ this.sigType = sigType;
this.export = export;
this.raw = raw;
@@ -523,9 +538,10 @@ public abstract class Response {
@Override
public String getDescription() {
+ String algo = CardUtil.getSigTypeString(sigType);
String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote";
String data = raw == null ? "random" : "provided";
- return String.format("ECDSA with %s keypair(%s data)", key, data);
+ return String.format("%s with %s keypair(%s data)", algo, key, data);
}
}
@@ -546,21 +562,4 @@ public abstract class Response {
}
}
-
- /**
- *
- */
- public static class Support extends Response {
-
- public Support(ResponseAPDU response, long time) {
- super(response, time);
-
- parse(3, 0);
- }
-
- @Override
- public String getDescription() {
- return "Support of ECDH, ECDHC, ECDSA allocation";
- }
- }
}
diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java
index 930a0d0..08e45ac 100644
--- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java
@@ -8,6 +8,7 @@ import cz.crcs.ectester.reader.ECTesterReader;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.common.ec.EC_Curve;
import cz.crcs.ectester.common.ec.EC_Key;
+import javacard.security.KeyAgreement;
import javacard.security.KeyPair;
import java.util.Map;
@@ -44,7 +45,7 @@ public class CardCompositeCurvesSuite extends CardTestSuite {
tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY));
tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY));
- Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten());
+ Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten());
tests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key."));
tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY));
}
diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
index 06818d4..eb46de0 100644
--- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java
@@ -23,7 +23,7 @@ public class CardDefaultSuite extends CardTestSuite {
@Override
public void setup(CardMngr cardManager) throws IOException {
- tests.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY));
+ //tests.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY));
if (cfg.namedCurve != null) {
String desc = "Default tests over the " + cfg.namedCurve + " curve category.";
if (cfg.primeField) {
diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java
index e4e55c9..00e3a46 100644
--- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java
@@ -60,7 +60,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite {
tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS));
List<Test> ecdhTests = new LinkedList<>();
for (EC_Key.Public pub : keys) {
- Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten());
+ Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten());
ecdhTests.add(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve."));
}
tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0])));
diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java
index 3da5158..5d34a13 100644
--- a/src/cz/crcs/ectester/reader/test/CardTestSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java
@@ -47,13 +47,13 @@ public abstract class CardTestSuite extends TestSuite {
List<Test> tests = new LinkedList<>();
tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected));
- tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected));
- tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected));
- tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
- tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
- tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
- tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
- tests.add(CommandTest.expect(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected));
+ tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ecdhExpected));
+ tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ecdhExpected));
+ tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE));
+ tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE));
+ tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE));
+ tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), ExpectedValue.FAILURE));
+ tests.add(CommandTest.expect(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.Signature_ALG_ECDSA_SHA, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected));
return CompoundTest.function((testArray) -> {
Function<ExpectedValue, String> shouldHave = (expected) -> {
diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
index 72e3cce..e1c499c 100644
--- a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
@@ -67,7 +67,7 @@ public class CardTestVectorSuite extends CardTestSuite {
//tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS));
- testVector.add(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), new TestCallback<CommandTestable>() {
+ testVector.add(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getJavaCardKA()), new TestCallback<CommandTestable>() {
@Override
public Result apply(CommandTestable testable) {
Response.ECDH dh = (Response.ECDH) testable.getResponse();