diff options
Diffstat (limited to 'src')
11 files changed, 347 insertions, 77 deletions
diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 27bb9e1..7c091e3 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -130,6 +130,56 @@ public class ECKeyTester { return length; } + /** + * + * @param signKey + * @param inputBuffer + * @param inputOffset + * @param inputLength + * @param sigBuffer + * @param sigOffset + * @return + */ + public short testECDSA_sign(ECPrivateKey signKey, byte[] inputBuffer, short inputOffset, short inputLength, byte[] sigBuffer, short sigOffset) { + short length = 0; + try { + sw = AppletUtil.signCheck(ecdsaSignature); + + ecdsaSignature.init(signKey, Signature.MODE_SIGN); + length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); + } catch (CardRuntimeException ce) { + sw = ce.getReason(); + } + return length; + } + + /** + * + * @param verifyKey + * @param inputBuffer + * @param inputOffset + * @param inputLength + * @param sigBuffer + * @param sigOffset + * @param sigLength + * @return + */ + public short testECDSA_verify(ECPublicKey verifyKey, byte[] inputBuffer, short inputOffset, short inputLength, byte[] sigBuffer, short sigOffset, short sigLength) { + short length = 0; + try { + sw = AppletUtil.signCheck(ecdsaSignature); + + ecdsaSignature.init(verifyKey, Signature.MODE_VERIFY); + boolean correct = ecdsaSignature.verify(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset, sigLength); + if (!correct) { + sw = ECTesterApplet.SW_SIG_VERIFY_FAIL; + } + } catch (CardRuntimeException ce) { + sw = ce.getReason(); + } + return length; + } + public KeyAgreement getKA() { return ecKeyAgreement; } diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 18c4d1f..d0ca8f5 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -51,10 +51,11 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final byte INS_ECDH = (byte) 0x70; 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_ALLOCATE_KA = (byte) 0x75; - public static final byte INS_ALLOCATE_SIG = (byte) 0x76; + public static final byte INS_ECDSA_SIGN = (byte) 0x73; + public static final byte INS_ECDSA_VERIFY = (byte) 0x74; + public static final byte INS_CLEANUP = (byte) 0x75; + public static final byte INS_ALLOCATE_KA = (byte) 0x76; + public static final byte INS_ALLOCATE_SIG = (byte) 0x77; // PARAMETERS for P1 and P2 @@ -83,34 +84,12 @@ public class ECTesterApplet extends Applet implements ExtendedLength { public static final short SW_TransactionException_prefix = (short) 0xf400; public static final short SW_CardRuntimeException_prefix = (short) 0xf500; - - // Class javacard.security.KeyAgreement - // javacard.security.KeyAgreement Fields: - public static final byte KeyAgreement_ALG_EC_SVDP_DH = 1; - public static final byte KeyAgreement_ALG_EC_SVDP_DH_KDF = 1; - public static final byte KeyAgreement_ALG_EC_SVDP_DHC = 2; - public static final byte KeyAgreement_ALG_EC_SVDP_DHC_KDF = 2; - public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN = 3; - public static final byte KeyAgreement_ALG_EC_SVDP_DHC_PLAIN = 4; - public static final byte KeyAgreement_ALG_EC_PACE_GM = 5; - public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6; - - // 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; // TEMPORARRY ARRAY IN RAM private byte[] ramArray = null; private byte[] ramArray2 = null; private byte[] apduArray = null; - // PERSISTENT ARRAY IN EEPROM - private byte[] dataArray = null; // unused private RandomData randomData = null; @@ -135,9 +114,6 @@ public class ECTesterApplet extends Applet implements ExtendedLength { ramArray2 = JCSystem.makeTransientByteArray(ARRAY_LENGTH, JCSystem.CLEAR_ON_RESET); apduArray = JCSystem.makeTransientByteArray(APDU_MAX_LENGTH, JCSystem.CLEAR_ON_RESET); - dataArray = new byte[ARRAY_LENGTH]; - Util.arrayFillNonAtomic(dataArray, (short) 0, ARRAY_LENGTH, (byte) 0); - randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM); EC_Consts.randomData = randomData; @@ -203,6 +179,12 @@ public class ECTesterApplet extends Applet implements ExtendedLength { case INS_ECDSA: length = insECDSA(apdu); break; + case INS_ECDSA_SIGN: + length = insECDSA_sign(apdu); + break; + case INS_ECDSA_VERIFY: + length = insECDSA_verify(apdu); + break; case INS_CLEANUP: length = insCleanup(apdu); break; @@ -495,6 +477,57 @@ public class ECTesterApplet extends Applet implements ExtendedLength { } /** + * + * @param apdu P1 = byte keyPair (KEYPAIR_*) + * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE) + * DATA = byte sigType + * short dataLength (00 = random data generated, !00 = data length) + * byte[] data + * @return length of response + */ + private short insECDSA_sign(APDU apdu) { + 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_sign(localKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), (short) 0); + } + if ((keyPair & KEYPAIR_REMOTE) != 0) { + len += ecdsa_sign(remoteKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), len); + } + return len; + } + + /** + * + * @param apdu P1 = byte keyPair (KEYPAIR_*) + * P2 = byte sigType + * DATA = short dataLength (00 = random data generated, !00 = data length) + * byte[] data + * short sigLength + * byte[] signature + * @return length of response + */ + private short insECDSA_verify(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte sigType = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + + short len = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) { + len += ecdsa_verify(localKeypair, sigType, apduArray, cdata, apdu.getBuffer(), (short) 0); + } + if ((keyPair & KEYPAIR_REMOTE) != 0) { + len += ecdsa_verify(remoteKeypair, sigType, apduArray, cdata, apdu.getBuffer(), len); + } + return len; + } + + + /** * Performs card memory cleanup via JCSystem.requestObjectDeletion() * * @param apdu no data @@ -741,6 +774,63 @@ public class ECTesterApplet extends Applet implements ExtendedLength { return length; } + private short ecdsa_sign(KeyPair sign, byte sigType, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { + short length = 0; + + short dataLength = Util.getShort(inBuffer, inOffset); + if (dataLength == 0) { //no data to sign + //generate random + dataLength = 64; + randomData.generateData(ramArray, (short) 0, dataLength); + } else { + Util.arrayCopyNonAtomic(inBuffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength); + } + + short signatureLength = 0; + if (keyTester.getSigType() == sigType) { + signatureLength = keyTester.testECDSA_sign((ECPrivateKey) sign.getPrivate(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + } else { + short allocateSW = keyTester.allocateSig(sigType); + if (allocateSW == ISO7816.SW_NO_ERROR) { + signatureLength = keyTester.testECDSA_sign((ECPrivateKey) sign.getPrivate(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); + } + } + Util.setShort(outBuffer, outOffset, keyTester.getSW()); + length += 2; + + if (export == EXPORT_TRUE) { + Util.setShort(outBuffer, (short) (outOffset + length), signatureLength); + length += 2; + + Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), signatureLength); + length += signatureLength; + } + + return length; + } + + private short ecdsa_verify(KeyPair verify, byte sigType, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { + short length = 0; + + short dataLength = Util.getShort(inBuffer, inOffset); + short dataOffset = (short)(inOffset + 2); + short sigLength = Util.getShort(inBuffer, (short)(dataOffset + dataLength)); + short sigOffset = (short)(dataOffset + dataLength + 2); + + if (keyTester.getSigType() == sigType) { + keyTester.testECDSA_verify((ECPublicKey) verify.getPublic(), inBuffer, dataOffset, dataLength, inBuffer, sigOffset, sigLength); + } else { + short allocateSW = keyTester.allocateSig(sigType); + if (allocateSW == ISO7816.SW_NO_ERROR) { + keyTester.testECDSA_verify((ECPublicKey) verify.getPublic(), inBuffer, dataOffset, dataLength, inBuffer, sigOffset, sigLength); + } + } + Util.setShort(outBuffer, outOffset, keyTester.getSW()); + length += 2; + + return length; + } + /** * @param buffer buffer to write sw to * @param offset output offset in buffer diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 5b3c74c..88a8bd6 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -12,6 +12,8 @@ import javacard.security.RandomData; */ public class EC_Consts { + public static final byte KeyAgreement_ALG_EC_SVDP_DH_KDF = 1; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC_KDF = 2; private static byte[] EC_FP_P = null; //p private static byte[] EC_A = null; //a private static byte[] EC_B = null; //b @@ -1026,23 +1028,40 @@ public class EC_Consts { public static final short[] FP_SIZES = new short[]{112, 128, 160, 192, 224, 256, 384, 521}; public static final short[] F2M_SIZES = new short[]{163, 233, 283, 409, 571}; + // Class javacard.security.KeyAgreement + // javacard.security.KeyAgreement Fields: + public static final byte KeyAgreement_ALG_EC_SVDP_DH = 1; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC = 2; + public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN = 3; + public static final byte KeyAgreement_ALG_EC_SVDP_DHC_PLAIN = 4; + public static final byte KeyAgreement_ALG_EC_PACE_GM = 5; + public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = 6; + public static final byte[] KA_TYPES = new byte[]{ - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, - //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_KDF, //duplicate - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC, - //ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_KDF, //duplicate - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN, - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN, - ECTesterApplet.KeyAgreement_ALG_EC_PACE_GM, - ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY + KeyAgreement_ALG_EC_SVDP_DH, + //KeyAgreement_ALG_EC_SVDP_DH_KDF, //duplicate + KeyAgreement_ALG_EC_SVDP_DHC, + //KeyAgreement_ALG_EC_SVDP_DHC_KDF, //duplicate + KeyAgreement_ALG_EC_SVDP_DH_PLAIN, + KeyAgreement_ALG_EC_SVDP_DHC_PLAIN, + KeyAgreement_ALG_EC_PACE_GM, + KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY }; + // 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_224 = 37; + 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_512 = 38; + public static final byte[] SIG_TYPES = new byte[]{ - ECTesterApplet.Signature_ALG_ECDSA_SHA, - ECTesterApplet.Signature_ALG_ECDSA_SHA_224, - ECTesterApplet.Signature_ALG_ECDSA_SHA_256, - ECTesterApplet.Signature_ALG_ECDSA_SHA_384, - ECTesterApplet.Signature_ALG_ECDSA_SHA_512 + Signature_ALG_ECDSA_SHA, + Signature_ALG_ECDSA_SHA_224, + Signature_ALG_ECDSA_SHA_256, + Signature_ALG_ECDSA_SHA_384, + Signature_ALG_ECDSA_SHA_512 }; public static byte getCurve(short keyLength, byte keyClass) { diff --git a/src/cz/crcs/ectester/common/util/CardUtil.java b/src/cz/crcs/ectester/common/util/CardUtil.java index 3df5829..2501e47 100644 --- a/src/cz/crcs/ectester/common/util/CardUtil.java +++ b/src/cz/crcs/ectester/common/util/CardUtil.java @@ -6,8 +6,6 @@ import javacard.framework.ISO7816; import javacard.security.CryptoException; import javacard.security.KeyPair; -import static cz.crcs.ectester.applet.ECTesterApplet.*; - /** * @author Petr Svenda petr@svenda.com * @author Jan Jancar johny@neuromancer.sk @@ -17,12 +15,12 @@ public class CardUtil { switch (name) { case "DH": case "ECDH": - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; case "DHC": case "ECDHC": - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DHC; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC; default: - return ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; } } @@ -208,17 +206,17 @@ public class CardUtil { public static String getKATypeString(byte kaType) { switch (kaType) { - case KeyAgreement_ALG_EC_SVDP_DH: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH: return "ALG_EC_SVDP_DH"; - case KeyAgreement_ALG_EC_SVDP_DH_PLAIN: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN: return "ALG_EC_SVDP_DH_PLAIN"; - case KeyAgreement_ALG_EC_PACE_GM: + case EC_Consts.KeyAgreement_ALG_EC_PACE_GM: return "ALG_EC_PACE_GM"; - case KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY: return "ALG_EC_SVDP_DH_PLAIN_XY"; - case KeyAgreement_ALG_EC_SVDP_DHC: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC: return "ALG_EC_SVDP_DHC"; - case KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: + case EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN: return "ALG_EC_SVDP_DHC_PLAIN"; default: return "unknown"; @@ -228,17 +226,17 @@ public class CardUtil { public static byte getKAType(String kaTypeString) { switch (kaTypeString) { case "ALG_EC_SVDP_DH": - return KeyAgreement_ALG_EC_SVDP_DH; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; case "ALG_EC_SVDP_DH_PLAIN": - return KeyAgreement_ALG_EC_SVDP_DH_PLAIN; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN; case "ALG_EC_PACE_GM": - return KeyAgreement_ALG_EC_PACE_GM; + return EC_Consts.KeyAgreement_ALG_EC_PACE_GM; case "ALG_EC_SVDP_DH_PLAIN_XY": - return KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY; case "ALG_EC_SVDP_DHC": - return KeyAgreement_ALG_EC_SVDP_DHC; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC; case "ALG_EC_SVDP_DHC_PLAIN": - return KeyAgreement_ALG_EC_SVDP_DHC_PLAIN; + return EC_Consts.KeyAgreement_ALG_EC_SVDP_DHC_PLAIN; default: return 0; } @@ -256,15 +254,15 @@ public class CardUtil { public static String getSigTypeString(byte sigType) { switch (sigType) { - case Signature_ALG_ECDSA_SHA: + case EC_Consts.Signature_ALG_ECDSA_SHA: return "ALG_ECDSA_SHA"; - case Signature_ALG_ECDSA_SHA_224: + case EC_Consts.Signature_ALG_ECDSA_SHA_224: return "ALG_ECDSA_SHA_224"; - case Signature_ALG_ECDSA_SHA_256: + case EC_Consts.Signature_ALG_ECDSA_SHA_256: return "ALG_ECDSA_SHA_256"; - case Signature_ALG_ECDSA_SHA_384: + case EC_Consts.Signature_ALG_ECDSA_SHA_384: return "ALG_ECDSA_SHA_384"; - case Signature_ALG_ECDSA_SHA_512: + case EC_Consts.Signature_ALG_ECDSA_SHA_512: return "ALG_ECDSA_SHA_512"; default: return "unknown"; @@ -274,15 +272,15 @@ public class CardUtil { public static byte getSigType(String sigTypeString) { switch (sigTypeString) { case "ALG_ECDSA_SHA": - return Signature_ALG_ECDSA_SHA; + return EC_Consts.Signature_ALG_ECDSA_SHA; case "ALG_ECDSA_SHA_224": - return Signature_ALG_ECDSA_SHA_224; + return EC_Consts.Signature_ALG_ECDSA_SHA_224; case "ALG_ECDSA_SHA_256": - return Signature_ALG_ECDSA_SHA_256; + return EC_Consts.Signature_ALG_ECDSA_SHA_256; case "ALG_ECDSA_SHA_384": - return Signature_ALG_ECDSA_SHA_384; + return EC_Consts.Signature_ALG_ECDSA_SHA_384; case "ALG_ECDSA_SHA_512": - return Signature_ALG_ECDSA_SHA_512; + return EC_Consts.Signature_ALG_ECDSA_SHA_512; default: return 0; } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index dfd71db..84c0439 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -49,8 +49,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Scanner; -import static cz.crcs.ectester.applet.ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH; -import static cz.crcs.ectester.applet.ECTesterApplet.Signature_ALG_ECDSA_SHA; +import static cz.crcs.ectester.applet.EC_Consts.KeyAgreement_ALG_EC_SVDP_DH; +import static cz.crcs.ectester.applet.EC_Consts.Signature_ALG_ECDSA_SHA; /** * Reader part of ECTester, a tool for testing Elliptic curve support on javacards. diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 25b41dd..d0eaf45 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -685,6 +685,10 @@ public abstract class Command { */ public ECDSA(CardMngr cardManager, byte keyPair, byte sigType, byte export, byte[] raw) { super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + this.keyPair = keyPair; this.sigType = sigType; this.export = export; @@ -718,6 +722,115 @@ public abstract class Command { } } + public static class ECDSA_sign extends Command { + private byte keyPair; + private byte sigType; + private byte export; + private byte[] raw; + + /** + * Creates the INS_ECDSA_SIGN instruction. + * + * @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_sign(CardMngr cardManager, byte keyPair, byte sigType, byte export, byte[] raw) { + super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + + this.keyPair = keyPair; + this.sigType = sigType; + this.export = export; + this.raw = raw; + + int len = raw != null ? raw.length : 0; + byte[] data = new byte[3 + len]; + data[0] = sigType; + ByteUtil.setShort(data, 1, (short) len); + if (raw != null) { + System.arraycopy(raw, 0, data, 3, len); + } + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA_SIGN, keyPair, export, data); + } + + @Override + public Response.ECDSA send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDSA(response, getDescription(), elapsed, keyPair, sigType, export, raw); + } + + @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("%s signature with %s keypair(%s data)", algo, key, data); + } + } + + public static class ECDSA_verify extends Command { + private byte keyPair; + private byte sigType; + private byte[] raw; + private byte[] signature; + + /** + * Creates the INS_ECDSA_VERIFY instruction. + * + * @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 raw data to sign + * @param signature signature data + */ + public ECDSA_verify(CardMngr cardManager, byte keyPair, byte sigType, byte[] raw, byte[] signature) { + super(cardManager); + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + throw new IllegalArgumentException(); + } + if (raw == null || signature == null) { + throw new IllegalArgumentException(); + } + + this.keyPair = keyPair; + this.sigType = sigType; + this.raw = raw; + this.signature = signature; + + byte[] data = new byte[4 + raw.length + signature.length]; + ByteUtil.setShort(data, 0, (short) raw.length); + System.arraycopy(raw, 0, data, 2, raw.length); + ByteUtil.setShort(data, 2 + raw.length, (short) signature.length); + System.arraycopy(signature, 0, data, 2 + raw.length + 2, signature.length); + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA_SIGN, keyPair, sigType, data); + } + + @Override + public Response.ECDSA send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDSA(response, getDescription(), elapsed, keyPair, sigType, ECTesterApplet.EXPORT_FALSE, raw); + } + + @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("%s verification with %s keypair(%s data)", algo, key, data); + } + } + /** * */ diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java index a0b71a7..1ca05d4 100644 --- a/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCofactorTestSuite.java @@ -48,7 +48,7 @@ public class CardCofactorTestSuite extends CardTestSuite { List<Test> ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on non-generator subgroup.", "Card incorrectly accepted point on non-generator subgroup.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on non-generator subgroup", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java index f0eaa87..95204dd 100644 --- a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -39,7 +39,7 @@ public class CardCompositeCurvesSuite extends CardTestSuite { Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS); Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY); Test generate = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY); - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, key.flatten()); Test ecdh = 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."); doTest(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", " + key.getDesc(), allocate, set, generate, ecdh)); diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java index fab7786..d3c5f99 100644 --- a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -53,7 +53,7 @@ public class CardInvalidCurvesSuite extends CardTestSuite { List<Test> ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.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.")); } Test ecdh = CompoundTest.all(ExpectedValue.SUCCESS, "Perform ECDH with invalid public points", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java index 4b90694..c80db0d 100644 --- a/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTwistTestSuite.java @@ -48,7 +48,7 @@ public class CardTwistTestSuite extends CardTestSuite { List<Test> ecdhTests = new LinkedList<>(); for (EC_Key.Public pub : keys) { - Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); + Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pub.flatten()); ecdhTests.add(CommandTest.expect(ecdhCommand, Result.ExpectedValue.FAILURE, "Card correctly rejected point on twist.", "Card incorrectly accepted point on twist.")); } Test ecdh = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH with public points on twist", ecdhTests.toArray(new Test[0])); diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java index 5d58be1..429b047 100644 --- a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -146,8 +146,8 @@ public class CardWrongCurvesSuite extends CardTestSuite { Test setup = runTest(CommandTest.expect(setupCmd, Result.ExpectedValue.FAILURE)); Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), Result.ExpectedValue.FAILURE)); Test preparePhase = runTest(CompoundTest.any(Result.ExpectedValue.SUCCESS, prepareDesc, setup, generate)); - Test allocateECDH = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.SUCCESS)); - Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, ECTesterApplet.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); + Test allocateECDH = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.SUCCESS)); + Test ecdh = runTest(CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), Result.ExpectedValue.FAILURE)); return runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, fullDesc, preparePhase, allocateECDH, ecdh)); } } |
