From bb9f146b4f5ea4cf471be2f40ca5c8b860ccf288 Mon Sep 17 00:00:00 2001 From: Subrahmanyaman Date: Fri, 23 Sep 2022 15:23:15 +0000 Subject: [PATCH 1/5] Replaced AdditionalCertChain from CoseSign1 to X.509 --- .../javacard/keymaster/KMAndroidSEApplet.java | 59 ++-- .../javacard/keymaster/KMJCardSimApplet.java | 59 ++-- .../android/javacard/test/KMProvision.java | 308 ++++++++++++++---- .../android/javacard/test/KMTestUtils.java | 131 ++++---- .../android/javacard/keymaster/KMDecoder.java | 9 +- .../keymaster/KMKeymintDataStore.java | 10 +- .../RemotelyProvisionedComponentDevice.java | 28 +- ProvisioningTool/sample_json_keymint_cf.txt | 5 +- ProvisioningTool/sample_json_keymint_gf.txt | 5 +- ProvisioningTool/src/construct_apdus.cpp | 104 ++---- 10 files changed, 424 insertions(+), 294 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index c6ccddbc..647cb93d 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -387,18 +387,28 @@ private static void processProvisionRkpDeviceUniqueKeyPair(APDU apdu) { sendResponse(apdu, KMError.OK); } - private static void processProvisionRkpAdditionalCertChain(APDU apdu) { - // Prepare the expression to decode - short headers = KMCoseHeaders.exp(); - short arrInst = KMArray.instance((short) 4); - KMArray.cast(arrInst).add((short) 0, KMByteBlob.exp()); - KMArray.cast(arrInst).add((short) 1, headers); - KMArray.cast(arrInst).add((short) 2, KMByteBlob.exp()); - KMArray.cast(arrInst).add((short) 3, KMByteBlob.exp()); - short coseSignArr = KMArray.exp(arrInst); - short map = KMMap.instance((short) 1); - KMMap.cast(map).add((short) 0, KMTextString.exp(), coseSignArr); - // receive incoming data and decode it. + private void processProvisionRkpAdditionalCertChain(APDU apdu) { + // X509 certificate chain is received as shown below: + /** + * x509CertChain = bstr .cbor UdsCerts + * + * AdditionalDKSignatures = { + * * SignerName => DKCertChain + * } + * ; SignerName is a string identifier that indicates both the signing authority as + * ; well as the format of the DKCertChain + * SignerName = tstr + * + * DKCertChain = [ + * 2* X509Certificate ; Root -> ... -> Leaf. "Root" is the vendor self-signed + * ; cert, "Leaf" contains DK_pub. There may also be + * ; intermediate certificates between Root and Leaf. + * ] + * ; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or edDSA) + * X509Certificate = bstr + */ + // Store the cbor encoded UdsCerts as it is in the persistent memory so cbor decoding is + // required here. byte[] srcBuffer = apdu.getBuffer(); short recvLen = apdu.setIncomingAndReceive(); short srcOffset = apdu.getOffsetCdata(); @@ -411,27 +421,12 @@ private static void processProvisionRkpAdditionalCertChain(APDU apdu) { index += recvLen; recvLen = apdu.receiveBytes(srcOffset); } - // decode - map = decoder.decode(map, buffer, bufferStartOffset, bufferLength); - arrInst = KMMap.cast(map).getKeyValue((short) 0); - // Validate Additional certificate chain. - short leafCoseKey = - validateCertChain(false, KMCose.COSE_ALG_ES256, KMCose.COSE_ALG_ES256, arrInst, - srcBuffer, null); - // Compare the DK_Pub. - short pubKeyLen = KMCoseKey.cast(leafCoseKey).getEcdsa256PublicKey(srcBuffer, (short) 0); - KMDeviceUniqueKeyPair uniqueKey = kmDataStore.getRkpDeviceUniqueKeyPair(false); - if (uniqueKey == null) { - KMException.throwIt(KMError.STATUS_FAILED); - } - short uniqueKeyLen = uniqueKey.getPublicKey(srcBuffer, pubKeyLen); - if ((pubKeyLen != uniqueKeyLen) || - (0 != Util.arrayCompare(srcBuffer, (short) 0, srcBuffer, pubKeyLen, pubKeyLen))) { - KMException.throwIt(KMError.STATUS_FAILED); - } - kmDataStore.persistAdditionalCertChain(buffer, bufferStartOffset, bufferLength); + short byteHeaderLen = decoder.readCertificateChainHeaderLen(buffer, bufferStartOffset, + bufferLength); + kmDataStore.persistAdditionalCertChain(buffer, (short) (bufferStartOffset + byteHeaderLen), + (short) (bufferLength - byteHeaderLen)); kmDataStore.setProvisionStatus(PROVISION_STATUS_ADDITIONAL_CERT_CHAIN); - //reclaim memory + // reclaim memory repository.reclaimMemory(bufferLength); sendResponse(apdu, KMError.OK); } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java index fc9db86e..58c5dc45 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java @@ -380,18 +380,28 @@ private static void processProvisionRkpDeviceUniqueKeyPair(APDU apdu) { sendResponse(apdu, KMError.OK); } - private static void processProvisionRkpAdditionalCertChain(APDU apdu) { - // Prepare the expression to decode - short headers = KMCoseHeaders.exp(); - short arrInst = KMArray.instance((short) 4); - KMArray.cast(arrInst).add((short) 0, KMByteBlob.exp()); - KMArray.cast(arrInst).add((short) 1, headers); - KMArray.cast(arrInst).add((short) 2, KMByteBlob.exp()); - KMArray.cast(arrInst).add((short) 3, KMByteBlob.exp()); - short coseSignArr = KMArray.exp(arrInst); - short map = KMMap.instance((short) 1); - KMMap.cast(map).add((short) 0, KMTextString.exp(), coseSignArr); - // receive incoming data and decode it. + private void processProvisionRkpAdditionalCertChain(APDU apdu) { + // X509 certificate chain is received as shown below: + /** + * x509CertChain = bstr .cbor UdsCerts + * + * UdsCerts = { + * * SignerName => UdsCertChain + * } + * ; SignerName is a string identifier that indicates both the signing authority as + * ; well as the format of the UdsCertChain + * SignerName = tstr + * + * UdsCertChain = [ + * 2* X509Certificate ; Root -> ... -> Leaf. "Root" is the vendor self-signed + * ; cert, "Leaf" contains UDS_Public. There may also be + * ; intermediate certificates between Root and Leaf. + * ] + * ; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or edDSA) + * X509Certificate = bstr + */ + // Store the cbor encoded UdsCerts as it is in the persistent memory so cbor decoding is + // required here. byte[] srcBuffer = apdu.getBuffer(); short recvLen = apdu.setIncomingAndReceive(); short srcOffset = apdu.getOffsetCdata(); @@ -404,27 +414,12 @@ private static void processProvisionRkpAdditionalCertChain(APDU apdu) { index += recvLen; recvLen = apdu.receiveBytes(srcOffset); } - // decode - map = decoder.decode(map, buffer, bufferStartOffset, bufferLength); - arrInst = KMMap.cast(map).getKeyValue((short) 0); - // Validate Additional certificate chain. - short leafCoseKey = - validateCertChain(false, KMCose.COSE_ALG_ES256, KMCose.COSE_ALG_ES256, arrInst, - srcBuffer, null); - // Compare the DK_Pub. - short pubKeyLen = KMCoseKey.cast(leafCoseKey).getEcdsa256PublicKey(srcBuffer, (short) 0); - KMDeviceUniqueKeyPair uniqueKey = kmDataStore.getRkpDeviceUniqueKeyPair(false); - if (uniqueKey == null) { - KMException.throwIt(KMError.STATUS_FAILED); - } - short uniqueKeyLen = uniqueKey.getPublicKey(srcBuffer, pubKeyLen); - if ((pubKeyLen != uniqueKeyLen) || - (0 != Util.arrayCompare(srcBuffer, (short) 0, srcBuffer, pubKeyLen, pubKeyLen))) { - KMException.throwIt(KMError.STATUS_FAILED); - } - kmDataStore.persistAdditionalCertChain(buffer, bufferStartOffset, bufferLength); + short byteHeaderLen = decoder.readCertificateChainHeaderLen(buffer, bufferStartOffset, + bufferLength); + kmDataStore.persistAdditionalCertChain(buffer, (short) (bufferStartOffset + byteHeaderLen), + (short) (bufferLength - byteHeaderLen)); kmDataStore.setProvisionStatus(PROVISION_STATUS_ADDITIONAL_CERT_CHAIN); - //reclaim memory + // reclaim memory repository.reclaimMemory(bufferLength); sendResponse(apdu, KMError.OK); } diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java index c86bb23f..f6305d12 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java @@ -93,6 +93,238 @@ public class KMProvision { (byte) 0xa6, (byte) 0x71, (byte) 0x58, (byte) 0x3e, (byte) 0xdb, (byte) 0x3e, (byte) 0x11, (byte) 0xae, (byte) 0x10, (byte) 0x14}; + private static final byte[] kEcAttestRootCert = { + (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xad, (byte) 0x30, (byte) 0x82, (byte) 0x02, + (byte) 0x53, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x02, + (byte) 0x14, (byte) 0x77, (byte) 0x76, (byte) 0x38, (byte) 0x73, (byte) 0x7f, (byte) 0x38, + (byte) 0xe6, (byte) 0x9e, (byte) 0xd9, (byte) 0x75, (byte) 0x5e, (byte) 0x67, (byte) 0xab, + (byte) 0x0f, (byte) 0x0e, (byte) 0x3d, (byte) 0xe3, (byte) 0xb4, (byte) 0x94, (byte) 0xb3, + (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, + (byte) 0xce, (byte) 0x3d, (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x30, (byte) 0x81, + (byte) 0xa3, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, + (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, + (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, (byte) 0x69, (byte) 0x61, + (byte) 0x31, (byte) 0x14, (byte) 0x30, (byte) 0x12, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0b, (byte) 0x53, (byte) 0x61, (byte) 0x6e, + (byte) 0x66, (byte) 0x72, (byte) 0x61, (byte) 0x6e, (byte) 0x73, (byte) 0x69, (byte) 0x63, + (byte) 0x6f, (byte) 0x31, (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, (byte) 0x47, (byte) 0x6f, + (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x31, (byte) 0x19, (byte) 0x30, + (byte) 0x17, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, + (byte) 0x10, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, + (byte) 0x64, (byte) 0x20, (byte) 0x53, (byte) 0x65, (byte) 0x63, (byte) 0x75, (byte) 0x72, + (byte) 0x69, (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x1c, (byte) 0x30, (byte) 0x1a, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x13, + (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x20, + (byte) 0x63, (byte) 0x61, (byte) 0x20, (byte) 0x73, (byte) 0x74, (byte) 0x72, (byte) 0x6f, + (byte) 0x6e, (byte) 0x67, (byte) 0x62, (byte) 0x6f, (byte) 0x78, (byte) 0x31, (byte) 0x1f, + (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, + (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x16, + (byte) 0x10, (byte) 0x73, (byte) 0x68, (byte) 0x61, (byte) 0x77, (byte) 0x6e, (byte) 0x40, + (byte) 0x67, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, + (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, + (byte) 0x32, (byte) 0x31, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x38, (byte) 0x30, + (byte) 0x36, (byte) 0x35, (byte) 0x37, (byte) 0x33, (byte) 0x38, (byte) 0x5a, (byte) 0x17, + (byte) 0x0d, (byte) 0x34, (byte) 0x31, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33, + (byte) 0x30, (byte) 0x36, (byte) 0x35, (byte) 0x37, (byte) 0x33, (byte) 0x38, (byte) 0x5a, + (byte) 0x30, (byte) 0x81, (byte) 0xa3, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, + (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x43, + (byte) 0x61, (byte) 0x6c, (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, + (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x14, (byte) 0x30, (byte) 0x12, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0b, (byte) 0x53, + (byte) 0x61, (byte) 0x6e, (byte) 0x66, (byte) 0x72, (byte) 0x61, (byte) 0x6e, (byte) 0x73, + (byte) 0x69, (byte) 0x63, (byte) 0x6f, (byte) 0x31, (byte) 0x0f, (byte) 0x30, (byte) 0x0d, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, + (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x31, + (byte) 0x19, (byte) 0x30, (byte) 0x17, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0b, (byte) 0x0c, (byte) 0x10, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, + (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x53, (byte) 0x65, (byte) 0x63, + (byte) 0x75, (byte) 0x72, (byte) 0x69, (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x1c, + (byte) 0x30, (byte) 0x1a, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, + (byte) 0x0c, (byte) 0x13, (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, + (byte) 0x65, (byte) 0x20, (byte) 0x63, (byte) 0x61, (byte) 0x20, (byte) 0x73, (byte) 0x74, + (byte) 0x72, (byte) 0x6f, (byte) 0x6e, (byte) 0x67, (byte) 0x62, (byte) 0x6f, (byte) 0x78, + (byte) 0x31, (byte) 0x1f, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, + (byte) 0x01, (byte) 0x16, (byte) 0x10, (byte) 0x73, (byte) 0x68, (byte) 0x61, (byte) 0x77, + (byte) 0x6e, (byte) 0x40, (byte) 0x67, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, + (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x59, + (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, + (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, + (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0x9c, (byte) 0xc8, (byte) 0x1a, + (byte) 0xcf, (byte) 0xc8, (byte) 0x8a, (byte) 0xb9, (byte) 0x2f, (byte) 0x1f, (byte) 0x87, + (byte) 0xb6, (byte) 0xb1, (byte) 0x34, (byte) 0x8e, (byte) 0x75, (byte) 0x38, (byte) 0x1d, + (byte) 0x3a, (byte) 0xed, (byte) 0xcd, (byte) 0xf0, (byte) 0x8f, (byte) 0x91, (byte) 0x55, + (byte) 0x0d, (byte) 0x1a, (byte) 0x6d, (byte) 0x6f, (byte) 0xf0, (byte) 0x70, (byte) 0x2d, + (byte) 0x55, (byte) 0x4a, (byte) 0x30, (byte) 0xb9, (byte) 0xbe, (byte) 0xab, (byte) 0x30, + (byte) 0xc7, (byte) 0xb3, (byte) 0xa2, (byte) 0x2d, (byte) 0xfc, (byte) 0xcc, (byte) 0x84, + (byte) 0x0a, (byte) 0xc9, (byte) 0xbf, (byte) 0xb9, (byte) 0x31, (byte) 0x5a, (byte) 0xb7, + (byte) 0x8c, (byte) 0xa0, (byte) 0x72, (byte) 0x21, (byte) 0xdd, (byte) 0x27, (byte) 0xac, + (byte) 0xfe, (byte) 0xcd, (byte) 0x34, (byte) 0x11, (byte) 0x82, (byte) 0xa3, (byte) 0x63, + (byte) 0x30, (byte) 0x61, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x81, + (byte) 0x6c, (byte) 0xe6, (byte) 0x5a, (byte) 0x30, (byte) 0xf8, (byte) 0xe2, (byte) 0xaf, + (byte) 0x7f, (byte) 0xef, (byte) 0x04, (byte) 0x23, (byte) 0x50, (byte) 0xdc, (byte) 0x4e, + (byte) 0xa4, (byte) 0x48, (byte) 0xe2, (byte) 0x05, (byte) 0x62, (byte) 0x30, (byte) 0x1f, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, + (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x81, (byte) 0x6c, (byte) 0xe6, + (byte) 0x5a, (byte) 0x30, (byte) 0xf8, (byte) 0xe2, (byte) 0xaf, (byte) 0x7f, (byte) 0xef, + (byte) 0x04, (byte) 0x23, (byte) 0x50, (byte) 0xdc, (byte) 0x4e, (byte) 0xa4, (byte) 0x48, + (byte) 0xe2, (byte) 0x05, (byte) 0x62, (byte) 0x30, (byte) 0x0f, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x04, + (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, + (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0f, (byte) 0x01, + (byte) 0x01, (byte) 0xff, (byte) 0x04, (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x01, + (byte) 0x86, (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x03, + (byte) 0x48, (byte) 0x00, (byte) 0x30, (byte) 0x45, (byte) 0x02, (byte) 0x21, (byte) 0x00, + (byte) 0xaf, (byte) 0x64, (byte) 0xe6, (byte) 0xa3, (byte) 0x6c, (byte) 0xae, (byte) 0xd3, + (byte) 0x38, (byte) 0x02, (byte) 0xa1, (byte) 0x1e, (byte) 0x0e, (byte) 0x98, (byte) 0xa1, + (byte) 0x91, (byte) 0xa8, (byte) 0x92, (byte) 0xe6, (byte) 0xf8, (byte) 0x79, (byte) 0x1a, + (byte) 0x9f, (byte) 0x83, (byte) 0xd1, (byte) 0xb3, (byte) 0x23, (byte) 0x74, (byte) 0xd3, + (byte) 0x3d, (byte) 0xb5, (byte) 0x4f, (byte) 0xc4, (byte) 0x02, (byte) 0x20, (byte) 0x74, + (byte) 0xba, (byte) 0xeb, (byte) 0x9d, (byte) 0x57, (byte) 0x35, (byte) 0x09, (byte) 0x80, + (byte) 0x20, (byte) 0x63, (byte) 0xb7, (byte) 0x0b, (byte) 0x15, (byte) 0xb6, (byte) 0xe5, + (byte) 0xc1, (byte) 0x72, (byte) 0xa6, (byte) 0x8a, (byte) 0x4e, (byte) 0x9e, (byte) 0x57, + (byte) 0x83, (byte) 0xd8, (byte) 0x63, (byte) 0xa7, (byte) 0x3c, (byte) 0x1a, (byte) 0x7d, + (byte) 0x20, (byte) 0x85, (byte) 0xc6 + }; + + + private static final byte[] kEcAttestCert = { + (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x94, (byte) 0x30, (byte) 0x82, (byte) 0x02, + (byte) 0x3b, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x02, + (byte) 0x02, (byte) 0x10, (byte) 0x00, (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, + (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, (byte) 0x03, + (byte) 0x02, (byte) 0x30, (byte) 0x81, (byte) 0xa3, (byte) 0x31, (byte) 0x0b, (byte) 0x30, + (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, + (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, + (byte) 0x43, (byte) 0x61, (byte) 0x6c, (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, + (byte) 0x6e, (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x14, (byte) 0x30, (byte) 0x12, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0b, + (byte) 0x53, (byte) 0x61, (byte) 0x6e, (byte) 0x66, (byte) 0x72, (byte) 0x61, (byte) 0x6e, + (byte) 0x73, (byte) 0x69, (byte) 0x63, (byte) 0x6f, (byte) 0x31, (byte) 0x0f, (byte) 0x30, + (byte) 0x0d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, + (byte) 0x06, (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, + (byte) 0x31, (byte) 0x19, (byte) 0x30, (byte) 0x17, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x10, (byte) 0x41, (byte) 0x6e, (byte) 0x64, + (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x53, (byte) 0x65, + (byte) 0x63, (byte) 0x75, (byte) 0x72, (byte) 0x69, (byte) 0x74, (byte) 0x79, (byte) 0x31, + (byte) 0x1c, (byte) 0x30, (byte) 0x1a, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x03, (byte) 0x0c, (byte) 0x13, (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, + (byte) 0x6c, (byte) 0x65, (byte) 0x20, (byte) 0x63, (byte) 0x61, (byte) 0x20, (byte) 0x73, + (byte) 0x74, (byte) 0x72, (byte) 0x6f, (byte) 0x6e, (byte) 0x67, (byte) 0x62, (byte) 0x6f, + (byte) 0x78, (byte) 0x31, (byte) 0x1f, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x09, + (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, + (byte) 0x09, (byte) 0x01, (byte) 0x16, (byte) 0x10, (byte) 0x73, (byte) 0x68, (byte) 0x61, + (byte) 0x77, (byte) 0x6e, (byte) 0x40, (byte) 0x67, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, + (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, + (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x31, (byte) 0x30, (byte) 0x31, + (byte) 0x32, (byte) 0x38, (byte) 0x30, (byte) 0x37, (byte) 0x31, (byte) 0x30, (byte) 0x30, + (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x33, (byte) 0x31, (byte) 0x30, + (byte) 0x31, (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x37, (byte) 0x31, (byte) 0x30, + (byte) 0x30, (byte) 0x39, (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0x9a, (byte) 0x31, + (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, + (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, + (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, (byte) 0x69, (byte) 0x66, + (byte) 0x6f, (byte) 0x72, (byte) 0x6e, (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x0f, + (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, + (byte) 0x0c, (byte) 0x06, (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, + (byte) 0x65, (byte) 0x31, (byte) 0x19, (byte) 0x30, (byte) 0x17, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x10, (byte) 0x41, (byte) 0x6e, + (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x53, + (byte) 0x65, (byte) 0x63, (byte) 0x75, (byte) 0x72, (byte) 0x69, (byte) 0x74, (byte) 0x79, + (byte) 0x31, (byte) 0x29, (byte) 0x30, (byte) 0x27, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x20, (byte) 0x47, (byte) 0x6f, (byte) 0x6f, + (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, + (byte) 0x65, (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, (byte) 0x69, (byte) 0x61, + (byte) 0x74, (byte) 0x65, (byte) 0x20, (byte) 0x43, (byte) 0x41, (byte) 0x20, (byte) 0x73, + (byte) 0x74, (byte) 0x72, (byte) 0x6f, (byte) 0x6e, (byte) 0x67, (byte) 0x62, (byte) 0x6f, + (byte) 0x78, (byte) 0x31, (byte) 0x1f, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x09, + (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, + (byte) 0x09, (byte) 0x01, (byte) 0x16, (byte) 0x10, (byte) 0x73, (byte) 0x68, (byte) 0x61, + (byte) 0x77, (byte) 0x6e, (byte) 0x40, (byte) 0x67, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, + (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, + (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, + (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, + (byte) 0x07, (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xfb, (byte) 0xc5, + (byte) 0x8d, (byte) 0x57, (byte) 0x3f, (byte) 0x53, (byte) 0x3e, (byte) 0x6e, (byte) 0x62, + (byte) 0x10, (byte) 0xd1, (byte) 0x66, (byte) 0x7a, (byte) 0x00, (byte) 0xf5, (byte) 0x8a, + (byte) 0xd9, (byte) 0xa8, (byte) 0x61, (byte) 0x8f, (byte) 0x99, (byte) 0xcf, (byte) 0xae, + (byte) 0x32, (byte) 0xf5, (byte) 0xb9, (byte) 0xab, (byte) 0xa4, (byte) 0x58, (byte) 0x1f, + (byte) 0xa9, (byte) 0x47, (byte) 0x01, (byte) 0x39, (byte) 0x5d, (byte) 0xf5, (byte) 0x18, + (byte) 0x82, (byte) 0x4e, (byte) 0x16, (byte) 0x44, (byte) 0x1a, (byte) 0xdf, (byte) 0xfc, + (byte) 0xf4, (byte) 0xa0, (byte) 0xbd, (byte) 0x93, (byte) 0x42, (byte) 0x4a, (byte) 0x92, + (byte) 0x41, (byte) 0x3b, (byte) 0x2b, (byte) 0x87, (byte) 0x04, (byte) 0xc0, (byte) 0x88, + (byte) 0x37, (byte) 0xdb, (byte) 0x4c, (byte) 0x24, (byte) 0xe0, (byte) 0x18, (byte) 0xa3, + (byte) 0x66, (byte) 0x30, (byte) 0x64, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, + (byte) 0xf9, (byte) 0xda, (byte) 0x05, (byte) 0x74, (byte) 0xa2, (byte) 0x35, (byte) 0x5b, + (byte) 0x00, (byte) 0xa2, (byte) 0x92, (byte) 0x08, (byte) 0x7e, (byte) 0x72, (byte) 0x87, + (byte) 0xb4, (byte) 0x57, (byte) 0xf3, (byte) 0x01, (byte) 0x04, (byte) 0x46, (byte) 0x30, + (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, + (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x81, (byte) 0x6c, + (byte) 0xe6, (byte) 0x5a, (byte) 0x30, (byte) 0xf8, (byte) 0xe2, (byte) 0xaf, (byte) 0x7f, + (byte) 0xef, (byte) 0x04, (byte) 0x23, (byte) 0x50, (byte) 0xdc, (byte) 0x4e, (byte) 0xa4, + (byte) 0x48, (byte) 0xe2, (byte) 0x05, (byte) 0x62, (byte) 0x30, (byte) 0x12, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x01, (byte) 0x01, (byte) 0xff, + (byte) 0x04, (byte) 0x08, (byte) 0x30, (byte) 0x06, (byte) 0x01, (byte) 0x01, (byte) 0xff, + (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x1d, (byte) 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x04, + (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x01, (byte) 0x86, (byte) 0x30, (byte) 0x0a, + (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, + (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x03, (byte) 0x47, (byte) 0x00, (byte) 0x30, + (byte) 0x44, (byte) 0x02, (byte) 0x20, (byte) 0x2e, (byte) 0xbb, (byte) 0x46, (byte) 0xd4, + (byte) 0x40, (byte) 0xab, (byte) 0x55, (byte) 0xb3, (byte) 0xb6, (byte) 0xb6, (byte) 0x1b, + (byte) 0x54, (byte) 0xe6, (byte) 0x3e, (byte) 0xed, (byte) 0x54, (byte) 0x30, (byte) 0xb7, + (byte) 0xb7, (byte) 0x72, (byte) 0x10, (byte) 0x56, (byte) 0x34, (byte) 0x2d, (byte) 0x0b, + (byte) 0xdb, (byte) 0x5c, (byte) 0x7f, (byte) 0xee, (byte) 0x51, (byte) 0x9a, (byte) 0x85, + (byte) 0x02, (byte) 0x20, (byte) 0x17, (byte) 0x24, (byte) 0x2a, (byte) 0xdf, (byte) 0xf5, + (byte) 0x33, (byte) 0xaf, (byte) 0x40, (byte) 0xa8, (byte) 0x6d, (byte) 0xd0, (byte) 0x58, + (byte) 0x0c, (byte) 0x78, (byte) 0xfb, (byte) 0x86, (byte) 0xef, (byte) 0x07, (byte) 0xa6, + (byte) 0x71, (byte) 0xcc, (byte) 0x55, (byte) 0xfc, (byte) 0x6a, (byte) 0x0b, (byte) 0x84, + (byte) 0x28, (byte) 0x88, (byte) 0xa2, (byte) 0xca, (byte) 0x19, (byte) 0xe0}; + + private static final byte[] X509Issuer = { + (byte) 0x30, (byte) 0x81, (byte) 0x88, (byte) 0x31, (byte) 0x0b, + (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, + (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, + (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, + (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, + (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x15, (byte) 0x30, + (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, + (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2c, + (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, (byte) 0x2e, + (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, + (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, + (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x3b, + (byte) 0x30, (byte) 0x39, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x32, (byte) 0x41, + (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, + (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, (byte) 0x79, + (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, (byte) 0x65, + (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, + (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, + (byte) 0x41, (byte) 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, + (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, + (byte) 0x6e, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, + (byte) 0x65, (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, + (byte) 0x69, (byte) 0x61, (byte) 0x74, (byte) 0x65}; + private static final byte[] expiryTime = {(byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, + (byte) 0x30, (byte) 0x38, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, (byte) 0x30, + (byte) 0x39, (byte) 0x5a}; // OEM lock / unlock verification constants. private static final byte[] OEM_LOCK_PROVISION_VERIFICATION_LABEL = { // "OEM Provisioning Lock" 0x4f, 0x45, 0x4d, 0x20, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, @@ -168,73 +400,25 @@ public static ResponseAPDU setBootParams(CardSimulator simulator, KMEncoder enco public static ResponseAPDU provisionAdditionalCertChain(CardSimulator simulator, KMSEProvider cryptoProvider, KMEncoder encoder, KMDecoder decoder) { - short[] lengths = new short[2]; - byte[] rootPriv = new byte[128]; - byte[] rootPub = new byte[128]; - byte[] scratchpad = new byte[500]; - short[] coseScratchpad = new short[20]; - cryptoProvider.createAsymmetricKey(KMType.EC, rootPriv, (short) 0, (short) 128, - rootPub, (short) 0, (short) 128, lengths); - short coseKey = - KMTestUtils.constructCoseKey( - KMInteger.uint_8(KMCose.COSE_KEY_TYPE_EC2), - KMType.INVALID_VALUE, - KMNInteger.uint_8(KMCose.COSE_ALG_ES256), - KMInteger.uint_8(KMCose.COSE_KEY_OP_SIGN), - KMInteger.uint_8(KMCose.COSE_ECCURVE_256), - rootPub, (short) 0, lengths[1], - rootPriv, (short) 0, lengths[0], - false - ); - short payload = encoder.encode(coseKey, scratchpad, (short) 0, (short) 500); - payload = KMByteBlob.instance(scratchpad, (short) 0, payload); - // Protected Header - short protectedHeaderPtr = KMCose.constructHeaders(coseScratchpad, - KMNInteger.uint_8(KMCose.COSE_ALG_ES256), - KMType.INVALID_VALUE, - KMType.INVALID_VALUE, - KMType.INVALID_VALUE); - protectedHeaderPtr = encoder.encode(protectedHeaderPtr, scratchpad, (short) 0, (short) 500); - protectedHeaderPtr = KMByteBlob.instance(scratchpad, (short) 0, protectedHeaderPtr); - - // Unprotected Headers. - short emptyArr = KMArray.instance((short) 0); - short unprotectedHeader = KMCoseHeaders.instance(emptyArr); - - short aad = KMByteBlob.instance((short) 0); - KeyPair ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256); - KMECDeviceUniqueKey ecUniqueKey = new KMECDeviceUniqueKey(ecKeyPair); - ecUniqueKey.setS(rootPriv, (short) 0, lengths[0]); - ecUniqueKey.setW(rootPub, (short) 0, lengths[1]); - short root = KMTestUtils.constructCoseSign1(cryptoProvider, encoder, - protectedHeaderPtr, unprotectedHeader, payload, aad, - ecUniqueKey); - coseKey = - KMTestUtils.constructCoseKey( - KMInteger.uint_8(KMCose.COSE_KEY_TYPE_EC2), - KMType.INVALID_VALUE, - KMNInteger.uint_8(KMCose.COSE_ALG_ES256), - KMInteger.uint_8(KMCose.COSE_KEY_OP_SIGN), - KMInteger.uint_8(KMCose.COSE_ECCURVE_256), - RKP_DK_PUB, (short) 0, (short) RKP_DK_PUB.length, - RKP_DK_PRIV, (short) 0, (short) RKP_DK_PRIV.length, - false - ); - payload = encoder.encode(coseKey, scratchpad, (short) 0, (short) 500); - payload = KMByteBlob.instance(scratchpad, (short) 0, payload); - short leaf = KMTestUtils.constructCoseSign1(cryptoProvider, encoder, protectedHeaderPtr, - unprotectedHeader, payload, aad, - ecUniqueKey); - short additionalCertChain = KMArray.instance((short) 2); - KMArray.cast(additionalCertChain).add((short) 0, root); - KMArray.cast(additionalCertChain).add((short) 1, leaf); + short innerArrPtr = KMArray.instance((short) 2); + + short byteBlobPtr1 = KMByteBlob.instance(kEcAttestRootCert, (short) 0, (short) kEcAttestRootCert.length); + short byteBlobPtr2 = KMByteBlob.instance(kEcAttestCert, (short) 0, (short) kEcAttestCert.length); + + KMArray.cast(innerArrPtr).add((short) 0, byteBlobPtr1); + KMArray.cast(innerArrPtr).add((short) 1, byteBlobPtr2); short map = KMMap.instance((short) 1); byte[] signerName = "TestSigner".getBytes(); KMMap.cast(map) .add((short) 0, KMTextString.instance(signerName, (short) 0, (short) signerName.length), - additionalCertChain); + innerArrPtr); + byte[] output = new byte[2048]; + short encodedLen = encoder.encode(map, output, (short) 0, (short) 2048); + short encodedData = KMByteBlob.instance(output, (short) 0, encodedLen); + CommandAPDU apdu = KMTestUtils.encodeApdu(encoder, - (byte) INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD, map); + (byte) INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD, encodedData); + // print(commandAPDU.getBytes()); return simulator.transmitCommand(apdu); } diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMTestUtils.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMTestUtils.java index e9d5be04..d5828bc1 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMTestUtils.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMTestUtils.java @@ -26,6 +26,19 @@ import com.android.javacard.seprovider.KMECPrivateKey; import com.android.javacard.seprovider.KMException; import com.android.javacard.seprovider.KMSEProvider; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateFactory; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; import javacard.framework.ISO7816; import javacard.framework.ISOException; import javacard.framework.Util; @@ -460,17 +473,16 @@ public static void validateProtectedData(KMSEProvider cryptoProvider, KMEncoder short bccArr = KMArray.instance((short) 2); KMArray.cast(bccArr).add((short) 0, coseKeyExp); KMArray.cast(bccArr).add((short) 1, signedMacArr); - //if (!testMode) { short headers = KMCoseHeaders.exp(); short arrInst = KMArray.instance((short) 4); KMArray.cast(arrInst).add((short) 0, KMByteBlob.exp()); KMArray.cast(arrInst).add((short) 1, headers); KMArray.cast(arrInst).add((short) 2, KMByteBlob.exp()); KMArray.cast(arrInst).add((short) 3, KMByteBlob.exp()); - short coseSignArr = KMArray.exp(arrInst); + short x509CertChainArr = KMArray.exp(KMByteBlob.exp()); if (!testMode) { additionalCertChain = KMMap.instance((short) 1); - KMMap.cast(additionalCertChain).add((short) 0, KMTextString.exp(), coseSignArr); + KMMap.cast(additionalCertChain).add((short) 0, KMTextString.exp(), x509CertChainArr); } // protected payload exp short payload = KMArray.instance(payloadLength); @@ -499,78 +511,63 @@ public static void validateProtectedData(KMSEProvider cryptoProvider, KMEncoder if (!testMode) { short addCertChain = KMArray.cast(payloadPtr).get((short) 2); addCertChain = KMMap.cast(addCertChain).getKeyValue((short) 0); - Assert.assertTrue( - validateCertChain(cryptoProvider, encoder, decoder, KMCose.COSE_ALG_ES256, - KMCose.COSE_ALG_ES256, addCertChain)); + try { + Assert.assertTrue(validateCertChain(cryptoProvider, encoder, decoder, KMCose.COSE_ALG_ES256, + KMCose.COSE_ALG_ES256, addCertChain)); + } catch (IOException e) { + e.printStackTrace(); + Assert.fail("Certificate chain validation failed."); + } + } + } + + public static X509Certificate decodeCert(byte[] cert, short certOff, short certLen) + throws IOException { + System.out.println("Certificate=>"); + print(cert, certOff, certLen); + byte[] certificate = new byte[certLen]; + Util.arrayCopyNonAtomic(cert, certOff, certificate, (short) 0, certLen); + InputStream inStream = new ByteArrayInputStream(certificate); + CertificateFactory certFactory; + try { + certFactory = CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + // Should not happen, as X.509 is mandatory for all providers. + throw new RuntimeException(e); + } + try { + return (X509Certificate) certFactory.generateCertificate(inStream); + } catch (CertificateException e) { + throw new IOException(e); } } public static boolean validateCertChain(KMSEProvider cryptoProvider, KMEncoder encoder, KMDecoder decoder, byte expCertAlg, byte expLeafCertAlg, - short certChainArr) { - byte[] scratchPad = new byte[500]; - short offset = 0; - short len = KMArray.cast(certChainArr).length(); - short coseHeadersExp = KMCoseHeaders.exp(); - //prepare exp for coseky - short coseKeyExp = KMCoseKey.exp(); - short ptr1; - short ptr2; - short signStructure; - short encodedLen; - short prevCoseKey = 0; - short keySize; - short alg = expCertAlg; - short[] shortScratchBuffer = new short[20]; - short index; - for (index = 0; index < len; index++) { - ptr1 = KMArray.cast(certChainArr).get(index); - - // validate protected Headers - ptr2 = KMArray.cast(ptr1).get(KMCose.COSE_SIGN1_PROTECTED_PARAMS_OFFSET); - ptr2 = decoder.decode(coseHeadersExp, KMByteBlob.cast(ptr2).getBuffer(), - KMByteBlob.cast(ptr2).getStartOff(), KMByteBlob.cast(ptr2).length()); - if (!KMCoseHeaders.cast(ptr2).isDataValid(shortScratchBuffer, alg, KMType.INVALID_VALUE)) { - return false; - } - - // parse and get the public key from payload. - ptr2 = KMArray.cast(ptr1).get(KMCose.COSE_SIGN1_PAYLOAD_OFFSET); - ptr2 = decoder.decode(coseKeyExp, KMByteBlob.cast(ptr2).getBuffer(), - KMByteBlob.cast(ptr2).getStartOff(), KMByteBlob.cast(ptr2).length()); - if (index == len - 1) { - alg = expLeafCertAlg; + short certChainArr) throws IOException { + short arrLen = KMArray.cast(certChainArr).length(); + PublicKey previousKey = null; + for(short i = 0; i < arrLen; i++) { + short byteBlob = KMArray.cast(certChainArr).get((short) i); + X509Certificate x509Cert = + decodeCert(KMByteBlob.cast(byteBlob).getBuffer(), KMByteBlob.cast(byteBlob).getStartOff(), + KMByteBlob.cast(byteBlob).length()); + if (i == 0) { + previousKey = x509Cert.getPublicKey(); } - if (!KMCoseKey.cast(ptr2) - .isDataValid(shortScratchBuffer, KMCose.COSE_KEY_TYPE_EC2, KMType.INVALID_VALUE, alg, - KMType.INVALID_VALUE, KMCose.COSE_ECCURVE_256)) { - return false; + try { + x509Cert.checkValidity(); + } catch (CertificateException e) { + Assert.fail("Certificate validity expired."); } - if (prevCoseKey == 0) { - prevCoseKey = ptr2; - } - // Get the public key. - keySize = KMCoseKey.cast(prevCoseKey).getEcdsa256PublicKey(scratchPad, offset); - if (keySize != 65) { - return false; - } - // Validate signature. - signStructure = - KMCose.constructCoseSignStructure( - KMArray.cast(ptr1).get(KMCose.COSE_SIGN1_PROTECTED_PARAMS_OFFSET), - KMByteBlob.instance((short) 0), - KMArray.cast(ptr1).get(KMCose.COSE_SIGN1_PAYLOAD_OFFSET)); - encodedLen = encoder.encode(signStructure, scratchPad, (short) (offset + keySize), - (short) 500); - - if (!cryptoProvider.ecVerify256(scratchPad, offset, keySize, scratchPad, - (short) (offset + keySize), encodedLen, - KMByteBlob.cast(KMArray.cast(ptr1).get(KMCose.COSE_SIGN1_SIGNATURE_OFFSET)).getBuffer(), - KMByteBlob.cast(KMArray.cast(ptr1).get(KMCose.COSE_SIGN1_SIGNATURE_OFFSET)).getStartOff(), - KMByteBlob.cast(KMArray.cast(ptr1).get(KMCose.COSE_SIGN1_SIGNATURE_OFFSET)).length())) { - return false; + try { + x509Cert.verify(previousKey); + } catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException | + NoSuchProviderException | SignatureException e) { + Assert.fail("Certificate verification failed."); + e.printStackTrace(); } - prevCoseKey = ptr2; + previousKey = x509Cert.getPublicKey(); } return true; } diff --git a/Applet/src/com/android/javacard/keymaster/KMDecoder.java b/Applet/src/com/android/javacard/keymaster/KMDecoder.java index 51395bb9..04eabe54 100644 --- a/Applet/src/com/android/javacard/keymaster/KMDecoder.java +++ b/Applet/src/com/android/javacard/keymaster/KMDecoder.java @@ -753,13 +753,12 @@ public short readKeyblobVersion(byte[] buf, short bufOffset, short bufLen) { return version; } - public short readCertificateChainLengthAndHeaderLen(byte[] buf, short bufOffset, - short bufLen) { + public short readCertificateChainHeaderLen(byte[] buf, short bufOffset, + short bufLen) { bufferRef[0] = buf; scratchBuf[START_OFFSET] = bufOffset; scratchBuf[LEN_OFFSET] = (short) (bufOffset + bufLen); - short totalLen = readMajorTypeWithPayloadLength(BYTES_TYPE); - totalLen += (short) (scratchBuf[START_OFFSET] - bufOffset); - return totalLen; + readMajorTypeWithPayloadLength(BYTES_TYPE); + return (short) (scratchBuf[START_OFFSET] - bufOffset); } } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index 1fc34dd7..35560830 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -74,7 +74,7 @@ public class KMKeymintDataStore implements KMUpgradable { private static final short SHARED_SECRET_KEY_SIZE = 32; private static final byte DEVICE_STATUS_FLAG_SIZE = 1; - private static final short ADDITIONAL_CERT_CHAIN_MAX_SIZE = 512;//First 2 bytes for length. + private static final short ADDITIONAL_CERT_CHAIN_MAX_SIZE = 2500;//First 2 bytes for length. private static final short BCC_MAX_SIZE = 512; //Device boot states. Applet starts executing the @@ -952,7 +952,7 @@ private void handlePreviousVersionUpgrade(Element element) { element.readObject(); // pop verifiedHash element.readObject(); //pop bootKey element.readObject(); // pop bootPatchLevel - additionalCertChain = (byte[]) element.readObject(); + element.readObject(); // pop AdditionalCertChain bcc = (byte[]) element.readObject(); // Read Key Objects @@ -979,7 +979,11 @@ private void handleUpgrade(Element element, short oldVersion) { attIdMeId = (byte[]) element.readObject(); attIdManufacturer = (byte[]) element.readObject(); attIdModel = (byte[]) element.readObject(); - additionalCertChain = (byte[]) element.readObject(); + if (oldVersion <= KM_APPLET_PACKAGE_VERSION_2) { + element.readObject(); // Pop AdditionalCertificateChain. + } else { + additionalCertChain = (byte[]) element.readObject(); + } bcc = (byte[]) element.readObject(); oemRootPublicKey = (byte[]) element.readObject(); // Read Key Objects diff --git a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java index 72331fa4..11da8f50 100644 --- a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java +++ b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java @@ -88,7 +88,7 @@ public class RemotelyProvisionedComponentDevice { public static final byte DI_SCHEMA_VERSION = 2; public static final byte[] DI_SECURITY_LEVEL = {0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x62, 0x6F, 0x78}; - private static final short MAX_SEND_DATA = 1024; + private static final short MAX_SEND_DATA = 512; private static final byte[] google = {0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65}; @@ -838,21 +838,21 @@ private KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(boolean testMode, byte[] * DeviceInfo is a CBOR Map structure described by the following CDDL. *

* DeviceInfo = { - * ? "brand" : tstr, - * ? "manufacturer" : tstr, - * ? "product" : tstr, - * ? "model" : tstr, - * ? "board" : tstr, - * ? "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values - * ? "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values - * ? "vbmeta_digest": bstr, // Taken from the AVB values + * "brand" : tstr, + * "manufacturer" : tstr, + * "product" : tstr, + * "model" : tstr, + * "device" : tstr, + * "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values + * "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values + * "vbmeta_digest": bstr, // Taken from the AVB values * ? "os_version" : tstr, // Same as android.os.Build.VERSION.release - * ? "system_patch_level" : uint, // YYYYMMDD - * ? "boot_patch_level" : uint, //YYYYMMDD - * ? "vendor_patch_level" : uint, // YYYYMMDD - * "version" : 1, // TheCDDL schema version + * "system_patch_level" : uint, // YYYYMMDD + * "boot_patch_level" : uint, //YYYYMMDD + * "vendor_patch_level" : uint, // YYYYMMDD + * "version" : 2, // TheCDDL schema version * "security_level" : "tee" / "strongbox" - * "att_id_state": "locked" / "open" + * "fused": 1 / 0, * } */ private short createDeviceInfo(byte[] scratchpad) { diff --git a/ProvisioningTool/sample_json_keymint_cf.txt b/ProvisioningTool/sample_json_keymint_cf.txt index f0de686c..a046baef 100644 --- a/ProvisioningTool/sample_json_keymint_cf.txt +++ b/ProvisioningTool/sample_json_keymint_cf.txt @@ -21,8 +21,9 @@ "signer_info": { "signer_name": "Google", "signing_keys": [ - "test_resources/ca_key.der", - "test_resources/intermediate_key.der" + "test_resources/ca_cert.der", + "test_resources/intermediate_cert.der", + "test_resources/batch_cert.der" ] }, "oem_root_key": "test_resources/oem_root_key.der", diff --git a/ProvisioningTool/sample_json_keymint_gf.txt b/ProvisioningTool/sample_json_keymint_gf.txt index 94b2a1e9..a624d1a5 100644 --- a/ProvisioningTool/sample_json_keymint_gf.txt +++ b/ProvisioningTool/sample_json_keymint_gf.txt @@ -21,8 +21,9 @@ "signer_info": { "signer_name": "Google", "signing_keys": [ - "test_resources/ca_key.der", - "test_resources/intermediate_key.der" + "test_resources/ca_cert.der", + "test_resources/intermediate_cert.der", + "test_resources/batch_cert.der" ] }, "oem_root_key": "test_resources/oem_root_key.der", diff --git a/ProvisioningTool/src/construct_apdus.cpp b/ProvisioningTool/src/construct_apdus.cpp index 2c101a93..0a8b7437 100644 --- a/ProvisioningTool/src/construct_apdus.cpp +++ b/ProvisioningTool/src/construct_apdus.cpp @@ -317,9 +317,8 @@ int processInputFile() { int processAdditionalCertificateChain() { Json::Value signerInfo = root.get(kSignerInfo, Json::Value::nullRef); if (!signerInfo.isNull()) { + std::vector certData; std::string signerName; - std::string signingKeyFile; - std::vector previousKey; Array array; if (SUCCESS != getStringValue(signerInfo, "signer_name", signerName)) { @@ -327,89 +326,44 @@ int processAdditionalCertificateChain() { return FAILURE; } - Json::Value keys = signerInfo.get("signing_keys", Json::Value::nullRef); - if (!keys.isNull()) { - if (!keys.isArray()) { + Json::Value certChainFiles = signerInfo.get("signing_keys", Json::Value::nullRef); + if (!certChainFiles.isNull()) { + if (!certChainFiles.isArray()) { printf("\n Improper value for signing_keys in json file \n"); return FAILURE; } - for(uint32_t i = 0; i < keys.size(); i++) { - std::vector data; - std::vector privateKey; - std::vector x_coord; - std::vector y_coord; - - if (!keys[i].isString()) { - printf("\n Improper value for signing_keys in json file \n"); + for (uint32_t i = 0; i < certChainFiles.size(); i++) { + if(certChainFiles[i].isString()) { + /* Read the certificates. */ + if(SUCCESS != readDataFromFile(certChainFiles[i].asString().data(), certData)) { + printf("\n Failed to read the Root certificate\n"); + return FAILURE; + } + array.add(certData); + certData.clear(); + + } else { + printf("\n Fail: Only proper certificate paths as a " + "string is allowed inside the json file. \n"); return FAILURE; } - - if(SUCCESS != readDataFromFile(keys[i].asString().data(), data)) { - printf("\n Failed to read the attestation key from the file.\n"); - return FAILURE; - } - if (SUCCESS != ecRawKeyFromPKCS8(data, privateKey, x_coord, y_coord)) { - return FAILURE; - } - - if (i == 0) { - // self-signed. - previousKey = privateKey; - } - - auto rootCoseSign = - cppcose::constructCoseSign1(previousKey, /* Signing key */ - cppbor::Map() /* Payload CoseKey */ - .add(CoseKey::KEY_TYPE, EC2) - .add(CoseKey::ALGORITHM, ES256) - .add(CoseKey::CURVE, P256) - .add(CoseKey::KEY_OPS, SIGN) - .add(CoseKey::PUBKEY_X, x_coord) - .add(CoseKey::PUBKEY_Y, y_coord) - .canonicalize() - .encode(), - {} /* AAD */); - if (!rootCoseSign) { - printf("\n Failed to construct CoseSign1 %s\n", rootCoseSign.moveMessage().c_str()); - return FAILURE; - } - - // Add to cbor array - array.add(rootCoseSign.moveValue()); - previousKey = privateKey; } + } else { + printf("\n Fail: cert chain value should be an array inside the json file. \n"); + return FAILURE; } - std::vector dk_priv; - std::vector dk_pub_x; - std::vector dk_pub_y; - if (SUCCESS == getDeviceUniqueKey(dk_priv, dk_pub_x, dk_pub_y)) { - auto dkCoseSign = - cppcose::constructCoseSign1(previousKey, /* Signing key */ - cppbor::Map() /* Payload CoseKey */ - .add(CoseKey::KEY_TYPE, EC2) - .add(CoseKey::ALGORITHM, ES256) - .add(CoseKey::CURVE, P256) - .add(CoseKey::KEY_OPS, SIGN) - .add(CoseKey::PUBKEY_X, dk_pub_x) - .add(CoseKey::PUBKEY_Y, dk_pub_y) - .canonicalize() - .encode(), - {} /* AAD */); - if (!dkCoseSign) { - printf("\n Failed to construct CoseSign1 %s\n", dkCoseSign.moveMessage().c_str()); - return FAILURE; - } - array.add(dkCoseSign.moveValue()); - std::vector cborData = Map().add(signerName, std::move(array)).encode(); - if(SUCCESS != addApduHeader(kAdditionalCertChainCmd, cborData)) { - return FAILURE; - } - // Write to json. - writerRoot[kAdditionalCertChain] = getHexString(cborData); - } else { + // Prepare cbor input + cppbor::Map map; + map.add(signerName, std::move(array)); + cppbor::Bstr bstr(map.encode()); + std::vector cborData = bstr.encode(); + + if(SUCCESS != addApduHeader(kAdditionalCertChainCmd, cborData)) { return FAILURE; } + // Write to json. + writerRoot[kAdditionalCertChain] = getHexString(cborData); } else { printf("\n Improper value for signer_info in json file \n"); From 4b2eaed9a6382750bfc43dd782664f1cc1a0b41a Mon Sep 17 00:00:00 2001 From: Subrahmanyaman Date: Wed, 28 Sep 2022 19:19:24 +0000 Subject: [PATCH 2/5] Skip sending AdditionalCertChain --- .../RemotelyProvisionedComponentDevice.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java index 11da8f50..b72cce46 100644 --- a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java +++ b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java @@ -196,9 +196,8 @@ private void createAuthorizedEEKRoot() { } private void initializeDataTable() { - if (dataIndex[0] != 0) { - KMException.throwIt(KMError.INVALID_STATE); - } + clearDataTable(); + releaseOperation(); dataIndex[0] = (short) (DATA_INDEX_SIZE * DATA_INDEX_ENTRY_SIZE); } @@ -561,8 +560,10 @@ public void process(short ins, APDU apdu) throws Exception { } private boolean isAdditionalCertificateChainPresent() { - if ((TRUE == data[getEntry(TEST_MODE)])) { - // In test mode, don't include AdditionalCertificateChain in ProtectedData. + if ((0x02 == RKP_VERSION) || (TRUE == data[getEntry(TEST_MODE)])) { + // Don't include AdditionalCertificateChain in ProtectedData if either + // 1. KeyMint Version is 2 or + // 2. Requested CSR for test mode. return false; } return (storeDataInst.getAdditionalCertChainLength() == 0 ? false : true); @@ -836,7 +837,7 @@ private KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(boolean testMode, byte[] /** * DeviceInfo is a CBOR Map structure described by the following CDDL. - *

+ * * DeviceInfo = { * "brand" : tstr, * "manufacturer" : tstr, From 4bf9ced31d8bb32fd46b7eac76f86336af31fc16 Mon Sep 17 00:00:00 2001 From: Subrahmanyaman Date: Thu, 29 Sep 2022 00:51:07 +0000 Subject: [PATCH 3/5] Removed redundant variables in KMFunction tests. --- .../android/javacard/test/KMProvision.java | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java index f6305d12..6331539e 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java @@ -293,38 +293,6 @@ public class KMProvision { (byte) 0x71, (byte) 0xcc, (byte) 0x55, (byte) 0xfc, (byte) 0x6a, (byte) 0x0b, (byte) 0x84, (byte) 0x28, (byte) 0x88, (byte) 0xa2, (byte) 0xca, (byte) 0x19, (byte) 0xe0}; - private static final byte[] X509Issuer = { - (byte) 0x30, (byte) 0x81, (byte) 0x88, (byte) 0x31, (byte) 0x0b, - (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, - (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, - (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, - (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, - (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x15, (byte) 0x30, - (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, - (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2c, - (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, (byte) 0x2e, - (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, - (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, - (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x3b, - (byte) 0x30, (byte) 0x39, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x32, (byte) 0x41, - (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, - (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, (byte) 0x79, - (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, (byte) 0x65, - (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, - (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, - (byte) 0x41, (byte) 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, - (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, - (byte) 0x6e, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, - (byte) 0x65, (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, - (byte) 0x69, (byte) 0x61, (byte) 0x74, (byte) 0x65}; - private static final byte[] expiryTime = {(byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, - (byte) 0x30, (byte) 0x38, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, (byte) 0x30, - (byte) 0x39, (byte) 0x5a}; // OEM lock / unlock verification constants. private static final byte[] OEM_LOCK_PROVISION_VERIFICATION_LABEL = { // "OEM Provisioning Lock" 0x4f, 0x45, 0x4d, 0x20, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, From 6d2d48c29d1bd8568ab697f2522ee44c728574b7 Mon Sep 17 00:00:00 2001 From: Subrahmanyaman Date: Thu, 29 Sep 2022 03:25:02 +0000 Subject: [PATCH 4/5] Upgrade changes for AdditionalCertificateChain --- .../keymaster/KMKeymintDataStore.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index 35560830..af8981d9 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -924,7 +924,13 @@ public void onRestore(Element element, short oldVersion, short currentVersion) { // have to update the secureBootMode with the correct input. secureBootMode = 0; provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_SECURE_BOOT_MODE; + // Applet package Versions till 2 had CoseSign1 for additionalCertificateChain. + // From package version 3, the additionalCertificateChain is in X.509 format. + // So Unreference the old address and allocate new persistent memory. + additionalCertChain = new byte[ADDITIONAL_CERT_CHAIN_MAX_SIZE]; JCSystem.commitTransaction(); + // Request for ObjectDeletion for unreferenced address of additionalCertChain. + JCSystem.requestObjectDeletion(); return; } handleUpgrade(element, oldVersion); @@ -952,7 +958,7 @@ private void handlePreviousVersionUpgrade(Element element) { element.readObject(); // pop verifiedHash element.readObject(); //pop bootKey element.readObject(); // pop bootPatchLevel - element.readObject(); // pop AdditionalCertChain + additionalCertChain = (byte[]) element.readObject(); bcc = (byte[]) element.readObject(); // Read Key Objects @@ -979,11 +985,7 @@ private void handleUpgrade(Element element, short oldVersion) { attIdMeId = (byte[]) element.readObject(); attIdManufacturer = (byte[]) element.readObject(); attIdModel = (byte[]) element.readObject(); - if (oldVersion <= KM_APPLET_PACKAGE_VERSION_2) { - element.readObject(); // Pop AdditionalCertificateChain. - } else { - additionalCertChain = (byte[]) element.readObject(); - } + additionalCertChain = (byte[]) element.readObject(); bcc = (byte[]) element.readObject(); oemRootPublicKey = (byte[]) element.readObject(); // Read Key Objects @@ -1013,8 +1015,14 @@ void handleProvisionStatusUpgrade(byte[] dataTable, short dataTableIndex){ // have to update the secureBootMode with the correct input. secureBootMode = 0; provisionStatus = pStatus; + // Applet package Versions till 2 had CoseSign1 for additionalCertificateChain. + // From package version 3, the additionalCertificateChain is in X.509 format. + // So Unreference the old address and allocate new persistent memory. + additionalCertChain = new byte[ADDITIONAL_CERT_CHAIN_MAX_SIZE]; JCSystem.commitTransaction(); repository.reclaimMemory((short)2); + // Request object deletion for unreferenced address for additionalCertChain + JCSystem.requestObjectDeletion(); } @Override From a4318cf3661ff69327800d00729809675182c5d2 Mon Sep 17 00:00:00 2001 From: Subrahmanyaman Date: Thu, 29 Sep 2022 20:59:39 +0000 Subject: [PATCH 5/5] Challenge length check --- .../keymaster/RemotelyProvisionedComponentDevice.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java index b72cce46..66d0127b 100644 --- a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java +++ b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java @@ -411,13 +411,17 @@ public void processUpdateChallenge(APDU apdu) throws Exception { arr = KMKeymasterApplet.receiveIncoming(apdu, arr); // Store the challenge in the data table. short challenge = KMArray.cast(arr).get((short) 0); - short dataEntryIndex = createEntry(CHALLENGE, KMByteBlob.cast(challenge).length()); + short challengeLen = KMByteBlob.cast(challenge).length(); + if (challengeLen < 32 || challengeLen > 64) { + KMException.throwIt(KMError.INVALID_INPUT_LENGTH); + } + short dataEntryIndex = createEntry(CHALLENGE, challengeLen); Util.arrayCopyNonAtomic( KMByteBlob.cast(challenge).getBuffer(), KMByteBlob.cast(challenge).getStartOff(), data, dataEntryIndex, - KMByteBlob.cast(challenge).length() + challengeLen ); // Update the state updateState(UPDATE);