From b90e22c6fe069425149699ad3bcf66dc2ca492dc Mon Sep 17 00:00:00 2001 From: "avinash.hedage" Date: Fri, 3 Jun 2022 11:08:55 +0000 Subject: [PATCH 1/2] updated bug fixes in RMA support --- .../javacard/keymaster/KMAndroidSEApplet.java | 99 ++++++++----------- .../javacard/seprovider/KMSEProvider.java | 1 - .../javacard/keymaster/KMJCardSimApplet.java | 90 +++++++---------- .../keymaster/KMKeymintDataStore.java | 29 +++--- ProvisioningTool/src/provision.cpp | 20 ++-- 5 files changed, 104 insertions(+), 135 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index 8fb66a7f..3f557d0d 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -65,17 +65,17 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis public static final byte BOOT_HASH_MAX_SIZE = 32; // Provision reporting status - private static final byte NOT_PROVISIONED = 0x00; - private static final byte PROVISION_STATUS_ATTESTATION_KEY = 0x01; // unused in keymint - private static final byte PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x02; // unused in keymint - private static final byte PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x04; // unused in keymint - private static final byte PROVISION_STATUS_ATTEST_IDS = 0x08; - private static final byte PROVISION_STATUS_PRESHARED_SECRET = 0x10; - private static final byte PROVISION_STATUS_PROVISIONING_LOCKED = 0x20; - private static final byte PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR = 0x40; - private static final byte PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = (byte) 0x80; - private static final byte PROVISION_STATUS_SE_LOCKED = 0x01; - private static final byte PROVISION_STATUS_OEM_PUBLIC_KEY = 0x02; + private static final short NOT_PROVISIONED = 0x0000; + private static final short PROVISION_STATUS_ATTESTATION_KEY = 0x0001; + private static final short PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x0002; + private static final short PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x0004; + private static final short PROVISION_STATUS_ATTEST_IDS = 0x0008; + private static final short PROVISION_STATUS_PRESHARED_SECRET = 0x0010; + private static final short PROVISION_STATUS_PROVISIONING_LOCKED = 0x0020; + private static final short PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR = 0x0040; + private static final short PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = 0x0080; + private static final short PROVISION_STATUS_SE_LOCKED = 0x0100; + private static final short PROVISION_STATUS_OEM_PUBLIC_KEY = 0x0200; public static final short SHARED_SECRET_KEY_SIZE = 32; @@ -206,7 +206,7 @@ private boolean isCommandAllowed(short apduIns) { break; case INS_SE_FACTORY_PROVISIONING_LOCK_CMD: - if(!isSeFactoryProvisioningComplete()) { + if(isSeFactoryProvisioningLocked() || !isSeFactoryProvisioningComplete()) { result = false; } break; @@ -216,7 +216,7 @@ private boolean isCommandAllowed(short apduIns) { // 1. All the necessary provisioning commands are succcessfully executed // 2. SE provision is locked // 3. OEM Root Public is provisioned. - if (!(isProvisioningComplete() && isSeFactoryProvisioningLocked())) { + if (kmDataStore.isProvisionLocked() || !(isProvisioningComplete() && isSeFactoryProvisioningLocked())) { result = false; } break; @@ -243,44 +243,48 @@ private boolean isCommandAllowed(short apduIns) { } private boolean isSeFactoryProvisioningLocked() { - short dInex = repository.allocReclaimableMemory((short)1); - byte data[] = repository.getHeap(); + short dInex = repository.allocReclaimableMemory((short)2); + byte data[] = repository.getHeap(); kmDataStore.getProvisionStatus(data, dInex); + short pStatus = Util.getShort(data, dInex); boolean result = false; - if ((0 != (data[dInex] & PROVISION_STATUS_SE_LOCKED))) { + if ((0 != (pStatus & PROVISION_STATUS_SE_LOCKED))) { result = true; } - repository.reclaimMemory((short)1); + repository.reclaimMemory((short)2); return result; } private boolean isSeFactoryProvisioningComplete() { - short dIndex = repository.allocReclaimableMemory((short)1); + short dIndex = repository.allocReclaimableMemory((short)2); byte data[] = repository.getHeap(); kmDataStore.getProvisionStatus(data, dIndex); + short pStatus = Util.getShort(data, dIndex); boolean result = false; - if ((0 != (data[dIndex] & INS_PROVISION_RKP_DEVICE_UNIQUE_KEYPAIR_CMD)) - && (0 != ((data[dIndex] & INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD)))) { - result = true; + if ((0 != (pStatus & PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR)) + && (0 != ((pStatus & PROVISION_STATUS_ADDITIONAL_CERT_CHAIN)))) { + result = true; } - repository.reclaimMemory((short)1); + repository.reclaimMemory((short)2); return result; } private void processOEMUnlockProvisionCmd(APDU apdu) { - handleOEMLockUnlockCmd(OEM_UNLOCK_PROVISION_VERIFICATION_LABEL, apdu); + authenticateOEM(OEM_UNLOCK_PROVISION_VERIFICATION_LABEL, apdu); + kmDataStore.setProvisionLock(false); kmDataStore.unlockProvision(PROVISION_STATUS_PROVISIONING_LOCKED); sendError(apdu, KMError.OK); } private void processOEMLockProvisionCmd(APDU apdu) { - handleOEMLockUnlockCmd(OEM_LOCK_PROVISION_VERIFICATION_LABEL, apdu); + authenticateOEM(OEM_LOCK_PROVISION_VERIFICATION_LABEL, apdu); // Enable the lock bit in provision status. + kmDataStore.setProvisionLock(true); kmDataStore.setProvisionStatus(PROVISION_STATUS_PROVISIONING_LOCKED); sendError(apdu, KMError.OK); } - private void handleOEMLockUnlockCmd(byte[] plainMsg, APDU apdu) { + private void authenticateOEM(byte[] plainMsg, APDU apdu) { tmpVariables[0] = KMArray.instance((short) 1); KMArray.cast(tmpVariables[0]).add((short) 0, KMByteBlob.exp()); @@ -519,7 +523,7 @@ private void processGetProvisionStatusCmd(APDU apdu) { kmDataStore.getProvisionStatus(scratchpad, (short) 0); short resp = KMArray.instance((short) 2); KMArray.cast(resp).add((short) 0, buildErrorStatus(KMError.OK)); - KMArray.cast(resp).add((short) 1, KMInteger.uint_8(scratchpad[0])); + KMArray.cast(resp).add((short) 1, KMInteger.instance(scratchpad, (short)0, (short)2)); sendOutgoing(apdu, resp); } @@ -586,53 +590,30 @@ private void processSetBootParamsCmd(APDU apdu) { enumVal = KMEnum.cast(bootParam).getVal(); kmDataStore.setDeviceLocked(enumVal == KMType.DEVICE_LOCKED_TRUE); - // Clear the Computed SharedHmac and Hmac nonce from persistent memory. Util.arrayFillNonAtomic(scratchPad, (short) 0, KMKeymintDataStore.COMPUTED_HMAC_KEY_SIZE, (byte) 0); kmDataStore.createComputedHmacKey(scratchPad, (short) 0, KMKeymintDataStore.COMPUTED_HMAC_KEY_SIZE); - + super.reboot(); sendError(apdu, KMError.OK); } private boolean isProvisioningComplete() { - short dInex = repository.allocReclaimableMemory((short)1); - byte data[] = repository.getHeap(); + short dInex = repository.allocReclaimableMemory((short)2); + byte data[] = repository.getHeap(); kmDataStore.getProvisionStatus(data, dInex); + short pStatus = Util.getShort(data, dInex); boolean result = false; - if (kmDataStore.isProvisionLocked() || ((0 != (data[dInex] & PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR)) - && (0 != (data[dInex] & PROVISION_STATUS_ADDITIONAL_CERT_CHAIN)) - && (0 != (data[dInex] & PROVISION_STATUS_PRESHARED_SECRET)) - && (0 != (data[dInex] & PROVISION_STATUS_ATTEST_IDS)))) { + if (kmDataStore.isProvisionLocked() || ((0 != (pStatus & PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR)) + && (0 != (pStatus & PROVISION_STATUS_ADDITIONAL_CERT_CHAIN)) + && (0 != (pStatus & PROVISION_STATUS_PRESHARED_SECRET)) + && (0 != (pStatus & PROVISION_STATUS_ATTEST_IDS)))) { result = true; } - repository.reclaimMemory((short)1); + repository.reclaimMemory((short)2); return result; } - private boolean isOemProvisionComplete() { - short dInex = repository.allocReclaimableMemory((short)1); - byte data[] = repository.getHeap(); - kmDataStore.getProvisionStatus(data, dInex); - boolean result = false; - if ((0 != (data[dInex] & PROVISION_STATUS_OEM_PUBLIC_KEY)) - && (0 != (data[dInex] & PROVISION_STATUS_SE_LOCKED))) { - result = true; - } - repository.reclaimMemory((short)1); - return result; - } - - private void processLockProvisioningCmd(APDU apdu) { - if (isProvisioningComplete()) { - kmDataStore.setProvisionLocked(); - kmDataStore.setProvisionStatus(PROVISION_STATUS_PROVISIONING_LOCKED); - sendError(apdu, KMError.OK); - } else { - ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); - } - } - @Override public void onCleanup() { } @@ -704,5 +685,5 @@ private short validateApdu(APDU apdu) { } return apduBuffer[ISO7816.OFFSET_INS]; } -} +} diff --git a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java index d641e4c6..d77f2167 100644 --- a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java +++ b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java @@ -698,7 +698,6 @@ KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair(KMDeviceUniqueKeyPair key, short messageDigest256(byte[] inBuff, short inOffset, short inLength, byte[] outBuff, short outOffset); - /** * This function generates a HMAC key from the provided key buffers. * diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java index 904a44ae..66f80148 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java @@ -54,17 +54,17 @@ public class KMJCardSimApplet extends KMKeymasterApplet { public static final byte BOOT_HASH_MAX_SIZE = 32; // Provision reporting status - private static final byte NOT_PROVISIONED = 0x00; - private static final byte PROVISION_STATUS_ATTESTATION_KEY = 0x01; // unused in keymint - private static final byte PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x02; // unused in keymint - private static final byte PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x04; // unused in keymint - private static final byte PROVISION_STATUS_ATTEST_IDS = 0x08; - private static final byte PROVISION_STATUS_PRESHARED_SECRET = 0x10; - private static final byte PROVISION_STATUS_PROVISIONING_LOCKED = 0x20; - private static final byte PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR = 0x40; - private static final byte PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = (byte) 0x80; - private static final byte PROVISION_STATUS_SE_LOCKED = 0x01; - private static final byte PROVISION_STATUS_OEM_PUBLIC_KEY = 0x02; + private static final short NOT_PROVISIONED = 0x0000; + private static final short PROVISION_STATUS_ATTESTATION_KEY = 0x0001; + private static final short PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x0002; + private static final short PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x0004; + private static final short PROVISION_STATUS_ATTEST_IDS = 0x0008; + private static final short PROVISION_STATUS_PRESHARED_SECRET = 0x0010; + private static final short PROVISION_STATUS_PROVISIONING_LOCKED = 0x0020; + private static final short PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR = 0x0040; + private static final short PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = 0x0080; + private static final short PROVISION_STATUS_SE_LOCKED = 0x0100; + private static final short PROVISION_STATUS_OEM_PUBLIC_KEY = 0x0200; public static final short SHARED_SECRET_KEY_SIZE = 32; @@ -194,7 +194,7 @@ private boolean isCommandAllowed(short apduIns) { break; case INS_SE_FACTORY_PROVISIONING_LOCK_CMD: - if(!isSeFactoryProvisioningComplete()) { + if(isSeFactoryProvisioningLocked() || !isSeFactoryProvisioningComplete()) { result = false; } break; @@ -204,7 +204,7 @@ private boolean isCommandAllowed(short apduIns) { // 1. All the necessary provisioning commands are succcessfully executed // 2. SE provision is locked // 3. OEM Root Public is provisioned. - if (!(isProvisioningComplete() && isSeFactoryProvisioningLocked())) { + if (kmDataStore.isProvisionLocked() || !(isProvisioningComplete() && isSeFactoryProvisioningLocked())) { result = false; } break; @@ -231,44 +231,48 @@ private boolean isCommandAllowed(short apduIns) { } private boolean isSeFactoryProvisioningLocked() { - short dInex = repository.allocReclaimableMemory((short)1); + short dInex = repository.allocReclaimableMemory((short)2); byte data[] = repository.getHeap(); kmDataStore.getProvisionStatus(data, dInex); + short pStatus = Util.getShort(data, dInex); boolean result = false; - if ((0 != (data[dInex] & PROVISION_STATUS_SE_LOCKED))) { + if ((0 != (pStatus & PROVISION_STATUS_SE_LOCKED))) { result = true; } - repository.reclaimMemory((short)1); + repository.reclaimMemory((short)2); return result; } private boolean isSeFactoryProvisioningComplete() { - short dIndex = repository.allocReclaimableMemory((short)1); + short dIndex = repository.allocReclaimableMemory((short)2); byte data[] = repository.getHeap(); kmDataStore.getProvisionStatus(data, dIndex); + short pStatus = Util.getShort(data, dIndex); boolean result = false; - if ((0 != (data[dIndex] & INS_PROVISION_RKP_DEVICE_UNIQUE_KEYPAIR_CMD)) - && (0 != ((data[dIndex] & INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD)))) { - result = true; + if ((0 != (pStatus & PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR)) + && (0 != ((pStatus & PROVISION_STATUS_ADDITIONAL_CERT_CHAIN)))) { + result = true; } - repository.reclaimMemory((short)1); + repository.reclaimMemory((short)2); return result; } private void processOEMUnlockProvisionCmd(APDU apdu) { - handleOEMLockUnlockCmd(OEM_UNLOCK_PROVISION_VERIFICATION_LABEL, apdu); + authenticateOEM(OEM_UNLOCK_PROVISION_VERIFICATION_LABEL, apdu); + kmDataStore.setProvisionLock(false); kmDataStore.unlockProvision(PROVISION_STATUS_PROVISIONING_LOCKED); sendError(apdu, KMError.OK); } private void processOEMLockProvisionCmd(APDU apdu) { - handleOEMLockUnlockCmd(OEM_LOCK_PROVISION_VERIFICATION_LABEL, apdu); + authenticateOEM(OEM_LOCK_PROVISION_VERIFICATION_LABEL, apdu); // Enable the lock bit in provision status. + kmDataStore.setProvisionLock(true); kmDataStore.setProvisionStatus(PROVISION_STATUS_PROVISIONING_LOCKED); sendError(apdu, KMError.OK); } - private void handleOEMLockUnlockCmd(byte[] plainMsg, APDU apdu) { + private void authenticateOEM(byte[] plainMsg, APDU apdu) { tmpVariables[0] = KMArray.instance((short) 1); KMArray.cast(tmpVariables[0]).add((short) 0, KMByteBlob.exp()); @@ -507,7 +511,7 @@ private void processGetProvisionStatusCmd(APDU apdu) { kmDataStore.getProvisionStatus(scratchpad, (short) 0); short resp = KMArray.instance((short) 2); KMArray.cast(resp).add((short) 0, buildErrorStatus(KMError.OK)); - KMArray.cast(resp).add((short) 1, KMInteger.uint_8(scratchpad[0])); + KMArray.cast(resp).add((short) 1, KMInteger.instance(scratchpad, (short)0, (short)2)); sendOutgoing(apdu, resp); } @@ -583,43 +587,21 @@ private void processSetBootParamsCmd(APDU apdu) { } private boolean isProvisioningComplete() { - short dInex = repository.allocReclaimableMemory((short)1); - byte data[] = repository.getHeap(); - kmDataStore.getProvisionStatus(data, dInex); - boolean result = false; - if (kmDataStore.isProvisionLocked() || ((0 != (data[dInex] & PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR)) - && (0 != (data[dInex] & PROVISION_STATUS_ADDITIONAL_CERT_CHAIN)) - && (0 != (data[dInex] & PROVISION_STATUS_PRESHARED_SECRET)) - && (0 != (data[dInex] & PROVISION_STATUS_ATTEST_IDS)))) { - result = true; - } - repository.reclaimMemory((short)1); - return result; - } - - private boolean isOemProvisionComplete() { - short dInex = repository.allocReclaimableMemory((short)1); + short dInex = repository.allocReclaimableMemory((short)2); byte data[] = repository.getHeap(); kmDataStore.getProvisionStatus(data, dInex); + short pStatus = Util.getShort(data, dInex); boolean result = false; - if ((0 != (data[dInex] & PROVISION_STATUS_OEM_PUBLIC_KEY)) - && (0 != (data[dInex] & PROVISION_STATUS_SE_LOCKED))) { + if (kmDataStore.isProvisionLocked() || ((0 != (pStatus & PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR)) + && (0 != (pStatus & PROVISION_STATUS_ADDITIONAL_CERT_CHAIN)) + && (0 != (pStatus & PROVISION_STATUS_PRESHARED_SECRET)) + && (0 != (pStatus & PROVISION_STATUS_ATTEST_IDS)))) { result = true; } - repository.reclaimMemory((short)1); + repository.reclaimMemory((short)2); return result; } - private void processLockProvisioningCmd(APDU apdu) { - if (isProvisioningComplete()) { - kmDataStore.setProvisionLocked(); - kmDataStore.setProvisionStatus(PROVISION_STATUS_PROVISIONING_LOCKED); - sendError(apdu, KMError.OK); - } else { - ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); - } - } - private short validateApdu(APDU apdu) { // Read the apdu header and buffer. byte[] apduBuffer = apdu.getBuffer(); diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index 0d50284f..570648ad 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -462,7 +462,6 @@ public void persistAdditionalCertChain(byte[] buf, short offset, short len) { Util.arrayCopyNonAtomic(buf, offset, additionalCertChain, (short) 2, len); JCSystem.commitTransaction(); - } public short getAdditionalCertChainLength() { @@ -749,8 +748,8 @@ public void setBootPatchLevel(byte[] buffer, short start, short length) { Util.arrayCopyNonAtomic(buffer, start, bootPatchLevel, (short) 0, (short) length); } - public void setProvisionLocked() { - writeBoolean(PROVISIONED_LOCKED, true); + public void setProvisionLock(boolean lockValue) { + writeBoolean(PROVISIONED_LOCKED, lockValue); } public boolean isProvisionLocked() { @@ -763,25 +762,28 @@ public boolean isProvisionLocked() { return false; } - public void setProvisionStatus(byte provisionStatus) { - short offset = repository.alloc((short) 1); + public void setProvisionStatus(short provisionStatus) { + short offset = repository.alloc((short) 2); byte[] buf = repository.getHeap(); getProvisionStatus(buf, offset); - buf[offset] |= provisionStatus; - writeDataEntry(PROVISIONED_STATUS, buf, offset, (short) 1); + provisionStatus |= Util.getShort(buf, offset); + Util.setShort(buf, offset, provisionStatus); + writeDataEntry(PROVISIONED_STATUS, buf, offset, (short) 2); } public void getProvisionStatus(byte[] scratchpad, short offset) { - scratchpad[offset] = 0; + Util.setShort(scratchpad, offset, (short)0); readDataEntry(PROVISIONED_STATUS, scratchpad, offset); } - public void unlockProvision(byte unlockOffset) { - short offset = repository.alloc((short) 1); + public void unlockProvision(short unlockOffset) { + short offset = repository.alloc((short) 2); byte[] buf = repository.getHeap(); getProvisionStatus(buf, offset); - buf[offset] &= ~unlockOffset; - writeDataEntry(PROVISIONED_STATUS, buf, offset, (short) 1); + short temp = Util.getShort(buf, offset); + temp &= ~unlockOffset; + Util.setShort(buf, offset, temp); + writeDataEntry(PROVISIONED_STATUS, buf, offset, (short) 2); } public void persistOEMRootPublicKey(byte[] inBuff, short inOffset, short inLength) { @@ -795,6 +797,9 @@ public void persistOEMRootPublicKey(byte[] inBuff, short inOffset, short inLengt } public byte[] getOEMRootPublicKey() { + if(oemRootPublicKey == null) { + KMException.throwIt(KMError.INVALID_DATA); + } return oemRootPublicKey; } diff --git a/ProvisioningTool/src/provision.cpp b/ProvisioningTool/src/provision.cpp index 4587a808..6284f686 100644 --- a/ProvisioningTool/src/provision.cpp +++ b/ProvisioningTool/src/provision.cpp @@ -30,15 +30,17 @@ #define SE_POWER_RESET_STATUS_FLAG (1 << 30) // TODO keymint provision status enum ProvisionStatus { - NOT_PROVISIONED = 0x00, - PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x04, - PROVISION_STATUS_ATTEST_IDS = 0x08, - PROVISION_STATUS_PRESHARED_SECRET = 0x10, - PROVISION_STATUS_PROVISIONING_LOCKED = 0x20, - PROVISION_STATUS_DEVICE_UNIQUE_KEY = 0x40, - PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = 0x80, - PROVISION_STATUS_SE_LOCKED = 0x01, - PROVISION_STATUS_OEM_PUBLIC_KEY = 0x02 + NOT_PROVISIONED = 0x0000, + PROVISION_STATUS_ATTESTATION_KEY = 0x0001, + PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x0002, + PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x0004, + PROVISION_STATUS_ATTEST_IDS = 0x0008, + PROVISION_STATUS_PRESHARED_SECRET = 0x0010, + PROVISION_STATUS_PROVISIONING_LOCKED = 0x0020, + PROVISION_STATUS_DEVICE_UNIQUE_KEY = 0x0040, + PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = 0x0080, + PROVISION_STATUS_SE_LOCKED = 0x0100, + PROVISION_STATUS_OEM_PUBLIC_KEY = 0x0200 }; // TODO keymint provision status and lock From 7dda70169c74bb822dd5b92ab468e73b4cba9000 Mon Sep 17 00:00:00 2001 From: "avinash.hedage" Date: Fri, 3 Jun 2022 20:06:37 +0000 Subject: [PATCH 2/2] updated bug fixes and provision status in RMA support --- .../javacard/keymaster/KMAndroidSEApplet.java | 15 ----------- .../javacard/keymaster/KMKeymasterApplet.java | 13 ++++++++++ .../keymaster/KMKeymintDataStore.java | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index 3f557d0d..adb18e05 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -59,24 +59,9 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis private static final byte INS_PROVISION_OEM_ROOT_PUBLIC_KEY_CMD = INS_KEYMINT_PROVIDER_APDU_START + 10; private static final byte INS_OEM_UNLOCK_PROVISIONING_CMD = INS_KEYMINT_PROVIDER_APDU_START + 11; - private static final byte INS_KEYMINT_PROVIDER_APDU_END = 0x1F; public static final byte BOOT_KEY_MAX_SIZE = 32; public static final byte BOOT_HASH_MAX_SIZE = 32; - - // Provision reporting status - private static final short NOT_PROVISIONED = 0x0000; - private static final short PROVISION_STATUS_ATTESTATION_KEY = 0x0001; - private static final short PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x0002; - private static final short PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x0004; - private static final short PROVISION_STATUS_ATTEST_IDS = 0x0008; - private static final short PROVISION_STATUS_PRESHARED_SECRET = 0x0010; - private static final short PROVISION_STATUS_PROVISIONING_LOCKED = 0x0020; - private static final short PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR = 0x0040; - private static final short PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = 0x0080; - private static final short PROVISION_STATUS_SE_LOCKED = 0x0100; - private static final short PROVISION_STATUS_OEM_PUBLIC_KEY = 0x0200; - public static final short SHARED_SECRET_KEY_SIZE = 32; // Package version. diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 462c42df..74d66f0f 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -266,6 +266,19 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe // Minimum HMAC length in bits public static final short MIN_HMAC_LENGTH_BITS = 64; + // Provision reporting status + public static final short NOT_PROVISIONED = 0x0000; + public static final short PROVISION_STATUS_ATTESTATION_KEY = 0x0001; + public static final short PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x0002; + public static final short PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x0004; + public static final short PROVISION_STATUS_ATTEST_IDS = 0x0008; + public static final short PROVISION_STATUS_PRESHARED_SECRET = 0x0010; + public static final short PROVISION_STATUS_PROVISIONING_LOCKED = 0x0020; + public static final short PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR = 0x0040; + public static final short PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = 0x0080; + public static final short PROVISION_STATUS_SE_LOCKED = 0x0100; + public static final short PROVISION_STATUS_OEM_PUBLIC_KEY = 0x0200; + protected static RemotelyProvisionedComponentDevice rkp; protected static KMEncoder encoder; protected static KMDecoder decoder; diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index 570648ad..3d6760ec 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -866,8 +866,34 @@ public void onRestore(Element element, short oldVersion, short currentVersion) { preSharedKey = (KMPreSharedKey) seProvider.onRestore(element); deviceUniqueKeyPair = (KMDeviceUniqueKeyPair) seProvider.onRestore(element); rkpMacKey = (KMRkpMacKey) seProvider.onRestore(element); + handleDataUpgrade(oldVersion, currentVersion); } + void handleDataUpgrade(short oldVersion, short currentVersion) { + if(oldVersion == 0x0100 && currentVersion == 0x0200) { + handleProvisionStatusUpgrade(); + } + } + + void handleProvisionStatusUpgrade( ){ + short dInex = repository.allocReclaimableMemory((short)2); + byte data[] = repository.getHeap(); + getProvisionStatus(data, dInex); + short newStatus = (short)( data[dInex] & 0x00ff); + if( KMKeymasterApplet.PROVISION_STATUS_PROVISIONING_LOCKED + == (newStatus & KMKeymasterApplet.PROVISION_STATUS_PROVISIONING_LOCKED)) { + newStatus |= KMKeymasterApplet.PROVISION_STATUS_SE_LOCKED; + } + Util.setShort(data, dInex, newStatus); + short pStatusOff = (short) (PROVISIONED_STATUS * DATA_INDEX_ENTRY_SIZE); + JCSystem.beginTransaction(); + Util.setShort(dataTable, (short) (pStatusOff + DATA_INDEX_ENTRY_OFFSET), (short)0); + Util.setShort(dataTable, (short) (pStatusOff + DATA_INDEX_ENTRY_LENGTH), (short)0); + JCSystem.commitTransaction(); + writeDataEntry(PROVISIONED_STATUS, data, dInex, (short) 2); + repository.reclaimMemory((short)2); + } + @Override public short getBackupPrimitiveByteCount() { // dataIndex - 2 bytes