diff options
Diffstat (limited to 'src/cz/crcs/ectester/applet')
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyTester.java | 50 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECTesterApplet.java | 148 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/EC_Consts.java | 45 |
3 files changed, 201 insertions, 42 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) { |
