diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index 115abe41..848eeefd 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -54,7 +54,7 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis 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; + 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; @@ -122,10 +122,6 @@ public void process(APDU apdu) { processSetBootParamsCmd(apdu); break; - case INS_SET_BOOT_ENDED_CMD: - processSetBootEndedCmd(apdu); - break; - case INS_PROVISION_RKP_DEVICE_UNIQUE_KEYPAIR_CMD: processProvisionRkpDeviceUniqueKeyPair(apdu); break; @@ -214,14 +210,13 @@ private boolean isCommandAllowed(short apduIns) { break; case INS_SET_BOOT_PARAMS_CMD: - case INS_SET_BOOT_ENDED_CMD: case INS_GET_PROVISION_STATUS_CMD: break; default: // Allow other commands only if provision is completed. if (!isProvisioningComplete()) { - result = false; + result = false; } } return result; @@ -512,23 +507,13 @@ private void processGetProvisionStatusCmd(APDU apdu) { sendOutgoing(apdu, resp); } - private void processSetBootEndedCmd(APDU apdu) { - if (seProvider.isBootSignalEventSupported() - && (!seProvider.isDeviceRebooted())) { - ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); - } - //set the flag to mark boot ended - kmDataStore.setBootEndedStatus(true); - seProvider.clearDeviceBooted(false); - sendError(apdu, KMError.OK); - } - private void processSetBootParamsCmd(APDU apdu) { if (seProvider.isBootSignalEventSupported() && (!seProvider.isDeviceRebooted())) { ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); } - + // clear the device reboot status + kmDataStore.clearDeviceBootStatus(); short argsProto = KMArray.instance((short) 5); byte[] scratchPad = apdu.getBuffer(); // Array of 4 expected arguments @@ -580,6 +565,8 @@ private void processSetBootParamsCmd(APDU apdu) { kmDataStore.createComputedHmacKey(scratchPad, (short) 0, KMKeymintDataStore.COMPUTED_HMAC_KEY_SIZE); super.reboot(); + kmDataStore.setDeviceBootStatus(KMKeymintDataStore.SET_BOOT_PARAMS_SUCCESS); + seProvider.clearDeviceBooted(false); sendError(apdu, KMError.OK); } @@ -660,9 +647,13 @@ public Element onSave() { private short validateApdu(APDU apdu) { // Read the apdu header and buffer. byte[] apduBuffer = apdu.getBuffer(); - byte apduClass = apduBuffer[ISO7816.OFFSET_CLA]; short P1P2 = Util.getShort(apduBuffer, ISO7816.OFFSET_P1); + // Validate CLA + if (!apdu.isValidCLA()) { + ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); + } + // Validate P1P2. if (P1P2 != KMKeymasterApplet.KM_HAL_VERSION) { sendError(apdu, KMError.INVALID_P1P2); diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java index 66f80148..2b8e55fe 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java @@ -43,29 +43,14 @@ public class KMJCardSimApplet extends KMKeymasterApplet { 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; + 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; - 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. @@ -125,10 +110,6 @@ public void process(APDU apdu) { processSetBootParamsCmd(apdu); break; - case INS_SET_BOOT_ENDED_CMD: - processSetBootEndedCmd(apdu); - break; - case INS_PROVISION_RKP_DEVICE_UNIQUE_KEYPAIR_CMD: processProvisionRkpDeviceUniqueKeyPair(apdu); break; @@ -217,14 +198,13 @@ private boolean isCommandAllowed(short apduIns) { break; case INS_SET_BOOT_PARAMS_CMD: - case INS_SET_BOOT_ENDED_CMD: case INS_GET_PROVISION_STATUS_CMD: break; default: // Allow other commands only if provision is completed. if (!isProvisioningComplete()) { - result = false; + result = false; } } return result; @@ -515,23 +495,13 @@ private void processGetProvisionStatusCmd(APDU apdu) { sendOutgoing(apdu, resp); } - private void processSetBootEndedCmd(APDU apdu) { - if (seProvider.isBootSignalEventSupported() - && (!seProvider.isDeviceRebooted())) { - ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); - } - //set the flag to mark boot ended - kmDataStore.setBootEndedStatus(true); - seProvider.clearDeviceBooted(false); - sendError(apdu, KMError.OK); - } - private void processSetBootParamsCmd(APDU apdu) { if (seProvider.isBootSignalEventSupported() && (!seProvider.isDeviceRebooted())) { ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); } - + // clear the device reboot status + kmDataStore.clearDeviceBootStatus(); short argsProto = KMArray.instance((short) 5); byte[] scratchPad = apdu.getBuffer(); // Array of 4 expected arguments @@ -583,12 +553,14 @@ private void processSetBootParamsCmd(APDU apdu) { kmDataStore.createComputedHmacKey(scratchPad, (short) 0, KMKeymintDataStore.COMPUTED_HMAC_KEY_SIZE); super.reboot(); + kmDataStore.setDeviceBootStatus(KMKeymintDataStore.SET_BOOT_PARAMS_SUCCESS); + seProvider.clearDeviceBooted(false); sendError(apdu, KMError.OK); } private boolean isProvisioningComplete() { - short dInex = repository.allocReclaimableMemory((short)2); - 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; @@ -605,9 +577,15 @@ private boolean isProvisioningComplete() { private short validateApdu(APDU apdu) { // Read the apdu header and buffer. byte[] apduBuffer = apdu.getBuffer(); - byte apduClass = apduBuffer[ISO7816.OFFSET_CLA]; + short apduClass = (short) (apduBuffer[ISO7816.OFFSET_CLA] & 0x00FF); short P1P2 = Util.getShort(apduBuffer, ISO7816.OFFSET_P1); + // Validate CLA. + if (((apduClass & 0x00E0) == 0x0020) || + (apduClass == 0x00FF)) { + ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); + } + // Validate P1P2. if (P1P2 != KMKeymasterApplet.KM_HAL_VERSION) { sendError(apdu, KMError.INVALID_P1P2); diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 74d66f0f..ed51caa0 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -48,7 +48,6 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe public static final short VERIFIED_BOOT_HASH_SIZE = 32; public static final short BOOT_PATCH_LVL_SIZE = 4; - protected static final byte CLA_ISO7816_NO_SM_NO_CHAN = (byte) 0x80; protected static final short KM_HAL_VERSION = (short) 0x5000; private static final short MAX_AUTH_DATA_SIZE = (short) 512; private static final short DERIVE_KEY_INPUT_SIZE = (short) 256; @@ -457,6 +456,9 @@ public void process(APDU apdu) { } byte[] apduBuffer = apdu.getBuffer(); byte apduIns = apduBuffer[ISO7816.OFFSET_INS]; + if (!isKeymintReady(apduIns)) { + ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); + } switch (apduIns) { case INS_INIT_STRONGBOX_CMD: processInitStrongBoxCmd(apdu); @@ -562,6 +564,28 @@ public void process(APDU apdu) { } } + //After every device boot, the Keymaster becomes ready to execute all the commands only after + // 1. boot parameters are set, + // 2. system properties are set and + // 3. computed the shared secret successfully. + private boolean isKeymintReady(byte apduIns) { + if(kmDataStore.isDeviceReady()) { + return true; + } + // Below commands are allowed even if the Keymaster is not ready. + switch (apduIns) { + case INS_GET_HW_INFO_CMD: + case INS_ADD_RNG_ENTROPY_CMD: + case INS_GET_HMAC_SHARING_PARAM_CMD: + case INS_COMPUTE_SHARED_HMAC_CMD: + case INS_INIT_STRONGBOX_CMD: + return true; + default: + break; + } + return false; + } + private void generateUniqueOperationHandle(byte[] buf, short offset, short len) { do { seProvider.newRandomNumber(buf, offset, len); @@ -579,6 +603,7 @@ private void freeOperations() { private void processEarlyBootEndedCmd(APDU apdu) { kmDataStore.setEarlyBootEndedStatus(true); + sendError(apdu, KMError.OK); } private short deviceLockedCmd(APDU apdu){ @@ -1015,6 +1040,7 @@ private void processComputeSharedHmacCmd(APDU apdu) { (short) sharingCheck.length, scratchPad, keyLen); + kmDataStore.setDeviceBootStatus(KMKeymintDataStore.NEGOTIATED_SHARED_SECRET_SUCCESS); // verification signature blob - 32 bytes //tmpVariables[1] short signature = KMByteBlob.instance(scratchPad, keyLen, signLen); @@ -2570,6 +2596,9 @@ private void authorizeAndBeginOperation(KMOperationState op, byte[] scratchPad) authorizeDeviceUnlock(scratchPad); authorizeKeyUsageForCount(scratchPad); + KMTag.assertAbsence(data[HW_PARAMETERS], KMType.BOOL_TAG, KMType.BOOTLOADER_ONLY, + KMError.INVALID_KEY_BLOB); + //Validate early boot //VTS expects error code EARLY_BOOT_ONLY during begin operation if eary boot ended tag is present if (kmDataStore.getEarlyBootEndedStatus()) { @@ -2577,12 +2606,6 @@ private void authorizeAndBeginOperation(KMOperationState op, byte[] scratchPad) KMError.EARLY_BOOT_ENDED); } - //Validate bootloader only - if (kmDataStore.getBootEndedStatus()) { - KMTag.assertAbsence(data[HW_PARAMETERS], KMType.BOOL_TAG, KMType.BOOTLOADER_ONLY, - KMError.INVALID_KEY_BLOB); - } - // Authorize Caller Nonce - if caller nonce absent in key char and nonce present in // key params then fail if it is not a Decrypt operation data[IV] = KMType.INVALID_VALUE; @@ -3422,12 +3445,11 @@ private void processInitStrongBoxCmd(APDU apdu) { setOsVersion(osVersion); setOsPatchLevel(osPatchLevel); setVendorPatchLevel(vendorPatchLevel); + kmDataStore.setDeviceBootStatus(KMKeymintDataStore.SET_SYSTEM_PROPERTIES_SUCCESS); } public void reboot() { kmDataStore.clearHmacNonce(); - //flag to maintain the boot state - kmDataStore.setBootEndedStatus(false); //flag to maintain early boot ended state kmDataStore.setEarlyBootEndedStatus(false); //Clear all the operation state. diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index 3d6760ec..e8dac348 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -49,9 +49,10 @@ public class KMKeymintDataStore implements KMUpgradable { public static final byte DEVICE_LOCKED_TIME = 5; public static final byte DEVICE_LOCKED = 6; public static final byte DEVICE_LOCKED_PASSWORD_ONLY = 7; + // Total 8 auth tags, so the next offset is AUTH_TAG_1 + 8 public static final byte AUTH_TAG_1 = 8; - public static final byte BOOT_ENDED_FLAG = 15; + public static final byte DEVICE_STATUS_FLAG = 15; public static final byte EARLY_BOOT_ENDED_FLAG = 16; private static final byte PROVISIONED_LOCKED = 17; private static final byte PROVISIONED_STATUS = 18; @@ -69,10 +70,23 @@ public class KMKeymintDataStore implements KMUpgradable { public static final short AUTH_TAG_ENTRY_SIZE = (AUTH_TAG_LENGTH + AUTH_TAG_COUNTER_SIZE + 1); private static final short MASTER_KEY_SIZE = 16; 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 BCC_MAX_SIZE = 512; + //Device boot states. Applet starts executing the + // core commands once all the states are set. The commands + // that are allowed irrespective of these states are: + // All the provision commands + // INS_GET_HW_INFO_CMD + // INS_ADD_RNG_ENTROPY_CMD + // INS_COMPUTE_SHARED_HMAC_CMD + // INS_GET_HMAC_SHARING_PARAM_CMD + public static final byte SET_BOOT_PARAMS_SUCCESS = 0x01; + public static final byte SET_SYSTEM_PROPERTIES_SUCCESS = 0x02; + public static final byte NEGOTIATED_SHARED_SECRET_SUCCESS = 0x04; + // Data - originally was in repository private byte[] attIdBrand; private byte[] attIdDevice; @@ -206,32 +220,29 @@ public short getHmacNonce() { public short getOsVersion() { short blob = readData(BOOT_OS_VERSION); - if (blob != KMType.INVALID_VALUE) { - return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); - } else { - return KMInteger.uint_32(zero, (short) 0); + if (blob == KMType.INVALID_VALUE) { + KMException.throwIt(KMError.INVALID_DATA); } + return KMInteger.uint_32( + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } public short getVendorPatchLevel() { short blob = readData(VENDOR_PATCH_LEVEL); - if (blob != KMType.INVALID_VALUE) { - return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); - } else { - return KMInteger.uint_32(zero, (short) 0); + if (blob == KMType.INVALID_VALUE) { + KMException.throwIt(KMError.INVALID_DATA); } + return KMInteger.uint_32( + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } public short getOsPatch() { short blob = readData(BOOT_OS_PATCH_LEVEL); - if (blob != KMType.INVALID_VALUE) { - return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); - } else { - return KMInteger.uint_32(zero, (short) 0); + if (blob == KMType.INVALID_VALUE) { + KMException.throwIt(KMError.INVALID_DATA); } + return KMInteger.uint_32( + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } private boolean readBoolean(short id) { @@ -254,18 +265,13 @@ public boolean getEarlyBootEndedStatus() { return readBoolean(EARLY_BOOT_ENDED_FLAG); } - public boolean getBootEndedStatus() { - return readBoolean(BOOT_ENDED_FLAG); - } - public short getDeviceTimeStamp() { short blob = readData(DEVICE_LOCKED_TIME); - if (blob != KMType.INVALID_VALUE) { - return KMInteger.uint_64(KMByteBlob.cast(blob).getBuffer(), - KMByteBlob.cast(blob).getStartOff()); - } else { - return KMInteger.uint_64(zero, (short) 0); + if (blob == KMType.INVALID_VALUE) { + KMException.throwIt(KMError.INVALID_DATA); } + return KMInteger.uint_64(KMByteBlob.cast(blob).getBuffer(), + KMByteBlob.cast(blob).getStartOff()); } public void setOsVersion(byte[] buf, short start, short len) { @@ -310,9 +316,37 @@ public void setDeviceLockTimestamp(byte[] buf, short start, short len) { public void setEarlyBootEndedStatus(boolean flag) { writeBoolean(EARLY_BOOT_ENDED_FLAG, flag); } - - public void setBootEndedStatus(boolean flag) { - writeBoolean(BOOT_ENDED_FLAG, flag); + + public void clearDeviceBootStatus() { + clearDataEntry(DEVICE_STATUS_FLAG); + } + + public void setDeviceBootStatus(byte initStatus) { + short offset = repository.allocReclaimableMemory(DEVICE_STATUS_FLAG_SIZE); + byte[] buf = repository.getHeap(); + getDeviceBootStatus(buf, offset); + buf[offset] |= initStatus; + writeDataEntry(DEVICE_STATUS_FLAG, buf, offset, DEVICE_STATUS_FLAG_SIZE); + repository.reclaimMemory(DEVICE_STATUS_FLAG_SIZE); + } + + public boolean isDeviceReady() { + boolean result = false; + short offset = repository.allocReclaimableMemory(DEVICE_STATUS_FLAG_SIZE); + byte[] buf = repository.getHeap(); + getDeviceBootStatus(buf, offset); + if ((0 != (buf[offset] & SET_BOOT_PARAMS_SUCCESS)) + && (0 != (buf[offset] & SET_SYSTEM_PROPERTIES_SUCCESS)) + && (0 != (buf[offset] & NEGOTIATED_SHARED_SECRET_SUCCESS))) { + result = true; + } + repository.reclaimMemory(DEVICE_STATUS_FLAG_SIZE); + return result; + } + + public short getDeviceBootStatus(byte[] scratchpad, short offset) { + scratchpad[offset] = 0; + return readDataEntry(DEVICE_STATUS_FLAG, scratchpad, offset); } public void clearDeviceLockTimeStamp() { @@ -512,6 +546,9 @@ public void createPresharedKey(byte[] keyData, short offset, short length) { } public KMPreSharedKey getPresharedKey() { + if (preSharedKey == null) { + KMException.throwIt(KMError.INVALID_DATA); + } return preSharedKey; } @@ -527,6 +564,9 @@ public void createComputedHmacKey(byte[] keyData, short offset, short length) { } public KMComputedHmacKey getComputedHmacKey() { + if (computedHmacKey == null) { + KMException.throwIt(KMError.INVALID_DATA); + } return computedHmacKey; } @@ -571,106 +611,112 @@ public void createRkpMacKey(byte[] keydata, short offset, short length) { } public KMRkpMacKey getRkpMacKey() { - return rkpMacKey; + if (rkpMacKey == null) { + KMException.throwIt(KMError.INVALID_DATA); + } + return rkpMacKey; } public short getAttestationId(short tag, byte[] buffer, short start) { + byte[] attestId = null; switch (tag) { // Attestation Id Brand case KMType.ATTESTATION_ID_BRAND: - Util.arrayCopyNonAtomic(attIdBrand, (short) 0, buffer, start, (short) attIdBrand.length); - return (short) attIdBrand.length; + attestId = attIdBrand; + break; // Attestation Id Device case KMType.ATTESTATION_ID_DEVICE: - Util.arrayCopyNonAtomic(attIdDevice, (short) 0, buffer, start, (short) attIdDevice.length); - return (short) attIdDevice.length; + attestId = attIdDevice; + break; // Attestation Id Product case KMType.ATTESTATION_ID_PRODUCT: - Util.arrayCopyNonAtomic(attIdProduct, (short) 0, buffer, start, - (short) attIdProduct.length); - return (short) attIdProduct.length; + attestId = attIdProduct; + break; // Attestation Id Serial case KMType.ATTESTATION_ID_SERIAL: - Util.arrayCopyNonAtomic(attIdSerial, (short) 0, buffer, start, (short) attIdSerial.length); - return (short) attIdSerial.length; + attestId = attIdSerial; + break; // Attestation Id IMEI case KMType.ATTESTATION_ID_IMEI: - Util.arrayCopyNonAtomic(attIdImei, (short) 0, buffer, start, (short) attIdImei.length); - return (short) attIdImei.length; + attestId = attIdImei; + break; // Attestation Id MEID case KMType.ATTESTATION_ID_MEID: - Util.arrayCopyNonAtomic(attIdMeId, (short) 0, buffer, start, (short) attIdMeId.length); - return (short) attIdMeId.length; + attestId = attIdMeId; + break; // Attestation Id Manufacturer case KMType.ATTESTATION_ID_MANUFACTURER: - Util.arrayCopyNonAtomic(attIdManufacturer, (short) 0, buffer, start, - (short) attIdManufacturer.length); - return (short) attIdManufacturer.length; + attestId = attIdManufacturer; + break; // Attestation Id Model case KMType.ATTESTATION_ID_MODEL: - Util.arrayCopyNonAtomic(attIdModel, (short) 0, buffer, start, (short) attIdModel.length); - return (short) attIdModel.length; + attestId = attIdModel; + break; } - return (short) 0; + if(attestId == null) { + KMException.throwIt(KMError.CANNOT_ATTEST_IDS); + } + Util.arrayCopyNonAtomic(attestId, (short) 0, buffer, start, (short) attestId.length); + return (short) attestId.length; } public void setAttestationId(short tag, byte[] buffer, short start, short length) { switch (tag) { // Attestation Id Brand case KMType.ATTESTATION_ID_BRAND: - JCSystem.beginTransaction(); + JCSystem.beginTransaction(); attIdBrand = new byte[length]; Util.arrayCopyNonAtomic(buffer, (short) start, attIdBrand, (short) 0, length); - JCSystem.commitTransaction(); + JCSystem.commitTransaction(); break; // Attestation Id Device case KMType.ATTESTATION_ID_DEVICE: - JCSystem.beginTransaction(); - attIdDevice = new byte[length]; - Util.arrayCopyNonAtomic(buffer, (short) start, attIdDevice, (short) 0, length); + JCSystem.beginTransaction(); + attIdDevice = new byte[length]; + Util.arrayCopyNonAtomic(buffer, (short) start, attIdDevice, (short) 0, length); JCSystem.commitTransaction(); break; // Attestation Id Product case KMType.ATTESTATION_ID_PRODUCT: - JCSystem.beginTransaction(); - attIdProduct = new byte[length]; - Util.arrayCopyNonAtomic(buffer, (short) start, attIdProduct, (short) 0, length); - JCSystem.commitTransaction(); + JCSystem.beginTransaction(); + attIdProduct = new byte[length]; + Util.arrayCopyNonAtomic(buffer, (short) start, attIdProduct, (short) 0, length); + JCSystem.commitTransaction(); break; // Attestation Id Serial case KMType.ATTESTATION_ID_SERIAL: - JCSystem.beginTransaction(); - attIdSerial = new byte[length]; - Util.arrayCopyNonAtomic(buffer, (short) start, attIdSerial, (short) 0, length); - JCSystem.commitTransaction(); + JCSystem.beginTransaction(); + attIdSerial = new byte[length]; + Util.arrayCopyNonAtomic(buffer, (short) start, attIdSerial, (short) 0, length); + JCSystem.commitTransaction(); break; // Attestation Id IMEI case KMType.ATTESTATION_ID_IMEI: - JCSystem.beginTransaction(); - attIdImei = new byte[length]; - Util.arrayCopyNonAtomic(buffer, (short) start, attIdImei, (short) 0, length); - JCSystem.commitTransaction(); + JCSystem.beginTransaction(); + attIdImei = new byte[length]; + Util.arrayCopyNonAtomic(buffer, (short) start, attIdImei, (short) 0, length); + JCSystem.commitTransaction(); break; // Attestation Id MEID case KMType.ATTESTATION_ID_MEID: - JCSystem.beginTransaction(); - attIdMeId = new byte[length]; - Util.arrayCopyNonAtomic(buffer, (short) start, attIdMeId, (short) 0, length); - JCSystem.commitTransaction(); + JCSystem.beginTransaction(); + attIdMeId = new byte[length]; + Util.arrayCopyNonAtomic(buffer, (short) start, attIdMeId, (short) 0, length); + JCSystem.commitTransaction(); break; // Attestation Id Manufacturer case KMType.ATTESTATION_ID_MANUFACTURER: - JCSystem.beginTransaction(); - attIdManufacturer = new byte[length]; + JCSystem.beginTransaction(); + attIdManufacturer = new byte[length]; Util.arrayCopyNonAtomic(buffer, (short) start, attIdManufacturer, (short) 0, length); JCSystem.commitTransaction(); break; // Attestation Id Model case KMType.ATTESTATION_ID_MODEL: - JCSystem.beginTransaction(); - attIdModel = new byte[length]; - Util.arrayCopyNonAtomic(buffer, (short) start, attIdModel, (short) 0, length); - JCSystem.commitTransaction(); + JCSystem.beginTransaction(); + attIdModel = new byte[length]; + Util.arrayCopyNonAtomic(buffer, (short) start, attIdModel, (short) 0, length); + JCSystem.commitTransaction(); break; } } @@ -687,11 +733,17 @@ public void deleteAttestationIds() { } public short getVerifiedBootHash(byte[] buffer, short start) { + if (verifiedHash == null) { + KMException.throwIt(KMError.INVALID_DATA); + } Util.arrayCopyNonAtomic(verifiedHash, (short) 0, buffer, start, (short) verifiedHash.length); return (short) verifiedHash.length; } public short getBootKey(byte[] buffer, short start) { + if (verifiedHash == null) { + KMException.throwIt(KMError.INVALID_DATA); + } Util.arrayCopyNonAtomic(bootKey, (short) 0, buffer, start, (short) bootKey.length); return (short) bootKey.length; } @@ -705,6 +757,9 @@ public boolean isDeviceBootLocked() { } public short getBootPatchLevel(byte[] buffer, short start) { + if (bootPatchLevel == null) { + KMException.throwIt(KMError.INVALID_DATA); + } Util.arrayCopyNonAtomic(bootPatchLevel, (short) 0, buffer, start, (short) bootPatchLevel.length); return (short) bootPatchLevel.length; @@ -717,7 +772,7 @@ public void setVerifiedBootHash(byte[] buffer, short start, short length) { if (length != 32) { KMException.throwIt(KMError.UNKNOWN_ERROR); } - Util.arrayCopyNonAtomic(buffer, start, verifiedHash, (short) 0, (short) 32); + Util.arrayCopy(buffer, start, verifiedHash, (short) 0, (short) 32); } public void setBootKey(byte[] buffer, short start, short length) { @@ -727,7 +782,7 @@ public void setBootKey(byte[] buffer, short start, short length) { if (length != 32) { KMException.throwIt(KMError.UNKNOWN_ERROR); } - Util.arrayCopyNonAtomic(buffer, start, bootKey, (short) 0, (short) 32); + Util.arrayCopy(buffer, start, bootKey, (short) 0, (short) 32); } public void setBootState(short state) { @@ -745,7 +800,7 @@ public void setBootPatchLevel(byte[] buffer, short start, short length) { if (length > 4 || length < 0) { KMException.throwIt(KMError.UNKNOWN_ERROR); } - Util.arrayCopyNonAtomic(buffer, start, bootPatchLevel, (short) 0, (short) length); + Util.arrayCopy(buffer, start, bootPatchLevel, (short) 0, (short) length); } public void setProvisionLock(boolean lockValue) { @@ -802,7 +857,7 @@ public byte[] getOEMRootPublicKey() { } return oemRootPublicKey; } - + @Override public void onSave(Element element) { // Prmitives @@ -875,7 +930,7 @@ void handleDataUpgrade(short oldVersion, short currentVersion) { } } - void handleProvisionStatusUpgrade( ){ + void handleProvisionStatusUpgrade(){ short dInex = repository.allocReclaimableMemory((short)2); byte data[] = repository.getHeap(); getProvisionStatus(data, dInex); diff --git a/HAL/JavacardSecureElement.cpp b/HAL/JavacardSecureElement.cpp index 252131da..0b5cef82 100644 --- a/HAL/JavacardSecureElement.cpp +++ b/HAL/JavacardSecureElement.cpp @@ -37,7 +37,7 @@ keymaster_error_t JavacardSecureElement::initializeJavacard() { request.add(Uint(getOsVersion())); request.add(Uint(getOsPatchlevel())); request.add(Uint(getVendorPatchlevel())); - auto [item, err] = sendRequest(Instruction::INS_SET_BOOT_PARAMS_CMD, request); + auto [item, err] = sendRequest(Instruction::INS_INIT_STRONGBOX_CMD, request); return err; } diff --git a/HAL/JavacardSecureElement.h b/HAL/JavacardSecureElement.h index 160d3d4d..d483a2d2 100644 --- a/HAL/JavacardSecureElement.h +++ b/HAL/JavacardSecureElement.h @@ -59,7 +59,7 @@ enum class Instruction { INS_UPDATE_AAD_OPERATION_CMD = KEYMINT_CMD_APDU_START + 23, INS_BEGIN_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 24, INS_FINISH_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 25, - INS_SET_BOOT_PARAMS_CMD = KEYMINT_CMD_APDU_START + 26, + INS_INIT_STRONGBOX_CMD = KEYMINT_CMD_APDU_START + 26, // RKP Commands INS_GET_RKP_HARDWARE_INFO = KEYMINT_CMD_APDU_START + 27, INS_GENERATE_RKP_KEY_CMD = KEYMINT_CMD_APDU_START + 28, diff --git a/HAL/JavacardSharedSecret.cpp b/HAL/JavacardSharedSecret.cpp index a779c1ad..d6fd0541 100644 --- a/HAL/JavacardSharedSecret.cpp +++ b/HAL/JavacardSharedSecret.cpp @@ -12,10 +12,14 @@ using std::shared_ptr; using std::vector; ScopedAStatus JavacardSharedSecret::getSharedSecretParameters(SharedSecretParameters* params) { - card_->initializeJavacard(); + auto error = card_->initializeJavacard(); + if(error != KM_ERROR_OK) { + LOG(ERROR) << "Error in initializing javacard."; + return km_utils::kmError2ScopedAStatus(error); + } auto [item, err] = card_->sendRequest(Instruction::INS_GET_SHARED_SECRET_PARAM_CMD); if (err != KM_ERROR_OK) { - LOG(ERROR) << "Error in sending in getSharedSecretParameters.!!!!!!!!!!!!!!!"; + LOG(ERROR) << "Error in sending in getSharedSecretParameters."; return km_utils::kmError2ScopedAStatus(err); } if (!cbor_.getSharedSecretParameters(item, 1, *params)) { @@ -29,7 +33,11 @@ ScopedAStatus JavacardSharedSecret::computeSharedSecret(const std::vector& params, std::vector* secret) { - card_->initializeJavacard(); + auto error = card_->initializeJavacard(); + if(error != KM_ERROR_OK) { + LOG(ERROR) << "Error in initializing javacard."; + return km_utils::kmError2ScopedAStatus(error); + } cppbor::Array request; cbor_.addSharedSecretParameters(request, params); auto [item, err] = card_->sendRequest(Instruction::INS_COMPUTE_SHARED_SECRET_CMD, request);