since I started working with Java Cards, I got a lot of valuable information from the discussions in this forum here. After a few weeks of playing around with some code in a simulator and in one of my last steps before finishing up the project, I'm now stuck since a few days. In this situation, I hope for some suggestions on how to proceed with debugging some annoying error.
I'm trying to calculate a signature based on the NIST P-192 curve. This works pretty well but now I'm trying to validate the signature. And when I try to init the ecdsa object for the purpose of verification, I'm getting an error (ILLEGAL_VALUE). The interesting aspect is that initialization works fine for the purpose of creating a signature and that the error only occurs in MODE_VERIFY. My best guess is that is has something to do with the public key but I cannot find any reason....
I copied the relevant parts of my code below. I hope that this is enough code to get an actual overview.
Any suggestions/ideas would be highly appreciated.
Thanks
- N
Code: Select all
private void ecc_verify(APDU apdu) {
byte[] buffer = apdu.getBuffer();
GenEccKeyPair();
short lenOfMessage = (short)(LEN_OF_MESSAGE - SIGNATURE_LEN);
ECPublicKey testkey = (ECPublicKey)eccKey.getPublic();
try {
//This is where the error is thrown. Error is 01, ILLEGAL_VALUE
ecdsa.init(eccKey.getPublic(), Signature.MODE_VERIFY);
}
catch (CryptoException e) {
short reason = e.getReason();
ISOException.throwIt((short) ((short) 0x6B00 | reason));
}
//Verify the signature of input data against the passed in ECC signature.
boolean ret = ecdsa.verify(buffer, (short)ISO7816.OFFSET_CDATA, lenOfMessage, buffer, (short)(ISO7816.OFFSET_CDATA + lenOfMessage), (short)SIGNATURE_LEN);
buffer[(short)0] = ret ? (byte)1 : (byte)0;
apdu.setOutgoingAndSend((short)0, (short)1);
}
private void GenEccKeyPair() {
byte[] tempBuffer = JCSystem.makeTransientByteArray((short)256, JCSystem.CLEAR_ON_DESELECT);
if (eccKeyInitialized)
return;
//Create a ECC(ALG_ECDSA_SHA) object instance
ecdsa = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
//Constructs a KeyPair instance for the specified algorithm and keylength;
eccKey = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192);
// prepare an ANSI X9.62 uncompressed EC point representation for G
byte[] auxBuffer = JCSystem.makeTransientByteArray(((short)(EC192_FP_G_X.length + EC192_FP_G_Y.length + 1)), JCSystem.CLEAR_ON_DESELECT);
short gSize = (short) 1;
gSize += (short) EC192_FP_G_X.length;
gSize += (short) EC192_FP_G_Y.length;
auxBuffer[0] = 0x04;
short off = 1;
off = Util.arrayCopyNonAtomic(EC192_FP_G_X, (short) 0, auxBuffer, off, (short) EC192_FP_G_X.length);
Util.arrayCopyNonAtomic(EC192_FP_G_Y, (short) 0, auxBuffer, off, (short) EC192_FP_G_Y.length);
((ECPrivateKey)eccKey.getPrivate()).setFieldFP(EC192_FP_P, (short)0, (short)EC192_FP_P.length);
((ECPrivateKey)eccKey.getPrivate()).setA(EC192_FP_A, (short)0, (short)EC192_FP_A.length);
((ECPrivateKey)eccKey.getPrivate()).setB(EC192_FP_B, (short)0, (short)EC192_FP_B.length);
((ECPrivateKey)eccKey.getPrivate()).setG(auxBuffer, (short)0, gSize);
((ECPrivateKey)eccKey.getPrivate()).setR(EC192_FP_R, (short)0, (short)EC192_FP_R.length);
((ECPublicKey)eccKey.getPublic()).setFieldFP(EC192_FP_P, (short)0, (short)EC192_FP_P.length);
((ECPublicKey)eccKey.getPublic()).setA(EC192_FP_A, (short)0, (short)EC192_FP_A.length);
((ECPublicKey)eccKey.getPublic()).setB(EC192_FP_B, (short)0, (short)EC192_FP_B.length);
((ECPublicKey)eccKey.getPublic()).setG(auxBuffer, (short)0, gSize);
((ECPublicKey)eccKey.getPublic()).setR(EC192_FP_R, (short)0, (short)EC192_FP_R.length);
eccKey.genKeyPair();
eccKeyInitialized = true;
}
private byte[] ecc_sign(byte[] dtbs) {
GenEccKeyPair();
byte[] signature;
signature = JCSystem.makeTransientByteArray((short)SIGNATURE_LEN, JCSystem.CLEAR_ON_DESELECT);
ecdsa.init(eccKey.getPrivate(), Signature.MODE_SIGN);
short lenTmp = ecdsa.sign(dtbs, (short)0, (short)dtbs.length, signature, (short)0);
return signature;
}