From 0d6509a157f5edb3b14658a656278c3b51a371d7 Mon Sep 17 00:00:00 2001 From: Subrahmanyaman Date: Mon, 22 Aug 2022 20:30:16 +0000 Subject: [PATCH] Introduced a new Provision Command (INS_PROVISION_SECURE_BOOT_MODE_CMD) to provision the secure boot mode status. 1 for enabled, 0 otherwise. This value is returned in the device_info structure in 'fused'property. --- .../javacard/keymaster/KMAndroidSEApplet.java | 28 ++++++++++++- .../javacard/keymaster/KMJCardSimApplet.java | 26 +++++++++++- .../javacard/test/KMFunctionalTest.java | 4 ++ .../android/javacard/test/KMProvision.java | 40 ++++++++++++------- .../javacard/keymaster/KMKeymasterApplet.java | 5 ++- .../keymaster/KMKeymintDataStore.java | 30 ++++++++++++-- .../RemotelyProvisionedComponentDevice.java | 2 +- ProvisioningTool/include/constants.h | 2 + ProvisioningTool/sample_json_keymint_cf.txt | 3 +- ProvisioningTool/sample_json_keymint_gf.txt | 4 +- ProvisioningTool/src/construct_apdus.cpp | 29 ++++++++++++++ ProvisioningTool/src/provision.cpp | 1 + 12 files changed, 148 insertions(+), 26 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index f2ae1c64..2cfd0eb1 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -28,6 +28,7 @@ import javacard.framework.APDU; import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; import javacard.security.CryptoException; @@ -35,7 +36,7 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis // Magic number version private static final byte KM_MAGIC_NUMBER = (byte) 0x82; // MSB byte is for Major version and LSB byte is for Minor version. - private static final short KM_APPLET_PACKAGE_VERSION = 0x0300; + public static final short KM_APPLET_PACKAGE_VERSION = 0x0300; private static final byte KM_BEGIN_STATE = 0x00; private static final byte ILLEGAL_STATE = KM_BEGIN_STATE + 1; @@ -58,6 +59,7 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis INS_KEYMINT_PROVIDER_APDU_START + 13; private static final byte INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD = INS_KEYMINT_PROVIDER_APDU_START + 14; + private static final byte INS_PROVISION_SECURE_BOOT_MODE_CMD = INS_KEYMINT_PROVIDER_APDU_START + 15; private static final byte INS_KEYMINT_PROVIDER_APDU_END = 0x1F; public static final byte BOOT_KEY_MAX_SIZE = 32; @@ -154,6 +156,10 @@ public void process(APDU apdu) { case INS_OEM_UNLOCK_PROVISIONING_CMD: processOEMUnlockProvisionCmd(apdu); break; + + case INS_PROVISION_SECURE_BOOT_MODE_CMD: + processSecureBootCmd(apdu); + break; default: super.process(apdu); @@ -180,6 +186,7 @@ private boolean isCommandAllowed(short apduIns) { switch(apduIns) { case INS_PROVISION_ATTEST_IDS_CMD: case INS_PROVISION_PRESHARED_SECRET_CMD: + case INS_PROVISION_SECURE_BOOT_MODE_CMD: case INS_PROVISION_OEM_ROOT_PUBLIC_KEY_CMD: if(kmDataStore.isProvisionLocked()) { result = false; @@ -245,6 +252,22 @@ private boolean isSeFactoryProvisioningComplete() { return false; } + private void processSecureBootCmd(APDU apdu) { + short argsProto = KMArray.instance((short) 1); + KMArray.cast(argsProto).add((short) 0, KMInteger.exp()); + short args = receiveIncoming(apdu, argsProto); + short val = KMInteger.cast(KMArray.cast(args).get((short) 0)).getShort(); + if (val != 1 && val != 0) { + KMException.throwIt(KMError.INVALID_ARGUMENT); + } + // Store secure boot mode value. + JCSystem.beginTransaction(); + kmDataStore.secureBootMode = (byte) val; + JCSystem.commitTransaction(); + kmDataStore.setProvisionStatus(PROVISION_STATUS_SECURE_BOOT_MODE); + sendResponse(apdu, KMError.OK); + } + private void processOEMUnlockProvisionCmd(APDU apdu) { authenticateOEM(OEM_UNLOCK_PROVISION_VERIFICATION_LABEL, apdu); kmDataStore.unlockProvision(); @@ -505,7 +528,8 @@ private void processGetProvisionStatusCmd(APDU apdu) { private boolean isProvisioningComplete() { short pStatus = kmDataStore.getProvisionStatus(); short pCompleteStatus = PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR | PROVISION_STATUS_ADDITIONAL_CERT_CHAIN | - PROVISION_STATUS_PRESHARED_SECRET | PROVISION_STATUS_ATTEST_IDS | PROVISION_STATUS_OEM_PUBLIC_KEY; + PROVISION_STATUS_PRESHARED_SECRET | PROVISION_STATUS_ATTEST_IDS | PROVISION_STATUS_OEM_PUBLIC_KEY | + PROVISION_STATUS_SECURE_BOOT_MODE; if (kmDataStore.isProvisionLocked() || (pCompleteStatus == (pStatus & pCompleteStatus))) { return true; } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java index 9d4a6bef..fc9d6ae0 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java @@ -21,6 +21,7 @@ import javacard.framework.APDU; import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; import javacard.security.CryptoException; @@ -47,6 +48,7 @@ public class KMJCardSimApplet extends KMKeymasterApplet { INS_KEYMINT_PROVIDER_APDU_START + 13; private static final byte INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD = INS_KEYMINT_PROVIDER_APDU_START + 14; + private static final byte INS_PROVISION_SECURE_BOOT_MODE_CMD = INS_KEYMINT_PROVIDER_APDU_START + 15; private static final byte INS_KEYMINT_PROVIDER_APDU_END = 0x1F; public static final byte BOOT_KEY_MAX_SIZE = 32; @@ -146,6 +148,10 @@ public void process(APDU apdu) { case INS_OEM_UNLOCK_PROVISIONING_CMD: processOEMUnlockProvisionCmd(apdu); break; + + case INS_PROVISION_SECURE_BOOT_MODE_CMD: + processSecureBootCmd(apdu); + break; default: super.process(apdu); @@ -172,6 +178,7 @@ private boolean isCommandAllowed(short apduIns) { switch(apduIns) { case INS_PROVISION_ATTEST_IDS_CMD: case INS_PROVISION_PRESHARED_SECRET_CMD: + case INS_PROVISION_SECURE_BOOT_MODE_CMD: case INS_PROVISION_OEM_ROOT_PUBLIC_KEY_CMD: if(kmDataStore.isProvisionLocked()) { result = false; @@ -238,6 +245,22 @@ private boolean isSeFactoryProvisioningComplete() { return false; } + private void processSecureBootCmd(APDU apdu) { + short argsProto = KMArray.instance((short) 1); + KMArray.cast(argsProto).add((short) 0, KMInteger.exp()); + short args = receiveIncoming(apdu, argsProto); + short val = KMInteger.cast(KMArray.cast(args).get((short) 0)).getShort(); + if (val != 1 && val != 0) { + KMException.throwIt(KMError.INVALID_ARGUMENT); + } + // Store secure boot mode value. + JCSystem.beginTransaction(); + kmDataStore.secureBootMode = (byte) val; + JCSystem.commitTransaction(); + kmDataStore.setProvisionStatus(PROVISION_STATUS_SECURE_BOOT_MODE); + sendResponse(apdu, KMError.OK); + } + private void processOEMUnlockProvisionCmd(APDU apdu) { authenticateOEM(OEM_UNLOCK_PROVISION_VERIFICATION_LABEL, apdu); kmDataStore.unlockProvision(); @@ -561,7 +584,8 @@ private void processSetBootParamsCmd(APDU apdu) { private boolean isProvisioningComplete() { short pStatus = kmDataStore.getProvisionStatus(); short pCompleteStatus = PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR | PROVISION_STATUS_ADDITIONAL_CERT_CHAIN | - PROVISION_STATUS_PRESHARED_SECRET | PROVISION_STATUS_ATTEST_IDS | PROVISION_STATUS_OEM_PUBLIC_KEY; + PROVISION_STATUS_PRESHARED_SECRET | PROVISION_STATUS_ATTEST_IDS | PROVISION_STATUS_OEM_PUBLIC_KEY | + PROVISION_STATUS_SECURE_BOOT_MODE; if (kmDataStore.isProvisionLocked() || (pCompleteStatus == (pStatus & pCompleteStatus))) { return true; } diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java index 7f4922ef..bcc02018 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java @@ -1510,6 +1510,8 @@ public void testVerifyOemUnLockAfterOemLockSuccess() { KMProvision.provisionSeLocked(simulator, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionSharedSecret(simulator, encoder, decoder))); + Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, + KMProvision.provisionSecureBootMode(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionAttestIds(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, @@ -1611,6 +1613,8 @@ public void testVerifyOemProvisionAfterOemLockFailure() { KMProvision.provisionSeLocked(simulator, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionSharedSecret(simulator, encoder, decoder))); + Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, + KMProvision.provisionSecureBootMode(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, KMProvision.provisionAttestIds(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java index d079a14f..daeb3aca 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMProvision.java @@ -40,23 +40,22 @@ public class KMProvision { // Provision Instructions private static final byte INS_KEYMINT_PROVIDER_APDU_START = 0x00; - private static final byte INS_PROVISION_ATTEST_IDS_CMD = INS_KEYMINT_PROVIDER_APDU_START + 1; + private static final byte INS_PROVISION_ATTEST_IDS_CMD = INS_KEYMINT_PROVIDER_APDU_START + 3; private static final byte INS_PROVISION_PRESHARED_SECRET_CMD = - INS_KEYMINT_PROVIDER_APDU_START + 2; - private static final byte INS_OEM_LOCK_PROVISIONING_CMD = INS_KEYMINT_PROVIDER_APDU_START + 3; - private static final byte INS_GET_PROVISION_STATUS_CMD = INS_KEYMINT_PROVIDER_APDU_START + 4; - private static final byte INS_SET_BOOT_PARAMS_CMD = INS_KEYMINT_PROVIDER_APDU_START + 5; + INS_KEYMINT_PROVIDER_APDU_START + 4; + private static final byte INS_SET_BOOT_PARAMS_CMD = INS_KEYMINT_PROVIDER_APDU_START + 5; // Unused + private static final byte INS_OEM_LOCK_PROVISIONING_CMD = INS_KEYMINT_PROVIDER_APDU_START + 6; + private static final byte INS_GET_PROVISION_STATUS_CMD = INS_KEYMINT_PROVIDER_APDU_START + 7; + //0x08 was reserved for INS_INIT_STRONGBOX_CMD + //0x09 was reserved for INS_SET_BOOT_ENDED_CMD earlier. it is unused now. + private static final byte INS_SE_FACTORY_PROVISIONING_LOCK_CMD = INS_KEYMINT_PROVIDER_APDU_START + 10; + private static final byte INS_PROVISION_OEM_ROOT_PUBLIC_KEY_CMD = INS_KEYMINT_PROVIDER_APDU_START + 11; + private static final byte INS_OEM_UNLOCK_PROVISIONING_CMD = INS_KEYMINT_PROVIDER_APDU_START + 12; private static final byte INS_PROVISION_RKP_DEVICE_UNIQUE_KEYPAIR_CMD = - INS_KEYMINT_PROVIDER_APDU_START + 6; + INS_KEYMINT_PROVIDER_APDU_START + 13; private static final byte INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD = - INS_KEYMINT_PROVIDER_APDU_START + 7; - private static final byte INS_SET_BOOT_ENDED_CMD = - INS_KEYMINT_PROVIDER_APDU_START + 8; //unused - private static final byte INS_SE_FACTORY_PROVISIONING_LOCK_CMD = - INS_KEYMINT_PROVIDER_APDU_START + 9; - 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; + INS_KEYMINT_PROVIDER_APDU_START + 14; + private static final byte INS_PROVISION_SECURE_BOOT_MODE_CMD = INS_KEYMINT_PROVIDER_APDU_START + 15; // Top 32 commands are reserved for provisioning. private static final byte INS_END_KM_PROVISION_CMD = 0x20; @@ -303,6 +302,17 @@ public static ResponseAPDU provisionOEMRootPublicKey(CardSimulator simulator, KM return simulator.transmitCommand(apdu); } + public static ResponseAPDU provisionSecureBootMode(CardSimulator simulator, KMEncoder encoder, + KMDecoder decoder) { + short arrPtr = KMArray.instance((short) 1); + KMArray.cast(arrPtr).add((short) 0, KMInteger.uint_8((byte) 0)); + + CommandAPDU apdu = KMTestUtils.encodeApdu(encoder, (byte) INS_PROVISION_SECURE_BOOT_MODE_CMD, + arrPtr); + // print(commandAPDU.getBytes()); + return simulator.transmitCommand(apdu); + } + public static ResponseAPDU provisionSharedSecret(CardSimulator simulator, KMEncoder encoder, KMDecoder decoder) { byte[] sharedKeySecret = { @@ -471,6 +481,8 @@ public static void provisionCmd(CardSimulator simulator, provisionSeLocked(simulator, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, provisionSharedSecret(simulator, encoder, decoder))); + Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, + provisionSecureBootMode(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, provisionAttestIds(simulator, encoder, decoder))); Assert.assertEquals(KMError.OK, KMTestUtils.decodeError(decoder, diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index a5fd857c..da8aa4b7 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -188,8 +188,8 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe private static final byte INS_END_KM_CMD = 0x7F; // Instruction values from 0xCD to 0xFF are completely reserved for Vendors to use and // will never be used by the base line code in future. - private static final byte INS_KM_VENDOR_START_CMD = 0xCD; - private static final byte INS_KM_VENDOR_END_CMD = 0xFF; + private static final byte INS_KM_VENDOR_START_CMD = (byte) 0xCD; + private static final byte INS_KM_VENDOR_END_CMD = (byte) 0xFF; // Data Dictionary items public static final byte DATA_ARRAY_SIZE = 40; @@ -289,6 +289,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe 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; + public static final short PROVISION_STATUS_SECURE_BOOT_MODE = 0x0400; protected static RemotelyProvisionedComponentDevice rkp; protected static KMEncoder encoder; diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index 791b68a5..1fc34dd7 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -33,6 +33,8 @@ public class KMKeymintDataStore implements KMUpgradable { // Data table configuration public static final short KM_APPLET_PACKAGE_VERSION_1 = 0x0100; + public static final short KM_APPLET_PACKAGE_VERSION_2 = 0x0200; + public static final short KM_APPLET_PACKAGE_VERSION_3 = 0x0300; public static final short OLD_DATA_INDEX_SIZE = 19; public static final short DATA_INDEX_SIZE = 17; public static final short DATA_INDEX_ENTRY_SIZE = 4; @@ -106,6 +108,8 @@ public class KMKeymintDataStore implements KMUpgradable { // Challenge for Root of trust private byte[] challenge; + // Secure Boot Mode + public byte secureBootMode; private short dataIndex; private byte[] dataTable; @@ -886,6 +890,7 @@ public byte[] getOEMRootPublicKey() { public void onSave(Element element) { // Prmitives element.write(provisionStatus); + element.write(secureBootMode); // Objects element.write(attIdBrand); element.write(attIdDevice); @@ -912,8 +917,17 @@ public void onRestore(Element element, short oldVersion, short currentVersion) { // 1.0 to 3.0 Upgrade happens here. handlePreviousVersionUpgrade(element); return; + } else if (oldVersion == KM_APPLET_PACKAGE_VERSION_2) { + handleUpgrade(element, oldVersion); + JCSystem.beginTransaction(); + // While upgrading Secure Boot Mode flag from 2.0 to 3.0, implementations + // have to update the secureBootMode with the correct input. + secureBootMode = 0; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_SECURE_BOOT_MODE; + JCSystem.commitTransaction(); + return; } - handleUpgrade(element); + handleUpgrade(element, oldVersion); } private void handlePreviousVersionUpgrade(Element element) { @@ -950,9 +964,12 @@ private void handlePreviousVersionUpgrade(Element element) { handleProvisionStatusUpgrade(oldDataTable, oldDataIndex); } - private void handleUpgrade(Element element) { + private void handleUpgrade(Element element, short oldVersion) { // Read Primitives provisionStatus = element.readShort(); + if (oldVersion >= KM_APPLET_PACKAGE_VERSION_3) { + secureBootMode = element.readByte(); + } // Read Objects attIdBrand = (byte[]) element.readObject(); attIdDevice = (byte[]) element.readObject(); @@ -984,9 +1001,13 @@ void handleProvisionStatusUpgrade(byte[] dataTable, short dataTableIndex){ short pStatus = (short)( data[dInex] & 0x00ff); if( KMKeymasterApplet.PROVISION_STATUS_PROVISIONING_LOCKED == (pStatus & KMKeymasterApplet.PROVISION_STATUS_PROVISIONING_LOCKED)) { - pStatus |= KMKeymasterApplet.PROVISION_STATUS_SE_LOCKED; + pStatus |= KMKeymasterApplet.PROVISION_STATUS_SE_LOCKED + | KMKeymasterApplet.PROVISION_STATUS_SECURE_BOOT_MODE; } JCSystem.beginTransaction(); + // While upgrading Secure Boot Mode flag from 1.0 to 3.0, implementations + // have to update the secureBootMode with the correct input. + secureBootMode = 0; provisionStatus = pStatus; JCSystem.commitTransaction(); repository.reclaimMemory((short)2); @@ -995,7 +1016,8 @@ void handleProvisionStatusUpgrade(byte[] dataTable, short dataTableIndex){ @Override public short getBackupPrimitiveByteCount() { // provisionStatus - 2 bytes - return (short) (2 + + // secureBootMode - 1 byte + return (short) (3 + seProvider.getBackupPrimitiveByteCount(KMDataStoreConstants.INTERFACE_TYPE_MASTER_KEY) + seProvider.getBackupPrimitiveByteCount(KMDataStoreConstants.INTERFACE_TYPE_PRE_SHARED_KEY) + seProvider.getBackupPrimitiveByteCount( KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR) + diff --git a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java index c5229f01..216c9359 100644 --- a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java +++ b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java @@ -879,7 +879,7 @@ private short createDeviceInfo(byte[] scratchpad) { updateItem(rkpTmpVariables, metaOffset, DEVICE_INFO_VERSION, KMInteger.uint_8(DI_SCHEMA_VERSION)); updateItem(rkpTmpVariables, metaOffset, SECURITY_LEVEL, KMTextString.instance(DI_SECURITY_LEVEL, (short) 0, (short) DI_SECURITY_LEVEL.length)); - updateItem(rkpTmpVariables, metaOffset, FUSED, KMInteger.uint_8((byte) 0)); + updateItem(rkpTmpVariables, metaOffset, FUSED, KMInteger.uint_8((byte) storeDataInst.secureBootMode)); // Create device info map. short map = KMMap.instance(rkpTmpVariables[1]); short mapIndex = 0; diff --git a/ProvisioningTool/include/constants.h b/ProvisioningTool/include/constants.h index 89d7413a..4aaf9118 100644 --- a/ProvisioningTool/include/constants.h +++ b/ProvisioningTool/include/constants.h @@ -99,6 +99,7 @@ constexpr char kLockProvision[] = "lock_provision"; constexpr char kOEMRootKey[] = "oem_root_key"; constexpr char kSeFactoryProvisionLock[] = "se_factory_lock"; constexpr char kUnLockProvision[] = "unlock_provision"; +constexpr char kSecureBootMode[] = "secure_boot_mode"; // Instruction constatnts constexpr int kAttestationIdsCmd = INS_BEGIN_KM_CMD + 3; @@ -111,6 +112,7 @@ constexpr int kOemRootPublicKeyCmd = INS_BEGIN_KM_CMD + 11; constexpr int kOemUnLockProvisionCmd = INS_BEGIN_KM_CMD + 12; constexpr int kDeviceUniqueKeyCmd = INS_BEGIN_KM_CMD + 13; constexpr int kAdditionalCertChainCmd = INS_BEGIN_KM_CMD + 14; +constexpr int kSecureBootModeCmd = INS_BEGIN_KM_CMD + 15; diff --git a/ProvisioningTool/sample_json_keymint_cf.txt b/ProvisioningTool/sample_json_keymint_cf.txt index af868d65..f0de686c 100644 --- a/ProvisioningTool/sample_json_keymint_cf.txt +++ b/ProvisioningTool/sample_json_keymint_cf.txt @@ -25,5 +25,6 @@ "test_resources/intermediate_key.der" ] }, - "oem_root_key": "test_resources/oem_root_key.der" + "oem_root_key": "test_resources/oem_root_key.der", + "secure_boot_mode": 0 } diff --git a/ProvisioningTool/sample_json_keymint_gf.txt b/ProvisioningTool/sample_json_keymint_gf.txt index 26c6c4d0..50b10011 100644 --- a/ProvisioningTool/sample_json_keymint_gf.txt +++ b/ProvisioningTool/sample_json_keymint_gf.txt @@ -24,5 +24,7 @@ "test_resources/ca_key.der", "test_resources/intermediate_key.der" ] - } + }, + "oem_root_key": "test_resources/oem_root_key.der", + "secure_boot_mode": 0 } diff --git a/ProvisioningTool/src/construct_apdus.cpp b/ProvisioningTool/src/construct_apdus.cpp index 5b5d50ad..2c101a93 100644 --- a/ProvisioningTool/src/construct_apdus.cpp +++ b/ProvisioningTool/src/construct_apdus.cpp @@ -80,6 +80,7 @@ static int sendOEMAuthenticationToken(const char* toBeSigned, int oemCmd, const static int processOEMFactoryProvisionLock(); static int processOEMFactoryProvisionUnLock(); static int processGetProvisionStatus(); +static int processSecureBootMode(); // Print usage. void usage() { @@ -302,6 +303,7 @@ int processInputFile() { 0 != processOEMFactoryProvisionUnLock() || 0 != processGetProvisionStatus() || 0 != processSEFactoryLock() || + 0 != processSecureBootMode() || 0 != processSetBootParameters()) { return FAILURE; } @@ -581,6 +583,33 @@ int processOEMRootPublicKey() { return SUCCESS; } +int processSecureBootMode() { + //SecureBootMode; + Json::Value secureBootMode = root.get("secure_boot_mode", Json::Value::nullRef); + if (!secureBootMode.isNull()) { + + if (!secureBootMode.isInt()) { + printf("\n Fail: Value for secure boot mode should be string inside the json file\n"); + return FAILURE; + } + int value = secureBootMode.asInt(); + // Construct apdu. + Array array; + array.add(value); + std::vector cborData = array.encode(); + if (SUCCESS != addApduHeader(kSecureBootModeCmd, cborData)) { + return FAILURE; + } + // Write to json. + writerRoot[kSecureBootMode] = getHexString(cborData); + printf("\n Constructed secure boot mode APDU successfully \n"); + + } else { + printf("\n Fail: Improper value for secure boot mode inside the json file\n"); + return FAILURE; + } + return SUCCESS; +} int processAttestationIds() { //AttestIDParams params; diff --git a/ProvisioningTool/src/provision.cpp b/ProvisioningTool/src/provision.cpp index 96472040..9befbab3 100644 --- a/ProvisioningTool/src/provision.cpp +++ b/ProvisioningTool/src/provision.cpp @@ -219,6 +219,7 @@ int processInputFile() { if (!isOEMProvisionLocked(provisionStatus) && ((0 != provisionData(pSocket, kAttestationIds)) || (0 != provisionData(pSocket, kSharedSecret)) || + (0 != provisionData(pSocket, kSecureBootMode)) || (0 != provisionData(pSocket, kOEMRootKey)))) { return FAILURE; }