Skip to Main Content

Java Card

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Bugs with EC KeyPair with Oracle javacard simulator

OlivierMartin5 days ago — edited 5 days ago

I am using latest Oracle javacard simulator: https://docs.oracle.com/en/java/javacard/3.2 - And my applet build also target `3.2`.

I tested all my code started from the `HelloWorld` sample.

Bug 1: First bug is related to retrieving EC Public Key

To duplicate the bug, I generate a EC key pair and try to retrieve the public key representation using ECPublicKey.getW().

First test:

// Create ECC key pair (P-256 / secp256r1)
KeyPair eccKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256);
eccKeyPair.genKeyPair();
ECPublicKey eccPublicKey = (ECPublicKey)eccKeyPair.getPublic();
short wLength = eccPublicKey.getW(buffer, (short)2);
	
apdu.setOutgoing();
apdu.setOutgoingLength((short)(2 + wLength));
buffer[0] = (byte)((wLength >> 8) & 0xFF);
buffer[1] = (byte)(wLength & 0xFF);
        
apdu.sendBytes((short) 0, (short)(2 + wLength));

I received `00210424603E79077F33047A46079DABB6155E0F9A46B70D570E52B61831AFB9AAAAF4`. So the public key is 33 bytes long.
So 33 bytes long is valid for a compressed EC Public key. But the first byte should either be `02` or `03` - not 04. `04` is for uncompressed key and it should be 65-byte long.

I have read in different places that the EC Private and Public keys must have their parameters set before calling genKeyPair. So I tried:

ECPrivateKey eccPrivateKey = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, KeyBuilder.LENGTH_EC_FP_256, false /* keyEncryption */);
setCurveParameters(eccPrivateKey); // Set SecP256r1 parameters
ECPublicKey eccPublicKey = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_256, false /* keyEncryption */);
setCurveParameters(eccPublicKey); // Set SecP256r1 parameters
KeyPair eccKeyPair = new KeyPair(eccPublicKey, eccPrivateKey);
eccKeyPair.genKeyPair();
short wLength = eccPublicKey.getW(buffer, (short)2);

And similar result: `002104B792239DBD35FC129592F258E8231232B30D2FA8907E984788290BC0B7100049`

Bug 2: EC Public key not correctly initialized by javacard simulator

So I was assuming the bug 1 could be ignored and I could overwrite the 04 by 02 - even if it is risky (it could also be 03).

And I wanted to check ECDSA signature and its verification:

	try {
		ECPrivateKey eccPrivateKey = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, KeyBuilder.LENGTH_EC_FP_256, false /* keyEncryption */);
		setCurveParameters(eccPrivateKey);
		ECPublicKey eccPublicKey = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_256, false /* keyEncryption */);
		setCurveParameters(eccPublicKey);
		KeyPair eccKeyPair = new KeyPair(eccPublicKey, eccPrivateKey);
		eccKeyPair.genKeyPair();
		
		byte[] messageBytes = new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B};
		
		Signature eccSignature = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false);
		eccSignature.init(eccPrivateKey, Signature.MODE_SIGN);
		short signatureLength = eccSignature.sign(
		        messageBytes, (short)0, (short)messageBytes.length,  // input
		        buffer, (short)0           // output (reuse buffer)
		    );

		Signature eccVerificationSignature = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false);
		eccVerificationSignature.init(eccPublicKey, Signature.MODE_VERIFY); // <<<<<< CryptoException here: 'javacard.security.CryptoException (reason=0x0001)' - EC_POINT not created: error:08000066:elliptic curve routines::invalid encoding

		apdu.setOutgoing();
		apdu.setOutgoingLength(signatureLength);
		apdu.sendBytes((short) 0, signatureLength);
	} catch (CryptoException e) {
	    ISOException.throwIt((short)0x6F01);
	}

My code actually throws an exception when calling `eccSignature.init(eccPublicKey, Signature.MODE_VERIFY);`

The exception is javacard.security.CryptoException (reason=0x0001)

Here are the logs from Oracle Javacard simulator for this sample:

SEVERE |msg|000598|grp:hal | EC_POINT not created: error:08000066:elliptic curve routines::invalid encoding
WARNING|msg|000599|grp:jcre| Exception:
WARNING|msg|000599|grp:jcre| javacard.security.CryptoException (reason=0x0001)
WARNING|msg|000599|grp:jcre|     at javacard.security.CryptoException.throwIt_S (pc=@0x63c02b92)
WARNING|msg|000599|grp:jcre|     at javacard.security.<anonymous> (pc=@0x63c035ee)
WARNING|msg|000599|grp:jcre|     at <unknown> (pc=@0x63c2b09b)
WARNING|msg|000599|grp:jcre|     at <unknown> (pc=@(nil))
WARNING|msg|000600|grp:jcre| Exception:
WARNING|msg|000600|grp:jcre| javacard.framework.ISOException (reason=0x6F01)
WARNING|msg|000600|grp:jcre|     at javacard.framework.ISOException.throwIt_S (pc=@0x63c00e5e)
WARNING|msg|000600|grp:jcre|     at <unknown> (pc=@0x63c2b0b7)
WARNING|msg|000600|grp:jcre|     at <unknown> (pc=@(nil))
Comments
Post Details
Added 5 days ago
1 comment
79 views