diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyTester.java | 204 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECTesterApplet.java | 184 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/EC_Consts.java | 7 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_KAResult.java | 18 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/output/BaseTextTestWriter.java | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/util/CardUtil.java | 52 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/data/EC_Store.java | 21 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/ECTesterReader.java | 45 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/command/Command.java | 79 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/response/Response.java | 59 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java | 3 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/test/CardDefaultSuite.java | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/test/CardTestSuite.java | 14 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java | 2 |
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(); |
