Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,43 @@ private ResponseAPDU provisionSeLocked(CardSimulator simulator) {
return response;
}

private ResponseAPDU computeSharedSecret(CardSimulator simulator) {
short ret = getHmacSharingParams();
short error = KMInteger.cast(KMArray.cast(ret).get((short) 0)).getShort();
KMHmacSharingParameters params = KMHmacSharingParameters.cast(KMArray.cast(ret).get((short) 1));
short seed = params.getSeed();
short nonce = params.getNonce();

short params1 = KMHmacSharingParameters.instance();
KMHmacSharingParameters.cast(params1).setSeed(KMByteBlob.instance((short) 0));
short num = KMByteBlob.instance((short) 32);
Util.arrayCopyNonAtomic(
KMByteBlob.cast(nonce).getBuffer(),
KMByteBlob.cast(nonce).getStartOff(),
KMByteBlob.cast(num).getBuffer(),
KMByteBlob.cast(num).getStartOff(),
KMByteBlob.cast(num).length());

KMHmacSharingParameters.cast(params1).setNonce(num);
short params2 = KMHmacSharingParameters.instance();
KMHmacSharingParameters.cast(params2).setSeed(KMByteBlob.instance((short) 0));
num = KMByteBlob.instance((short) 32);
cryptoProvider.newRandomNumber(
KMByteBlob.cast(num).getBuffer(),
KMByteBlob.cast(num).getStartOff(),
KMByteBlob.cast(num).length());
KMHmacSharingParameters.cast(params2).setNonce(num);
short arr = KMArray.instance((short) 2);
KMArray.cast(arr).add((short) 0, params1);
KMArray.cast(arr).add((short) 1, params2);
short arrPtr = KMArray.instance((short) 1);
KMArray.cast(arrPtr).add((short) 0, arr);
CommandAPDU apdu = encodeApdu((byte) INS_COMPUTE_SHARED_HMAC_CMD, arrPtr);
// print(commandAPDU.getBytes());
ResponseAPDU response = simulator.transmitCommand(apdu);
return response;
}

