diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index 10094e4e..c50065ee 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -20,7 +20,7 @@ import org.globalplatform.upgrade.UpgradeManager; import com.android.javacard.seprovider.KMAndroidSEProvider; -import com.android.javacard.seprovider.KMDeviceUniqueKey; +import com.android.javacard.seprovider.KMDeviceUniqueKeyPair; import com.android.javacard.seprovider.KMError; import com.android.javacard.seprovider.KMException; import com.android.javacard.seprovider.KMType; @@ -35,7 +35,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 CURRENT_PACKAGE_VERSION = 0x0009; // 0.9 + private static final short CURRENT_PACKAGE_VERSION = 0x0100; private static final byte KM_BEGIN_STATE = 0x00; private static final byte ILLEGAL_STATE = KM_BEGIN_STATE + 1; @@ -49,9 +49,9 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis private static final byte INS_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; - private static final byte INS_PROVISION_DEVICE_UNIQUE_KEY_CMD = + private static final byte INS_PROVISION_RKP_UNIQUE_DEVICE_KEYPAIR_CMD = INS_KEYMINT_PROVIDER_APDU_START + 6; - private static final byte INS_PROVISION_ADDITIONAL_CERT_CHAIN_CMD = + 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; @@ -68,7 +68,7 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis 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_KEY = 0x40; + private static final byte PROVISION_STATUS_UNIQUE_DEVICE_KEYPAIR = 0x40; private static final byte PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = (byte) 0x80; public static final short SHARED_SECRET_KEY_SIZE = 32; @@ -159,11 +159,11 @@ public void process(APDU apdu) { processSetBootParamsCmd(apdu); break; - case INS_PROVISION_DEVICE_UNIQUE_KEY_CMD: - processProvisionDeviceUniqueKey(apdu); + case INS_PROVISION_RKP_UNIQUE_DEVICE_KEYPAIR_CMD: + processProvisionDeviceUniqueKeyPair(apdu); break; - case INS_PROVISION_ADDITIONAL_CERT_CHAIN_CMD: + case INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD: processProvisionAdditionalCertChain(apdu); break; @@ -189,7 +189,7 @@ public void process(APDU apdu) { } } - private static void processProvisionDeviceUniqueKey(APDU apdu) { + private static void processProvisionDeviceUniqueKeyPair(APDU apdu) { // Re-purpose the apdu buffer as scratch pad. byte[] scratchPad = apdu.getBuffer(); short arr = KMArray.instance((short) 1); @@ -201,13 +201,13 @@ private static void processProvisionDeviceUniqueKey(APDU apdu) { short pubKeyLen = KMCoseKey.cast(coseKey).getEcdsa256PublicKey(scratchPad, (short) 0); short privKeyLen = KMCoseKey.cast(coseKey).getPrivateKey(scratchPad, pubKeyLen); //Store the Device unique Key. - kmDataStore.createDeviceUniqueKey(scratchPad, (short) 0, pubKeyLen, scratchPad, + kmDataStore.createDeviceUniqueKeyPair(scratchPad, (short) 0, pubKeyLen, scratchPad, pubKeyLen, privKeyLen); short bcc = generateBcc(false, scratchPad); short len = KMKeymasterApplet.encodeToApduBuffer(bcc, scratchPad, (short) 0, MAX_COSE_BUF_SIZE); kmDataStore.persistBootCertificateChain(scratchPad, (short) 0, len); - kmDataStore.setProvisionStatus(PROVISION_STATUS_DEVICE_UNIQUE_KEY); + kmDataStore.setProvisionStatus(PROVISION_STATUS_UNIQUE_DEVICE_KEYPAIR); sendError(apdu, KMError.OK); } @@ -244,7 +244,7 @@ private static void processProvisionAdditionalCertChain(APDU apdu) { srcBuffer, null); // Compare the DK_Pub. short pubKeyLen = KMCoseKey.cast(leafCoseKey).getEcdsa256PublicKey(srcBuffer, (short) 0); - KMDeviceUniqueKey uniqueKey = kmDataStore.getDeviceUniqueKey(false); + KMDeviceUniqueKeyPair uniqueKey = kmDataStore.getDeviceUniqueKeyPair(false); if (uniqueKey == null) { KMException.throwIt(KMError.STATUS_FAILED); } @@ -408,7 +408,7 @@ private boolean isProvisioningComplete() { byte data[] = repository.getHeap(); kmDataStore.getProvisionStatus(data, dInex); boolean result = false; - if ((0 != (data[dInex] & PROVISION_STATUS_DEVICE_UNIQUE_KEY)) + if ((0 != (data[dInex] & PROVISION_STATUS_UNIQUE_DEVICE_KEYPAIR)) && (0 != (data[dInex] & PROVISION_STATUS_ADDITIONAL_CERT_CHAIN)) && (0 != (data[dInex] & PROVISION_STATUS_PRESHARED_SECRET))) { result = true; diff --git a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java index 015a1c09..12a6cbc2 100644 --- a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java @@ -1090,7 +1090,7 @@ public boolean ecVerify256(byte[] pubKey, short pubKeyOffset, short pubKeyLen, } @Override - public short ecSign256(KMDeviceUniqueKey ecPrivKey, byte[] inputDataBuf, + public short ecSign256(KMDeviceUniqueKeyPair ecPrivKey, byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] outputDataBuf, short outputDataStart) { Signature.OneShot signer = null; @@ -1108,7 +1108,7 @@ public short ecSign256(KMDeviceUniqueKey ecPrivKey, byte[] inputDataBuf, } @Override - public KMDeviceUniqueKey createDeviceUniqueKey(KMDeviceUniqueKey key, + public KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(KMDeviceUniqueKeyPair key, byte[] pubKey, short pubKeyOff, short pubKeyLen, byte[] privKey, short privKeyOff, short privKeyLen) { if (key == null) { @@ -1118,7 +1118,7 @@ public KMDeviceUniqueKey createDeviceUniqueKey(KMDeviceUniqueKey key, } ((KMECDeviceUniqueKey) key).setS(privKey, privKeyOff, privKeyLen); ((KMECDeviceUniqueKey) key).setW(pubKey, pubKeyOff, pubKeyLen); - return (KMDeviceUniqueKey) key; + return (KMDeviceUniqueKeyPair) key; } @Override @@ -1182,7 +1182,7 @@ public void onSave(Element element, byte interfaceType, Object object) { case KMDataStoreConstants.INTERFACE_TYPE_ATTESTATION_KEY: KMECPrivateKey.onSave(element, (KMECPrivateKey) object); break; - case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY: + case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR: KMECDeviceUniqueKey.onSave(element, (KMECDeviceUniqueKey) object); break; case KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY: @@ -1208,7 +1208,7 @@ public Object onResore(Element element) { return KMHmacKey.onRestore((HMACKey) element.readObject()); case KMDataStoreConstants.INTERFACE_TYPE_ATTESTATION_KEY: return KMECPrivateKey.onRestore((KeyPair) element.readObject()); - case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY: + case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR: return KMECDeviceUniqueKey.onRestore((KeyPair) element.readObject()); case KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY: return KMHmacKey.onRestore((HMACKey) element.readObject()); @@ -1234,7 +1234,7 @@ public short getBackupPrimitiveByteCount(byte interfaceType) { case KMDataStoreConstants.INTERFACE_TYPE_ATTESTATION_KEY: primitiveCount += KMECPrivateKey.getBackupPrimitiveByteCount(); break; - case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY: + case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR: primitiveCount += KMECDeviceUniqueKey.getBackupPrimitiveByteCount(); break; case KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY: @@ -1257,7 +1257,7 @@ public short getBackupObjectCount(byte interfaceType) { return KMHmacKey.getBackupObjectCount(); case KMDataStoreConstants.INTERFACE_TYPE_ATTESTATION_KEY: return KMECPrivateKey.getBackupObjectCount(); - case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY: + case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR: return KMECDeviceUniqueKey.getBackupObjectCount(); case KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY: return KMHmacKey.getBackupObjectCount(); diff --git a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDataStoreConstants.java b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDataStoreConstants.java index 31917a75..feb7d170 100644 --- a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDataStoreConstants.java +++ b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDataStoreConstants.java @@ -4,7 +4,7 @@ public class KMDataStoreConstants { // INTERFACE Types public static final byte INTERFACE_TYPE_COMPUTED_HMAC_KEY = 0x01; public static final byte INTERFACE_TYPE_ATTESTATION_KEY = 0x02; - public static final byte INTERFACE_TYPE_DEVICE_UNIQUE_KEY = 0x03; + public static final byte INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR = 0x03; public static final byte INTERFACE_TYPE_MASTER_KEY = 0x04; public static final byte INTERFACE_TYPE_PRE_SHARED_KEY = 0x05; public static final byte INTERFACE_TYPE_RKP_MAC_KEY = 0x06; diff --git a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECDeviceUniqueKey.java b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECDeviceUniqueKey.java index f7a96100..1c512a5c 100644 --- a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECDeviceUniqueKey.java +++ b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECDeviceUniqueKey.java @@ -20,7 +20,7 @@ import javacard.security.ECPublicKey; import javacard.security.KeyPair; -public class KMECDeviceUniqueKey implements KMDeviceUniqueKey { +public class KMECDeviceUniqueKey implements KMDeviceUniqueKeyPair { private KeyPair ecKeyPair; diff --git a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java index 4d4570b6..1fe1467a 100644 --- a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java +++ b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java @@ -479,7 +479,7 @@ boolean ecVerify256( * @return length of the decrypted data. */ short ecSign256( - KMDeviceUniqueKey ecPrivKey, + KMDeviceUniqueKeyPair ecPrivKey, byte[] inputDataBuf, short inputDataStart, short inputDataLength, @@ -626,7 +626,7 @@ KMOperation initAsymmetricOperation( * @param privKeyLen private key buffer length. * @return instance of KMDeviceUniqueKey. */ - KMDeviceUniqueKey createDeviceUniqueKey(KMDeviceUniqueKey key, + KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(KMDeviceUniqueKeyPair key, byte[] pubKey, short pubKeyOff, short pubKeyLen, byte[] privKey, short privKeyOff, short privKeyLen); diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 56105fdf..c335bca0 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -17,7 +17,7 @@ package com.android.javacard.keymaster; import com.android.javacard.seprovider.KMAttestationCert; -import com.android.javacard.seprovider.KMDeviceUniqueKey; +import com.android.javacard.seprovider.KMDeviceUniqueKeyPair; import com.android.javacard.seprovider.KMException; import com.android.javacard.seprovider.KMHmacKey; import com.android.javacard.seprovider.KMSEProvider; @@ -1221,26 +1221,23 @@ private KMAttestationCert makeCommonCert(byte[] scratchPad) { } - private KMAttestationCert makeAttestationCert(short attKeyBlob, short attKeyParam, - short attChallenge, short issuer, short hwParameters, short swParameters, byte[] scratchPad) { + private KMAttestationCert makeAttestationCert(short attKeyBlob, short attKeyParam, short attChallenge, short issuer, + short hwParameters, short swParameters, byte[] scratchPad) { KMAttestationCert cert = makeCommonCert(scratchPad); // App Id and App Data, short appId = KMType.INVALID_VALUE; short appData = KMType.INVALID_VALUE; - if(attKeyParam != KMType.INVALID_VALUE) { - appId = - KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.APPLICATION_ID, attKeyParam); + if (attKeyParam != KMType.INVALID_VALUE) { + appId = KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.APPLICATION_ID, attKeyParam); if (appId != KMTag.INVALID_VALUE) { appId = KMByteTag.cast(appId).getValue(); } - appData = - KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.APPLICATION_DATA, attKeyParam); + appData = KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.APPLICATION_DATA, attKeyParam); if (appData != KMTag.INVALID_VALUE) { appData = KMByteTag.cast(appData).getValue(); } } - //TODO remove following line short origBlob = data[KEY_BLOB]; short pubKey = data[PUB_KEY]; short privKey = data[SECRET]; @@ -1248,8 +1245,7 @@ private KMAttestationCert makeAttestationCert(short attKeyBlob, short attKeyPara short attestationKeySecret = KMArray.cast(keyBlob).get(KEY_BLOB_SECRET); short attestParam = KMArray.cast(keyBlob).get(KEY_BLOB_PARAMS); attestParam = KMKeyCharacteristics.cast(attestParam).getStrongboxEnforced(); - short attKeyPurpose = - KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PURPOSE, attestParam); + short attKeyPurpose = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PURPOSE, attestParam); // If the attest key's purpose is not "attest key" then error. if (!KMEnumArrayTag.cast(attKeyPurpose).contains(KMType.ATTEST_KEY)) { KMException.throwIt(KMError.INCOMPATIBLE_PURPOSE); @@ -1260,45 +1256,43 @@ private KMAttestationCert makeAttestationCert(short attKeyBlob, short attKeyPara } short alg = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, attestParam); - if(KMEnumTag.cast(alg).getValue() == KMType.RSA) { + if (KMEnumTag.cast(alg).getValue() == KMType.RSA) { short attestationKeyPublic = KMArray.cast(keyBlob).get(KEY_BLOB_PUB_KEY); cert.rsaAttestKey(attestationKeySecret, attestationKeyPublic, KMType.ATTESTATION_CERT); - }else{ + } else { cert.ecAttestKey(attestationKeySecret, KMType.ATTESTATION_CERT); } cert.attestationChallenge(attChallenge); cert.issuer(issuer); - //TODO remove following line data[PUB_KEY] = pubKey; + data[SECRET] = privKey; + data[KEY_BLOB] = origBlob; cert.publicKey(data[PUB_KEY]); // Save attestation application id - must be present. - short attAppId = - KMKeyParameters.findTag( KMType.BYTES_TAG, KMType.ATTESTATION_APPLICATION_ID, data[KEY_PARAMETERS]); - if (attAppId == KMType.INVALID_VALUE) { - KMException.throwIt(KMError.ATTESTATION_APPLICATION_ID_MISSING); - } - cert.extensionTag(attAppId, false); - // unique id byte blob - uses application id and temporal month count of creation time. - setUniqueId(cert, scratchPad); - // Add Attestation Ids if present - addAttestationIds(cert, scratchPad); - - // Add Tags - addTags(hwParameters, true, cert); - addTags(swParameters, false, cert); - // Add Device Boot locked status - cert.deviceLocked(kmDataStore.isDeviceBootLocked()); - // VB data - cert.verifiedBootHash(getVerifiedBootHash(scratchPad)); - cert.verifiedBootKey(getBootKey(scratchPad)); - cert.verifiedBootState((byte)kmDataStore.getBootState()); - - //TODO remove the following line + short attAppId = KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.ATTESTATION_APPLICATION_ID, data[KEY_PARAMETERS]); + if (attAppId == KMType.INVALID_VALUE) { + KMException.throwIt(KMError.ATTESTATION_APPLICATION_ID_MISSING); + } + cert.extensionTag(attAppId, false); + // unique id byte blob - uses application id and temporal month count of + // creation time. + setUniqueId(cert, scratchPad); + // Add Attestation Ids if present + addAttestationIds(cert, scratchPad); + + // Add Tags + addTags(hwParameters, true, cert); + addTags(swParameters, false, cert); + // Add Device Boot locked status + cert.deviceLocked(kmDataStore.isDeviceBootLocked()); + // VB data + cert.verifiedBootHash(getVerifiedBootHash(scratchPad)); + cert.verifiedBootKey(getBootKey(scratchPad)); + cert.verifiedBootState((byte) kmDataStore.getBootState()); + + // TODO remove the following line makeKeyCharacteristics(scratchPad); - data[SECRET] = privKey; - data[KEY_BLOB] = origBlob; - return cert; } @@ -3455,45 +3449,6 @@ private void generateAttestation(short attKeyBlob, short attKeyParam, byte[] sc // Initialize the certificate as array of blob data[CERTIFICATE] = KMArray.instance((short)1); KMArray.cast(data[CERTIFICATE]).add((short)0, certData); - -/* - boolean rsaCert = KMEnumTag.cast(alg).getValue() == KMType.EC; - short appId = KMType.INVALID_VALUE; - short appData = KMType.INVALID_VALUE; - if(attKeyParam != KMType.INVALID_VALUE) { - appId = - KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.APPLICATION_ID, attKeyParam); - if (appId != KMTag.INVALID_VALUE) { - appId = KMByteTag.cast(appId).getValue(); - } - appData = - KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.APPLICATION_DATA, attKeyParam); - if (appData != KMTag.INVALID_VALUE) { - appData = KMByteTag.cast(appData).getValue(); - } - } - - KMAttestationCert cert = makeCert(attKeyBlob, appId, appData, scratchPad); - if(cert == null) {// No certificate - data[CERTIFICATE] = KMArray.instance((short)0); - return; - } - - // Allocate memory - short certData = KMByteBlob.instance(MAX_CERT_SIZE); - cert.buffer(KMByteBlob.cast(certData).getBuffer(), - KMByteBlob.cast(certData).getStartOff(), - KMByteBlob.cast(certData).length()); - // Build the certificate - this will sign the cert - cert.build(); - // Adjust the start and length of the certificate in the blob - KMByteBlob.cast(certData).setStartOff(cert.getCertStart()); - KMByteBlob.cast(certData).setLength(cert.getCertLength()); - - // Initialize the certificate as array of blob - data[CERTIFICATE] = KMArray.instance((short)1); - KMArray.cast(data[CERTIFICATE]).add((short)0, certData); - */ } /** @@ -4100,7 +4055,7 @@ public static short generateBcc(boolean testMode, byte[] scratchPad) { if (!testMode && kmDataStore.isProvisionLocked()) { KMException.throwIt(KMError.STATUS_FAILED); } - KMDeviceUniqueKey deviceUniqueKey = kmDataStore.getDeviceUniqueKey(testMode); + KMDeviceUniqueKeyPair deviceUniqueKey = kmDataStore.getDeviceUniqueKeyPair(testMode); short temp = deviceUniqueKey.getPublicKey(scratchPad, (short) 0); short coseKey = KMCose.constructCoseKey( diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index f098537b..5f643ba5 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -6,7 +6,7 @@ import com.android.javacard.seprovider.KMAttestationKey; import com.android.javacard.seprovider.KMComputedHmacKey; import com.android.javacard.seprovider.KMDataStoreConstants; -import com.android.javacard.seprovider.KMDeviceUniqueKey; +import com.android.javacard.seprovider.KMDeviceUniqueKeyPair; import com.android.javacard.seprovider.KMECDeviceUniqueKey; import com.android.javacard.seprovider.KMECPrivateKey; import com.android.javacard.seprovider.KMError; @@ -97,8 +97,8 @@ public class KMKeymintDataStore implements KMUpgradable { private byte[] additionalCertChain; private byte[] bcc; private KMMasterKey masterKey; - private KMDeviceUniqueKey testDeviceUniqueKey; - private KMDeviceUniqueKey deviceUniqueKey; + private KMDeviceUniqueKeyPair testDeviceUniqueKeyPair; + private KMDeviceUniqueKeyPair deviceUniqueKeyPair; private KMPreSharedKey preSharedKey; private KMComputedHmacKey computedHmacKey; private KMRkpMacKey rkpMacKey; @@ -530,36 +530,36 @@ public KMComputedHmacKey getComputedHmacKey() { return computedHmacKey; } - public KMDeviceUniqueKey createTestDeviceUniqueKey(byte[] pubKey, short pubKeyOff, short pubKeyLen, + public KMDeviceUniqueKeyPair createTestDeviceUniqueKeyPair(byte[] pubKey, short pubKeyOff, short pubKeyLen, byte[] privKey, short privKeyOff, short privKeyLen) { - if (testDeviceUniqueKey == null) { - testDeviceUniqueKey = seProvider.createDeviceUniqueKey(testDeviceUniqueKey, pubKey, pubKeyOff, + if (testDeviceUniqueKeyPair == null) { + testDeviceUniqueKeyPair = seProvider.createDeviceUniqueKeyPair(testDeviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, privKeyOff, privKeyLen); } else { - seProvider.createDeviceUniqueKey(testDeviceUniqueKey, pubKey, pubKeyOff, pubKeyLen, privKey, + seProvider.createDeviceUniqueKeyPair(testDeviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, privKeyOff, privKeyLen); } - return testDeviceUniqueKey; + return testDeviceUniqueKeyPair; } - public KMDeviceUniqueKey createDeviceUniqueKey(byte[] pubKey, short pubKeyOff, short pubKeyLen, + public KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(byte[] pubKey, short pubKeyOff, short pubKeyLen, byte[] privKey, short privKeyOff, short privKeyLen) { - if (deviceUniqueKey == null) { - deviceUniqueKey = seProvider.createDeviceUniqueKey(deviceUniqueKey, pubKey, pubKeyOff, + if (deviceUniqueKeyPair == null) { + deviceUniqueKeyPair = seProvider.createDeviceUniqueKeyPair(deviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, privKeyOff, privKeyLen); } else { - seProvider.createDeviceUniqueKey(deviceUniqueKey, pubKey, pubKeyOff, pubKeyLen, privKey, + seProvider.createDeviceUniqueKeyPair(deviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, privKeyOff, privKeyLen); } - return deviceUniqueKey; + return deviceUniqueKeyPair; } - public KMDeviceUniqueKey getDeviceUniqueKey(boolean testMode) { - return ((KMDeviceUniqueKey) (testMode ? testDeviceUniqueKey : deviceUniqueKey)); + public KMDeviceUniqueKeyPair getDeviceUniqueKeyPair(boolean testMode) { + return ((KMDeviceUniqueKeyPair) (testMode ? testDeviceUniqueKeyPair : deviceUniqueKeyPair)); } public void createRkpMacKey(byte[] keydata, short offset, short length) { @@ -801,7 +801,7 @@ public void onSave(Element element) { seProvider.onSave(element, KMDataStoreConstants.INTERFACE_TYPE_COMPUTED_HMAC_KEY, computedHmacKey); seProvider.onSave(element, KMDataStoreConstants.INTERFACE_TYPE_PRE_SHARED_KEY, preSharedKey); - seProvider.onSave(element, KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY, deviceUniqueKey); + seProvider.onSave(element, KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR, deviceUniqueKeyPair); seProvider.onSave(element, KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY, rkpMacKey); } @@ -830,7 +830,7 @@ public void onRestore(Element element) { masterKey = (KMMasterKey) seProvider.onResore(element); computedHmacKey = (KMComputedHmacKey) seProvider.onResore(element); preSharedKey = (KMPreSharedKey) seProvider.onResore(element); - deviceUniqueKey = (KMDeviceUniqueKey) seProvider.onResore(element); + deviceUniqueKeyPair = (KMDeviceUniqueKeyPair) seProvider.onResore(element); rkpMacKey = (KMRkpMacKey) seProvider.onResore(element); } @@ -844,7 +844,7 @@ public short getBackupPrimitiveByteCount() { seProvider.getBackupPrimitiveByteCount( KMDataStoreConstants.INTERFACE_TYPE_COMPUTED_HMAC_KEY) + seProvider.getBackupPrimitiveByteCount(KMDataStoreConstants.INTERFACE_TYPE_PRE_SHARED_KEY) + - seProvider.getBackupPrimitiveByteCount( KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY) + + seProvider.getBackupPrimitiveByteCount( KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR) + seProvider.getBackupPrimitiveByteCount(KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY)); } @@ -859,7 +859,7 @@ public short getBackupObjectCount() { seProvider.getBackupObjectCount(KMDataStoreConstants.INTERFACE_TYPE_COMPUTED_HMAC_KEY) + seProvider.getBackupObjectCount(KMDataStoreConstants.INTERFACE_TYPE_MASTER_KEY) + seProvider.getBackupObjectCount(KMDataStoreConstants.INTERFACE_TYPE_PRE_SHARED_KEY) + - seProvider.getBackupObjectCount(KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY) + + seProvider.getBackupObjectCount(KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR) + seProvider.getBackupObjectCount( KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY)); } diff --git a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java index 462aebfa..bb62d0ec 100644 --- a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java +++ b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java @@ -15,7 +15,7 @@ */ package com.android.javacard.keymaster; -import com.android.javacard.seprovider.KMDeviceUniqueKey; +import com.android.javacard.seprovider.KMDeviceUniqueKeyPair; import com.android.javacard.seprovider.KMException; import com.android.javacard.seprovider.KMOperation; import com.android.javacard.seprovider.KMSEProvider; @@ -742,7 +742,7 @@ private void constructPartialPubKeysToSignMac(byte[] scratchPad, short arrayLeng ((KMOperation) operation[0]).update(scratchPad, (short) 0, (short) (len + partialPayloadLen)); } - private short createSignedMac(KMDeviceUniqueKey deviceUniqueKey, byte[] scratchPad, + private short createSignedMac(KMDeviceUniqueKeyPair deviceUniqueKeyPair, byte[] scratchPad, short deviceMapPtr, short pubKeysToSign) { // Challenge short dataEntryIndex = getEntry(CHALLENGE); @@ -778,7 +778,7 @@ private short createSignedMac(KMDeviceUniqueKey deviceUniqueKey, byte[] scratchP (short) 0, KMKeymasterApplet.MAX_COSE_BUF_SIZE); short len = seProvider.ecSign256( - deviceUniqueKey, + deviceUniqueKeyPair, scratchPad, (short) 0, signStructure, @@ -799,8 +799,8 @@ private short createSignedMac(KMDeviceUniqueKey deviceUniqueKey, byte[] scratchP } - private KMDeviceUniqueKey createDeviceUniqueKey(boolean testMode, byte[] scratchPad) { - KMDeviceUniqueKey deviceUniqueKey; + private KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(boolean testMode, byte[] scratchPad) { + KMDeviceUniqueKeyPair deviceUniqueKeyPair; short[] lengths = {0, 0}; if (testMode) { seProvider.createAsymmetricKey( @@ -812,13 +812,13 @@ private KMDeviceUniqueKey createDeviceUniqueKey(boolean testMode, byte[] scratch (short) 128, (short) 128, lengths); - deviceUniqueKey = - storeDataInst.createTestDeviceUniqueKey(scratchPad, (short) 128, lengths[1], + deviceUniqueKeyPair = + storeDataInst.createTestDeviceUniqueKeyPair(scratchPad, (short) 128, lengths[1], scratchPad, (short) 0, lengths[0]); } else { - deviceUniqueKey = storeDataInst.getDeviceUniqueKey(false); + deviceUniqueKeyPair = storeDataInst.getDeviceUniqueKeyPair(false); } - return deviceUniqueKey; + return deviceUniqueKeyPair; } /** @@ -1276,10 +1276,10 @@ private void processAesGcmUpdateAad(byte[] scratchPad) { private short processSignedMac(byte[] scratchPad, short pubKeysToSignMac, short deviceInfo) { // Construct SignedMac - KMDeviceUniqueKey deviceUniqueKey = - createDeviceUniqueKey((TRUE == data[getEntry(TEST_MODE)]) ? true : false, scratchPad); + KMDeviceUniqueKeyPair deviceUniqueKeyPair = + createDeviceUniqueKeyPair((TRUE == data[getEntry(TEST_MODE)]) ? true : false, scratchPad); // Create signedMac - short signedMac = createSignedMac(deviceUniqueKey, scratchPad, deviceInfo, pubKeysToSignMac); + short signedMac = createSignedMac(deviceUniqueKeyPair, scratchPad, deviceInfo, pubKeysToSignMac); //Prepare partial data for encryption. short arrLength = (short) (isAdditionalCertificateChainPresent() ? 3 : 2); short arr = KMArray.instance(arrLength); diff --git a/ProvisioningTool/sample_json_keymint_gf.txt b/ProvisioningTool/sample_json_keymint_gf.txt new file mode 100644 index 00000000..26c6c4d0 --- /dev/null +++ b/ProvisioningTool/sample_json_keymint_gf.txt @@ -0,0 +1,28 @@ +{ + "attest_ids": { + "brand": "Android", + "device": "generic_x86_64", + "product": "aosp_x86_64", + "serial": "", + "imei": "000000000000000", + "meid": "000000000000000", + "manufacturer": "unknown", + "model": "AOSP on x86_64" + }, + "shared_secret": "0000000000000000000000000000000000000000000000000000000000000000", + "set_boot_params": { + "boot_patch_level": 20220101, + "verified_boot_key": "0000000000000000000000000000000000000000000000000000000000000000", + "verified_boot_key_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "boot_state": 0, + "device_locked": 1 + }, + "device_unique_key": "test_resources/batch_key.der", + "signer_info": { + "signer_name": "Google", + "signing_keys": [ + "test_resources/ca_key.der", + "test_resources/intermediate_key.der" + ] + } +} diff --git a/aosp_integration_patches/device_google_cuttlefish.patch b/aosp_integration_patches/cuttlefish_target_only/device_google_cuttlefish.patch similarity index 76% rename from aosp_integration_patches/device_google_cuttlefish.patch rename to aosp_integration_patches/cuttlefish_target_only/device_google_cuttlefish.patch index 7d8461a6..bf743916 100644 --- a/aosp_integration_patches/device_google_cuttlefish.patch +++ b/aosp_integration_patches/cuttlefish_target_only/device_google_cuttlefish.patch @@ -1,8 +1,22 @@ +From 873f771fec1e60fb45d5ccab449cdc859c656910 Mon Sep 17 00:00:00 2001 +From: subrahmanyaman +Date: Mon, 21 Mar 2022 23:01:00 +0000 +Subject: [PATCH] javacard strongbox keymint + +Change-Id: Ic6b0dac4b5078fdfdbfa2b13e3260c62acf628cf +--- + shared/device.mk | 3 +++ + shared/sepolicy/vendor/file_contexts | 1 + + shared/sepolicy/vendor/hal_keymint_strongbox.te | 16 ++++++++++++++++ + shared/sepolicy/vendor/service_contexts | 3 +++ + 4 files changed, 23 insertions(+) + create mode 100644 shared/sepolicy/vendor/hal_keymint_strongbox.te + diff --git a/shared/device.mk b/shared/device.mk -index 36c66ce18..2f6505d4f 100644 +index 904ddd6ca..3e48f3ac1 100644 --- a/shared/device.mk +++ b/shared/device.mk -@@ -622,6 +622,9 @@ endif +@@ -623,6 +623,9 @@ endif PRODUCT_PACKAGES += \ $(LOCAL_KEYMINT_PRODUCT_PACKAGE) @@ -24,26 +38,12 @@ index 6c471b8b8..cc223bdc4 100644 /vendor/bin/hw/android\.hardware\.keymaster@4\.1-service.remote u:object_r:hal_keymaster_remote_exec:s0 /vendor/bin/hw/android\.hardware\.gatekeeper@1\.0-service.remote u:object_r:hal_gatekeeper_remote_exec:s0 /vendor/bin/hw/android\.hardware\.confirmationui@1\.0-service.cuttlefish u:object_r:hal_confirmationui_cuttlefish_exec:s0 -diff --git a/shared/sepolicy/vendor/service_contexts b/shared/sepolicy/vendor/service_contexts -index c41503e3b..acd78e1ce 100644 ---- a/shared/sepolicy/vendor/service_contexts -+++ b/shared/sepolicy/vendor/service_contexts -@@ -5,6 +5,9 @@ android.hardware.neuralnetworks.IDevice/nnapi-sample_float_slow u:object_r:hal_n - android.hardware.neuralnetworks.IDevice/nnapi-sample_minimal u:object_r:hal_neuralnetworks_service:s0 - android.hardware.neuralnetworks.IDevice/nnapi-sample_quant u:object_r:hal_neuralnetworks_service:s0 - android.hardware.neuralnetworks.IDevice/nnapi-sample_sl_shim u:object_r:hal_neuralnetworks_service:s0 -+android.hardware.security.keymint.IKeyMintDevice/strongbox u:object_r:hal_keymint_service:s0 -+android.hardware.security.sharedsecret.ISharedSecret/strongbox u:object_r:hal_sharedsecret_service:s0 -+android.hardware.security.keymint.IRemotelyProvisionedComponent/strongbox u:object_r:hal_keymint_service:s0 - - # Binder service mappings - gce u:object_r:gce_service:s0 - diff --git a/shared/sepolicy/vendor/hal_keymint_strongbox.te b/shared/sepolicy/vendor/hal_keymint_strongbox.te +diff --git a/shared/sepolicy/vendor/hal_keymint_strongbox.te b/shared/sepolicy/vendor/hal_keymint_strongbox.te new file mode 100644 -index 000000000..839fd1a6b +index 000000000..4073d0790 --- /dev/null +++ b/shared/sepolicy/vendor/hal_keymint_strongbox.te -@@ -0,0 +1,14 @@ +@@ -0,0 +1,16 @@ +type hal_keymint_strongbox, domain; +hal_server_domain(hal_keymint_strongbox, hal_keymint) + @@ -53,8 +53,27 @@ index 000000000..839fd1a6b +vndbinder_use(hal_keymint_strongbox) +get_prop(hal_keymint_strongbox, vendor_security_patch_level_prop); + ++allow hal_keymint_strongbox secure_element_service:service_manager find; ++ +# Allow access to sockets +allow hal_keymint_strongbox self:tcp_socket { connect create write read getattr getopt setopt }; +allow hal_keymint_strongbox port_type:tcp_socket name_connect; +allow hal_keymint_strongbox port:tcp_socket { name_connect }; +allow hal_keymint_strongbox vendor_data_file:file { open read getattr }; +diff --git a/shared/sepolicy/vendor/service_contexts b/shared/sepolicy/vendor/service_contexts +index c41503e3b..acd78e1ce 100644 +--- a/shared/sepolicy/vendor/service_contexts ++++ b/shared/sepolicy/vendor/service_contexts +@@ -5,6 +5,9 @@ android.hardware.neuralnetworks.IDevice/nnapi-sample_float_slow u:object_r:hal_n + android.hardware.neuralnetworks.IDevice/nnapi-sample_minimal u:object_r:hal_neuralnetworks_service:s0 + android.hardware.neuralnetworks.IDevice/nnapi-sample_quant u:object_r:hal_neuralnetworks_service:s0 + android.hardware.neuralnetworks.IDevice/nnapi-sample_sl_shim u:object_r:hal_neuralnetworks_service:s0 ++android.hardware.security.keymint.IKeyMintDevice/strongbox u:object_r:hal_keymint_service:s0 ++android.hardware.security.sharedsecret.ISharedSecret/strongbox u:object_r:hal_sharedsecret_service:s0 ++android.hardware.security.keymint.IRemotelyProvisionedComponent/strongbox u:object_r:hal_keymint_service:s0 + + # Binder service mappings + gce u:object_r:gce_service:s0 +-- +2.35.1.894.gb6a874cedc-goog + diff --git a/aosp_integration_patches/goldfish_target_only/device_generic_goldfish.patch b/aosp_integration_patches/goldfish_target_only/device_generic_goldfish.patch new file mode 100644 index 00000000..d1033185 --- /dev/null +++ b/aosp_integration_patches/goldfish_target_only/device_generic_goldfish.patch @@ -0,0 +1,15 @@ +diff --git a/64bitonly/product/vendor.mk b/64bitonly/product/vendor.mk +index 8b27fd14..09b8588e 100644 +--- a/64bitonly/product/vendor.mk ++++ b/64bitonly/product/vendor.mk +@@ -103,7 +103,9 @@ PRODUCT_PACKAGES += \ + android.hardware.neuralnetworks@1.3-service-sample-limited + + PRODUCT_PACKAGES += \ +- android.hardware.security.keymint-service ++ android.hardware.security.keymint-service \ ++ android.hardware.security.keymint-service.strongbox ++ + PRODUCT_COPY_FILES += \ + frameworks/native/data/etc/android.hardware.keystore.app_attest_key.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.keystore.app_attest_key.xml + diff --git a/aosp_integration_patches/goldfish_target_only/system_sepolicy.patch b/aosp_integration_patches/goldfish_target_only/system_sepolicy.patch new file mode 100644 index 00000000..d5a78454 --- /dev/null +++ b/aosp_integration_patches/goldfish_target_only/system_sepolicy.patch @@ -0,0 +1,46 @@ +diff --git a/private/service_contexts b/private/service_contexts +index c7f881136..6c3bfc06c 100644 +--- a/private/service_contexts ++++ b/private/service_contexts +@@ -53,6 +53,9 @@ android.hardware.security.keymint.IKeyMintDevice/default u:object_r: + android.hardware.security.keymint.IRemotelyProvisionedComponent/default u:object_r:hal_remotelyprovisionedcomponent_service:s0 + android.hardware.security.secureclock.ISecureClock/default u:object_r:hal_secureclock_service:s0 + android.hardware.security.sharedsecret.ISharedSecret/default u:object_r:hal_sharedsecret_service:s0 ++android.hardware.security.keymint.IKeyMintDevice/strongbox u:object_r:hal_keymint_service:s0 ++android.hardware.security.sharedsecret.ISharedSecret/strongbox u:object_r:hal_sharedsecret_service:s0 ++android.hardware.security.keymint.IRemotelyProvisionedComponent/strongbox u:object_r:hal_keymint_service:s0 + android.hardware.sensors.ISensors/default u:object_r:hal_sensors_service:s0 + android.hardware.soundtrigger3.ISoundTriggerHw/default u:object_r:hal_audio_service:s0 + android.hardware.tv.tuner.ITuner/default u:object_r:hal_tv_tuner_service:s0 +diff --git a/vendor/file_contexts b/vendor/file_contexts +index 0cfb7cf39..65b8a8205 100644 +--- a/vendor/file_contexts ++++ b/vendor/file_contexts +@@ -84,6 +84,7 @@ + /(vendor|system/vendor)/bin/hw/android\.hardware\.secure_element@1\.0-service u:object_r:hal_secure_element_default_exec:s0 + /(vendor|system/vendor)/bin/hw/android\.hardware\.security\.dice-service\.non-secure-software u:object_r:hal_dice_default_exec:s0 + /(vendor|system/vendor)/bin/hw/android\.hardware\.security\.keymint-service u:object_r:hal_keymint_default_exec:s0 ++/vendor/bin/hw/android\.hardware\.security\.keymint-service\.strongbox u:object_r:hal_keymint_strongbox_exec:s0 + /(vendor|system/vendor)/bin/hw/rild u:object_r:rild_exec:s0 + /(vendor|system/vendor)/bin/hw/android\.hardware\.thermal@1\.[01]-service u:object_r:hal_thermal_default_exec:s0 + /(vendor|system/vendor)/bin/hw/android\.hardware\.tv\.cec@1\.[01]-service u:object_r:hal_tv_cec_default_exec:s0 +diff --git a/vendor/hal_keymint_strongbox.te b/vendor/hal_keymint_strongbox.te +new file mode 100644 +index 000000000..40cb82c3f +--- /dev/null ++++ b/vendor/hal_keymint_strongbox.te +@@ -0,0 +1,14 @@ ++type hal_keymaster_strongbox, domain; ++hal_server_domain(hal_keymaster_strongbox, hal_keymaster) ++ ++type hal_keymaster_strongbox_exec, exec_type, vendor_file_type, file_type; ++init_daemon_domain(hal_keymaster_strongbox) ++ ++vndbinder_use(hal_keymaster_strongbox) ++get_prop(hal_keymaster_strongbox, vendor_security_patch_level_prop); ++ ++# Allow access to sockets ++allow hal_keymaster_strongbox self:tcp_socket { connect create write read getattr getopt setopt }; ++allow hal_keymaster_strongbox port_type:tcp_socket name_connect; ++allow hal_keymaster_strongbox port:tcp_socket { name_connect }; ++allow hal_keymaster_strongbox vendor_data_file:file { open read getattr }; diff --git a/aosp_integration_patches/omapi_patches/JavacardKeymaster.patch b/aosp_integration_patches/omapi_patches/JavacardKeymaster.patch deleted file mode 100644 index 1d6bad7a..00000000 --- a/aosp_integration_patches/omapi_patches/JavacardKeymaster.patch +++ /dev/null @@ -1,385 +0,0 @@ -diff --git a/HAL/Android.bp b/HAL/Android.bp -index c705a01..10dd93e 100644 ---- a/HAL/Android.bp -+++ b/HAL/Android.bp -@@ -55,13 +55,17 @@ cc_library { - vendor_available: true, - srcs: [ - "SocketTransport.cpp", -+ "OmapiTransport.cpp" - ], - export_include_dirs: [ - "." - ], - shared_libs: [ -+ "libbinder", - "libbase", - "liblog", -+ "libbinder_ndk", -+ "android.se.omapi-V1-ndk", - ], - } - -@@ -90,6 +94,7 @@ cc_binary { - "libjc_keymint_transport", - "liblog", - "libutils", -+ "android.se.omapi-V1-ndk", - ], - srcs: [ - "service.cpp", -diff --git a/HAL/OmapiTransport.cpp b/HAL/OmapiTransport.cpp -new file mode 100644 -index 0000000..dd81d3d ---- /dev/null -+++ b/HAL/OmapiTransport.cpp -@@ -0,0 +1,218 @@ -+/* -+ ** -+ ** Copyright 2020, The Android Open Source Project -+ ** -+ ** Licensed under the Apache License, Version 2.0 (the "License"); -+ ** you may not use this file except in compliance with the License. -+ ** You may obtain a copy of the License at -+ ** -+ ** http://www.apache.org/licenses/LICENSE-2.0 -+ ** -+ ** Unless required by applicable law or agreed to in writing, software -+ ** distributed under the License is distributed on an "AS IS" BASIS, -+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ ** See the License for the specific language governing permissions and -+ ** limitations under the License. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "OmapiTransport.h" -+ -+namespace keymint::javacard { -+ -+class SEListener : public ::aidl::android::se::omapi::BnSecureElementListener {}; -+ -+bool OmapiTransport::initialize() { -+ std::vector readers = {}; -+ -+ LOG(DEBUG) << "Initialize the secure element connection"; -+ -+ // Get OMAPI vendor stable service handler -+ ::ndk::SpAIBinder ks2Binder(AServiceManager_getService(omapiServiceName)); -+ omapiSeService = aidl::android::se::omapi::ISecureElementService::fromBinder(ks2Binder); -+ -+ if (omapiSeService == nullptr) { -+ LOG(ERROR) << "Failed to start omapiSeService null"; -+ return false; -+ } -+ -+ // reset readers, clear readers if already existing -+ if (mVSReaders.size() > 0) { -+ closeConnection(); -+ } -+ -+ // Get available readers -+ auto status = omapiSeService->getReaders(&readers); -+ if (!status.isOk()) { -+ LOG(ERROR) << "getReaders failed to get available readers: " << status.getMessage(); -+ return false; -+ } -+ -+ // Get SE readers handlers -+ for (auto readerName : readers) { -+ std::shared_ptr<::aidl::android::se::omapi::ISecureElementReader> reader; -+ status = omapiSeService->getReader(readerName, &reader); -+ if (!status.isOk()) { -+ LOG(ERROR) << "getReader for " << readerName.c_str() << " Failed: " -+ << status.getMessage(); -+ return false; -+ } -+ -+ mVSReaders[readerName] = reader; -+ } -+ -+ // Find eSE reader, as of now assumption is only eSE available on device -+ LOG(DEBUG) << "Finding eSE reader"; -+ eSEReader = nullptr; -+ if (mVSReaders.size() > 0) { -+ for (const auto& [name, reader] : mVSReaders) { -+ if (name.find(ESE_READER_PREFIX, 0) != std::string::npos) { -+ LOG(DEBUG) << "eSE reader found: " << name; -+ eSEReader = reader; -+ } -+ } -+ } -+ -+ if (eSEReader == nullptr) { -+ LOG(ERROR) << "secure element reader " << ESE_READER_PREFIX << " not found"; -+ return false; -+ } -+ -+ return true; -+} -+ -+bool OmapiTransport::internalTransmitApdu( -+ std::shared_ptr reader, -+ std::vector apdu, std::vector& transmitResponse) { -+ std::shared_ptr session; -+ std::shared_ptr channel; -+ auto mSEListener = std::make_shared(); -+ std::vector selectResponse = {}; -+ std::vector SELECTABLE_AID = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, -+ 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x31}; -+ -+ LOG(DEBUG) << "internalTransmitApdu: trasmitting data to secure element"; -+ -+ if (reader == nullptr) { -+ LOG(ERROR) << "eSE reader is null"; -+ return false; -+ } -+ -+ bool status = false; -+ auto res = reader->isSecureElementPresent(&status); -+ if (!res.isOk()) { -+ LOG(ERROR) << "isSecureElementPresent error: " << res.getMessage(); -+ return false; -+ } -+ if (!status) { -+ LOG(ERROR) << "secure element not found"; -+ return false; -+ } -+ -+ res = reader->openSession(&session); -+ if (!res.isOk()) { -+ LOG(ERROR) << "openSession error: " << res.getMessage(); -+ return false; -+ } -+ if (session == nullptr) { -+ LOG(ERROR) << "Could not open session null"; -+ return false; -+ } -+ -+ res = session->openLogicalChannel(SELECTABLE_AID, 0x00, mSEListener, &channel); -+ if (!res.isOk()) { -+ LOG(ERROR) << "openLogicalChannel error: " << res.getMessage(); -+ return false; -+ } -+ if (channel == nullptr) { -+ LOG(ERROR) << "Could not open channel null"; -+ return false; -+ } -+ -+ res = channel->getSelectResponse(&selectResponse); -+ if (!res.isOk()) { -+ LOG(ERROR) << "getSelectResponse error: " << res.getMessage(); -+ return false; -+ } -+ if (selectResponse.size() < 2) { -+ LOG(ERROR) << "getSelectResponse size error"; -+ return false; -+ } -+ -+ res = channel->transmit(apdu, &transmitResponse); -+ if (channel != nullptr) channel->close(); -+ if (session != nullptr) session->close(); -+ -+ LOG(INFO) << "STATUS OF TRNSMIT: " << res.getExceptionCode() << " Message: " -+ << res.getMessage(); -+ if (!res.isOk()) { -+ LOG(ERROR) << "transmit error: " << res.getMessage(); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool OmapiTransport::openConnection() { -+ -+ // if already conection setup done, no need to initialise it again. -+ if (isConnected()) { -+ return true; -+ } -+ -+ return initialize(); -+} -+ -+bool OmapiTransport::sendData(const vector& inData, vector& output) { -+ -+ if (!isConnected()) { -+ // Try to initialize connection to eSE -+ LOG(INFO) << "Failed to send data, try to initialize connection SE connection"; -+ if (!initialize()) { -+ LOG(ERROR) << "Failed to send data, initialization not completed"; -+ closeConnection(); -+ return false; -+ } -+ } -+ -+ if (eSEReader != nullptr) { -+ LOG(DEBUG) << "Sending apdu data to secure element: " << ESE_READER_PREFIX; -+ return internalTransmitApdu(eSEReader, inData, output); -+ } else { -+ LOG(ERROR) << "secure element reader " << ESE_READER_PREFIX << " not found"; -+ return false; -+ } -+} -+ -+bool OmapiTransport::closeConnection() { -+ LOG(DEBUG) << "Closing all connections"; -+ if (omapiSeService != nullptr) { -+ if (mVSReaders.size() > 0) { -+ for (const auto& [name, reader] : mVSReaders) { -+ reader->closeSessions(); -+ } -+ mVSReaders.clear(); -+ } -+ } -+ return true; -+} -+ -+bool OmapiTransport::isConnected() { -+ // Check already initialization completed or not -+ if (omapiSeService != nullptr && eSEReader != nullptr) { -+ LOG(DEBUG) << "Connection initialization already completed"; -+ return true; -+ } -+ -+ LOG(DEBUG) << "Connection initialization not completed"; -+ return false; -+} -+ -+} -diff --git a/HAL/OmapiTransport.h b/HAL/OmapiTransport.h -new file mode 100644 -index 0000000..f7711e7 ---- /dev/null -+++ b/HAL/OmapiTransport.h -@@ -0,0 +1,61 @@ -+#pragma once -+ -+#include "ITransport.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+namespace keymint::javacard { -+using std::vector; -+ -+/** -+ * OmapiTransport is derived from ITransport. This class gets the OMAPI service binder instance and uses IPC to -+ * communicate with OMAPI service. OMAPI inturn communicates with hardware via ISecureElement. -+ */ -+class OmapiTransport : public ITransport { -+ -+public: -+ -+ /** -+ * Gets the binder instance of ISEService, gets the reader corresponding to secure element, establishes a session -+ * and opens a basic channel. -+ */ -+ bool openConnection() override; -+ /** -+ * Transmists the data over the opened basic channel and receives the data back. -+ */ -+ bool sendData(const vector& inData, vector& output) override; -+ -+ /** -+ * Closes the connection. -+ */ -+ bool closeConnection() override; -+ /** -+ * Returns the state of the connection status. Returns true if the connection is active, false if connection is -+ * broken. -+ */ -+ bool isConnected() override; -+ -+private: -+ std::shared_ptr omapiSeService = nullptr; -+ std::shared_ptr eSEReader = nullptr; -+ std::map> -+ mVSReaders = {}; -+ std::string const ESE_READER_PREFIX = "eSE"; -+ constexpr static const char omapiServiceName[] = -+ "android.system.omapi.ISecureElementService/default"; -+ -+ bool initialize(); -+ bool internalTransmitApdu( -+ std::shared_ptr reader, -+ std::vector apdu, std::vector& transmitResponse); -+}; -+ -+} -\ No newline at end of file -diff --git a/HAL/service.cpp b/HAL/service.cpp -index 3d51877..14580f8 100644 ---- a/HAL/service.cpp -+++ b/HAL/service.cpp -@@ -22,18 +22,24 @@ - - #include "JavacardKeyMintDevice.h" - #include -- -+#include - #include "JavacardSecureElement.h" - #include "JavacardSharedSecret.h" - #include "keymint_utils.h" - #include "JavacardRemotelyProvisionedComponentDevice.h" - #include -+#include - - using aidl::android::hardware::security::keymint::JavacardKeyMintDevice; - using aidl::android::hardware::security::keymint::JavacardSharedSecret; - using aidl::android::hardware::security::keymint::SecurityLevel; - using namespace keymint::javacard; - -+#define PROP_BUILD_QEMU "ro.kernel.qemu" -+#define PROP_BUILD_FINGERPRINT "ro.build.fingerprint" -+// Cuttlefish build fingerprint substring. -+#define CUTTLEFISH_FINGERPRINT_SS "aosp_cf_" -+ - template std::shared_ptr addService(Args&&... args) { - std::shared_ptr ser = ndk::SharedRefBase::make(std::forward(args)...); - auto instanceName = std::string(T::descriptor) + "/strongbox"; -@@ -44,11 +50,31 @@ template std::shared_ptr addService(Args&&... arg - return ser; - } - -+std::shared_ptr getTransportInstance() { -+ bool isEmulator = false; -+ // Check if the current build is for emulator or device. -+ isEmulator = android::base::GetBoolProperty(PROP_BUILD_QEMU, false); -+ if (!isEmulator) { -+ std::string fingerprint = android::base::GetProperty(PROP_BUILD_FINGERPRINT, ""); -+ if (!fingerprint.empty()) { -+ if (fingerprint.find(CUTTLEFISH_FINGERPRINT_SS, 0) != std::string::npos) { -+ isEmulator = true; -+ } -+ } -+ } -+ -+ if (!isEmulator) { -+ return std::make_shared(); -+ } else { -+ return std::make_shared(); -+ } -+} -+ - int main() { - ABinderProcess_setThreadPoolMaxThreadCount(0); - // Javacard Secure Element - std::shared_ptr card = -- std::make_shared(std::make_shared(), getOsVersion(), -+ std::make_shared(getTransportInstance(), getOsVersion(), - getOsPatchlevel(), getVendorPatchlevel()); - // Add Keymint Service - addService(card); diff --git a/aosp_integration_patches_aosp_12_r15/JavacardKeymaster_remove_omapi.patch b/aosp_integration_patches_aosp_12_r15/JavacardKeymaster_remove_omapi.patch new file mode 100644 index 00000000..c27763ef --- /dev/null +++ b/aosp_integration_patches_aosp_12_r15/JavacardKeymaster_remove_omapi.patch @@ -0,0 +1,387 @@ +diff --git a/HAL/Android.bp b/HAL/Android.bp +index 557f204..69fead7 100644 +--- a/HAL/Android.bp ++++ b/HAL/Android.bp +@@ -55,17 +55,13 @@ cc_library { + vendor_available: true, + srcs: [ + "SocketTransport.cpp", +- "OmapiTransport.cpp" + ], + export_include_dirs: [ + "." + ], + shared_libs: [ +- "libbinder", + "libbase", + "liblog", +- "libbinder_ndk", +- "android.se.omapi-V1-ndk", + ], + } + +@@ -94,7 +90,6 @@ cc_binary { + "libjc_keymint_transport", + "liblog", + "libutils", +- "android.se.omapi-V1-ndk", + ], + srcs: [ + "service.cpp", +diff --git a/HAL/OmapiTransport.cpp b/HAL/OmapiTransport.cpp +deleted file mode 100644 +index b7e1dc0..0000000 +--- a/HAL/OmapiTransport.cpp ++++ /dev/null +@@ -1,221 +0,0 @@ +-/* +- ** +- ** Copyright 2020, The Android Open Source Project +- ** +- ** Licensed under the Apache License, Version 2.0 (the "License"); +- ** you may not use this file except in compliance with the License. +- ** You may obtain a copy of the License at +- ** +- ** http://www.apache.org/licenses/LICENSE-2.0 +- ** +- ** Unless required by applicable law or agreed to in writing, software +- ** distributed under the License is distributed on an "AS IS" BASIS, +- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- ** See the License for the specific language governing permissions and +- ** limitations under the License. +- */ +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-#include "OmapiTransport.h" +- +-namespace keymint::javacard { +- +-constexpr uint8_t SELECTABLE_AID[] = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, +- 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x31}; +- +-class SEListener : public ::aidl::android::se::omapi::BnSecureElementListener {}; +- +-bool OmapiTransport::initialize() { +- std::vector readers = {}; +- +- LOG(DEBUG) << "Initialize the secure element connection"; +- +- // Get OMAPI vendor stable service handler +- ::ndk::SpAIBinder ks2Binder(AServiceManager_getService(omapiServiceName)); +- omapiSeService = aidl::android::se::omapi::ISecureElementService::fromBinder(ks2Binder); +- +- if (omapiSeService == nullptr) { +- LOG(ERROR) << "Failed to start omapiSeService null"; +- return false; +- } +- +- // reset readers, clear readers if already existing +- if (mVSReaders.size() > 0) { +- closeConnection(); +- } +- +- // Get available readers +- auto status = omapiSeService->getReaders(&readers); +- if (!status.isOk()) { +- LOG(ERROR) << "getReaders failed to get available readers: " << status.getMessage(); +- return false; +- } +- +- // Get SE readers handlers +- for (auto readerName : readers) { +- std::shared_ptr<::aidl::android::se::omapi::ISecureElementReader> reader; +- status = omapiSeService->getReader(readerName, &reader); +- if (!status.isOk()) { +- LOG(ERROR) << "getReader for " << readerName.c_str() +- << " Failed: " << status.getMessage(); +- return false; +- } +- +- mVSReaders[readerName] = reader; +- } +- +- // Find eSE reader, as of now assumption is only eSE available on device +- LOG(DEBUG) << "Finding eSE reader"; +- eSEReader = nullptr; +- if (mVSReaders.size() > 0) { +- for (const auto& [name, reader] : mVSReaders) { +- if (name.find(ESE_READER_PREFIX, 0) != std::string::npos) { +- LOG(DEBUG) << "eSE reader found: " << name; +- eSEReader = reader; +- } +- } +- } +- +- if (eSEReader == nullptr) { +- LOG(ERROR) << "secure element reader " << ESE_READER_PREFIX << " not found"; +- return false; +- } +- +- return true; +-} +- +-bool OmapiTransport::internalTransmitApdu( +- std::shared_ptr reader, +- std::vector apdu, std::vector& transmitResponse) { +- std::shared_ptr session; +- std::shared_ptr channel; +- auto mSEListener = ndk::SharedRefBase::make(); +- std::vector selectResponse = {}; +- int size = sizeof(SELECTABLE_AID) / sizeof(SELECTABLE_AID[0]); +- std::vector aid(SELECTABLE_AID, SELECTABLE_AID + size); +- +- LOG(DEBUG) << "internalTransmitApdu: trasmitting data to secure element"; +- +- if (reader == nullptr) { +- LOG(ERROR) << "eSE reader is null"; +- return false; +- } +- +- bool status = false; +- auto res = reader->isSecureElementPresent(&status); +- if (!res.isOk()) { +- LOG(ERROR) << "isSecureElementPresent error: " << res.getMessage(); +- return false; +- } +- if (!status) { +- LOG(ERROR) << "secure element not found"; +- return false; +- } +- +- res = reader->openSession(&session); +- if (!res.isOk()) { +- LOG(ERROR) << "openSession error: " << res.getMessage(); +- return false; +- } +- if (session == nullptr) { +- LOG(ERROR) << "Could not open session null"; +- return false; +- } +- +- res = session->openLogicalChannel(aid, 0x00, mSEListener, &channel); +- if (!res.isOk()) { +- LOG(ERROR) << "openLogicalChannel error: " << res.getMessage(); +- return false; +- } +- if (channel == nullptr) { +- LOG(ERROR) << "Could not open channel null"; +- return false; +- } +- +- res = channel->getSelectResponse(&selectResponse); +- if (!res.isOk()) { +- LOG(ERROR) << "getSelectResponse error: " << res.getMessage(); +- return false; +- } +- if (selectResponse.size() < 2) { +- LOG(ERROR) << "getSelectResponse size error"; +- return false; +- } +- +- res = channel->transmit(apdu, &transmitResponse); +- if (channel != nullptr) channel->close(); +- if (session != nullptr) session->close(); +- +- LOG(INFO) << "STATUS OF TRNSMIT: " << res.getExceptionCode() +- << " Message: " << res.getMessage(); +- if (!res.isOk()) { +- LOG(ERROR) << "transmit error: " << res.getMessage(); +- return false; +- } +- +- return true; +-} +- +-bool OmapiTransport::openConnection() { +- +- // if already conection setup done, no need to initialise it again. +- if (isConnected()) { +- return true; +- } +- +- return initialize(); +-} +- +-bool OmapiTransport::sendData(const vector& inData, vector& output) { +- +- if (!isConnected()) { +- // Try to initialize connection to eSE +- LOG(INFO) << "Failed to send data, try to initialize connection SE connection"; +- if (!initialize()) { +- LOG(ERROR) << "Failed to send data, initialization not completed"; +- closeConnection(); +- return false; +- } +- } +- +- if (eSEReader != nullptr) { +- LOG(DEBUG) << "Sending apdu data to secure element: " << ESE_READER_PREFIX; +- return internalTransmitApdu(eSEReader, inData, output); +- } else { +- LOG(ERROR) << "secure element reader " << ESE_READER_PREFIX << " not found"; +- return false; +- } +-} +- +-bool OmapiTransport::closeConnection() { +- LOG(DEBUG) << "Closing all connections"; +- if (omapiSeService != nullptr) { +- if (mVSReaders.size() > 0) { +- for (const auto& [name, reader] : mVSReaders) { +- reader->closeSessions(); +- } +- mVSReaders.clear(); +- } +- } +- return true; +-} +- +-bool OmapiTransport::isConnected() { +- // Check already initialization completed or not +- if (omapiSeService != nullptr && eSEReader != nullptr) { +- LOG(DEBUG) << "Connection initialization already completed"; +- return true; +- } +- +- LOG(DEBUG) << "Connection initialization not completed"; +- return false; +-} +- +-} +diff --git a/HAL/OmapiTransport.h b/HAL/OmapiTransport.h +deleted file mode 100644 +index 2a53787..0000000 +--- a/HAL/OmapiTransport.h ++++ /dev/null +@@ -1,61 +0,0 @@ +-#pragma once +- +-#include "ITransport.h" +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-namespace keymint::javacard { +-using std::vector; +- +-/** +- * OmapiTransport is derived from ITransport. This class gets the OMAPI service binder instance and +- * uses IPC to communicate with OMAPI service. OMAPI inturn communicates with hardware via +- * ISecureElement. +- */ +-class OmapiTransport : public ITransport { +- +- public: +- /** +- * Gets the binder instance of ISEService, gets the reader corresponding to secure element, +- * establishes a session and opens a basic channel. +- */ +- bool openConnection() override; +- /** +- * Transmists the data over the opened basic channel and receives the data back. +- */ +- bool sendData(const vector& inData, vector& output) override; +- +- /** +- * Closes the connection. +- */ +- bool closeConnection() override; +- /** +- * Returns the state of the connection status. Returns true if the connection is active, false +- * if connection is broken. +- */ +- bool isConnected() override; +- +- private: +- std::shared_ptr omapiSeService = nullptr; +- std::shared_ptr eSEReader = nullptr; +- std::map> +- mVSReaders = {}; +- std::string const ESE_READER_PREFIX = "eSE"; +- constexpr static const char omapiServiceName[] = +- "android.system.omapi.ISecureElementService/default"; +- +- bool initialize(); +- bool +- internalTransmitApdu(std::shared_ptr reader, +- std::vector apdu, std::vector& transmitResponse); +-}; +- +-} +diff --git a/HAL/service.cpp b/HAL/service.cpp +index 14580f8..3d51877 100644 +--- a/HAL/service.cpp ++++ b/HAL/service.cpp +@@ -22,24 +22,18 @@ + + #include "JavacardKeyMintDevice.h" + #include +-#include ++ + #include "JavacardSecureElement.h" + #include "JavacardSharedSecret.h" + #include "keymint_utils.h" + #include "JavacardRemotelyProvisionedComponentDevice.h" + #include +-#include + + using aidl::android::hardware::security::keymint::JavacardKeyMintDevice; + using aidl::android::hardware::security::keymint::JavacardSharedSecret; + using aidl::android::hardware::security::keymint::SecurityLevel; + using namespace keymint::javacard; + +-#define PROP_BUILD_QEMU "ro.kernel.qemu" +-#define PROP_BUILD_FINGERPRINT "ro.build.fingerprint" +-// Cuttlefish build fingerprint substring. +-#define CUTTLEFISH_FINGERPRINT_SS "aosp_cf_" +- + template std::shared_ptr addService(Args&&... args) { + std::shared_ptr ser = ndk::SharedRefBase::make(std::forward(args)...); + auto instanceName = std::string(T::descriptor) + "/strongbox"; +@@ -50,31 +44,11 @@ template std::shared_ptr addService(Args&&... arg + return ser; + } + +-std::shared_ptr getTransportInstance() { +- bool isEmulator = false; +- // Check if the current build is for emulator or device. +- isEmulator = android::base::GetBoolProperty(PROP_BUILD_QEMU, false); +- if (!isEmulator) { +- std::string fingerprint = android::base::GetProperty(PROP_BUILD_FINGERPRINT, ""); +- if (!fingerprint.empty()) { +- if (fingerprint.find(CUTTLEFISH_FINGERPRINT_SS, 0) != std::string::npos) { +- isEmulator = true; +- } +- } +- } +- +- if (!isEmulator) { +- return std::make_shared(); +- } else { +- return std::make_shared(); +- } +-} +- + int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + // Javacard Secure Element + std::shared_ptr card = +- std::make_shared(getTransportInstance(), getOsVersion(), ++ std::make_shared(std::make_shared(), getOsVersion(), + getOsPatchlevel(), getVendorPatchlevel()); + // Add Keymint Service + addService(card);