private void provisionCmd(CardSimulator simulator) {
Assert.assertEquals(0x9000, provisionSigningKey(simulator).getSW());
Assert.assertEquals(0x9000, provisionSigningCertificate(simulator).getSW());
Expand All @@ -1004,6 +1041,8 @@ private void provisionCmd(CardSimulator simulator) {
setAndroidOSSystemProperties(simulator, (short) OS_VERSION, (short) OS_PATCH_LEVEL,
(short) VENDOR_PATCH_LEVEL);
Assert.assertEquals(0x9000, provisionLocked(simulator).getSW());
// negotiate shared secret.
Assert.assertEquals(0x9000, computeSharedSecret(simulator).getSW());
}

private void cleanUp() {
Expand Down Expand Up @@ -1575,6 +1614,7 @@ public void testRateLimitClearBufferAfterReboot() {
setBootParams(simulator, (short) BOOT_PATCH_LEVEL);
setAndroidOSSystemProperties(simulator, (short) OS_VERSION, (short) OS_PATCH_LEVEL,
(short) VENDOR_PATCH_LEVEL);
computeSharedSecret(simulator);
}
short rsaKeyArr = generateRsaKey(null, null, KMInteger.uint_8((byte) 1));
Assert.assertEquals(KMInteger.cast(KMArray.cast(rsaKeyArr).get((short) 0)).getShort(),
Expand Down Expand Up @@ -3230,6 +3270,7 @@ public void testVerifyOemUnLockAfterOemLockSuccess() {
// set android system properties
setAndroidOSSystemProperties(simulator, (short) OS_VERSION, (short) OS_PATCH_LEVEL,
(short) VENDOR_PATCH_LEVEL);
computeSharedSecret(simulator);
Assert.assertEquals(0x9000, provisionOemUnLock(simulator).getSW());
Assert.assertEquals(0x9000, provisionSharedSecret(simulator).getSW());
Assert.assertEquals(0x9000, provisionAttestIds(simulator).getSW());
Expand Down Expand Up @@ -3339,6 +3380,8 @@ public void testVerifyOemProvisionAfterOemLockFailure() {
Assert.assertEquals(0x9000, provisionAttestIds(simulator).getSW());
Assert.assertEquals(0x9000, provisionOEMRootPublicKey(simulator).getSW());
Assert.assertEquals(0x9000, provisionLocked(simulator).getSW());
// set bootup parameters
setBootParams(simulator, (short) BOOT_PATCH_LEVEL);
ResponseAPDU response = provisionSharedSecret(simulator);
Assert.assertEquals(0x9000, response.getSW());
byte[] respBuf = response.getBytes();
Expand Down Expand Up @@ -3465,6 +3508,7 @@ public void testUpgradeKey() {
setBootParams(simulator, (short) test_data[i][3]);
setAndroidOSSystemProperties(simulator, (short) test_data[i][0], (short) test_data[i][1],
(short) test_data[i][2]);
computeSharedSecret(simulator);
ret = upgradeKey(
KMByteBlob.instance(keyBlob, (short) 0, (short) keyBlob.length),
null, null, test_data[i][5]);
Expand Down
31 changes: 19 additions & 12 deletions Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
// INS_ADD_RNG_ENTROPY_CMD
// INS_COMPUTE_SHARED_HMAC_CMD
// INS_GET_HMAC_SHARING_PARAM_CMD
// INS_EARLY_BOOT_ENDED
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;
Expand Down Expand Up @@ -596,16 +597,6 @@ && isProvisioningComplete())) {
case INS_OEM_UNLOCK_PROVISIONING_CMD:
processOEMUnlockProvisionCmd(apdu);
break;
case INS_PROVISION_ATTEST_IDS_CMD:
case INS_PROVISION_ATTESTATION_KEY_CMD:
case INS_PROVISION_ATTESTATION_CERT_DATA_CMD:
case INS_PROVISION_OEM_ROOT_PUBLIC_KEY_CMD:
case INS_PROVISION_PRESHARED_SECRET_CMD:
case INS_SE_FACTORY_LOCK_PROVISIONING_CMD:
case INS_OEM_LOCK_PROVISIONING_CMD:
// Provision commands are not allowed in ACTIVE_STATE
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
Expand Down Expand Up @@ -642,10 +633,21 @@ private boolean isKeymasterReady(byte apduIns) {
// Keymaster is ready to execute all the commands.
return true;
}
// Below commands are allowed even if the Keymaster is not ready.
switch (apduIns) {
case INS_PROVISION_ATTEST_IDS_CMD:
case INS_PROVISION_ATTESTATION_KEY_CMD:
case INS_PROVISION_ATTESTATION_CERT_DATA_CMD:
case INS_PROVISION_OEM_ROOT_PUBLIC_KEY_CMD:
case INS_PROVISION_PRESHARED_SECRET_CMD:
case INS_SE_FACTORY_LOCK_PROVISIONING_CMD:
case INS_OEM_LOCK_PROVISIONING_CMD:
// Provision commands are not allowed in ACTIVE_STATE
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
break;
// Below commands are allowed even if the Keymaster is not ready.
case INS_GET_HW_INFO_CMD:
case INS_ADD_RNG_ENTROPY_CMD:
case INS_EARLY_BOOT_ENDED_CMD:
case INS_GET_HMAC_SHARING_PARAM_CMD:
case INS_COMPUTE_SHARED_HMAC_CMD:
case INS_SET_VERSION_PATCHLEVEL_CMD:
Expand Down Expand Up @@ -765,7 +767,12 @@ private void processDeviceLockedCmd(APDU apdu) {
data[VERIFICATION_TOKEN] = KMArray.cast(tmpVariables[0]).get((short) 1);
validateVerificationToken(data[VERIFICATION_TOKEN], scratchPad);
short verTime = KMVerificationToken.cast(data[VERIFICATION_TOKEN]).getTimestamp();
short lastDeviceLockedTime = repository.getDeviceTimeStamp();
short lastDeviceLockedTime;
try {
lastDeviceLockedTime = repository.getDeviceTimeStamp();
} catch (KMException e) {
lastDeviceLockedTime = KMInteger.uint_8((byte) 0);
}
if (KMInteger.compare(verTime, lastDeviceLockedTime) > 0) {
Util.arrayFillNonAtomic(scratchPad, (short) 0, KMInteger.UINT_64, (byte) 0);
KMInteger.cast(verTime).getValue(scratchPad, (short) 0, KMInteger.UINT_64);
Expand Down