diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index c50065ee..3a3d4983 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -49,7 +49,7 @@ 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_RKP_UNIQUE_DEVICE_KEYPAIR_CMD = + private static final byte INS_PROVISION_RKP_DEVICE_UNIQUE_KEYPAIR_CMD = INS_KEYMINT_PROVIDER_APDU_START + 6; private static final byte INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD = INS_KEYMINT_PROVIDER_APDU_START + 7; @@ -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_UNIQUE_DEVICE_KEYPAIR = 0x40; + private static final byte PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR = 0x40; private static final byte PROVISION_STATUS_ADDITIONAL_CERT_CHAIN = (byte) 0x80; public static final short SHARED_SECRET_KEY_SIZE = 32; @@ -159,12 +159,12 @@ public void process(APDU apdu) { processSetBootParamsCmd(apdu); break; - case INS_PROVISION_RKP_UNIQUE_DEVICE_KEYPAIR_CMD: - processProvisionDeviceUniqueKeyPair(apdu); + case INS_PROVISION_RKP_DEVICE_UNIQUE_KEYPAIR_CMD: + processProvisionRkpDeviceUniqueKeyPair(apdu); break; case INS_PROVISION_RKP_ADDITIONAL_CERT_CHAIN_CMD: - processProvisionAdditionalCertChain(apdu); + processProvisionRkpAdditionalCertChain(apdu); break; default: @@ -189,7 +189,7 @@ public void process(APDU apdu) { } } - private static void processProvisionDeviceUniqueKeyPair(APDU apdu) { + private static void processProvisionRkpDeviceUniqueKeyPair(APDU apdu) { // Re-purpose the apdu buffer as scratch pad. byte[] scratchPad = apdu.getBuffer(); short arr = KMArray.instance((short) 1); @@ -201,17 +201,17 @@ private static void processProvisionDeviceUniqueKeyPair(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.createDeviceUniqueKeyPair(scratchPad, (short) 0, pubKeyLen, scratchPad, + kmDataStore.createRkpDeviceUniqueKeyPair(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_UNIQUE_DEVICE_KEYPAIR); + kmDataStore.setProvisionStatus(PROVISION_STATUS_DEVICE_UNIQUE_KEYPAIR); sendError(apdu, KMError.OK); } - private static void processProvisionAdditionalCertChain(APDU apdu) { + private static void processProvisionRkpAdditionalCertChain(APDU apdu) { // Prepare the expression to decode short headers = KMCoseHeaders.exp(); short arrInst = KMArray.instance((short) 4); @@ -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); - KMDeviceUniqueKeyPair uniqueKey = kmDataStore.getDeviceUniqueKeyPair(false); + KMDeviceUniqueKeyPair uniqueKey = kmDataStore.getRkpDeviceUniqueKeyPair(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_UNIQUE_DEVICE_KEYPAIR)) + if ((0 != (data[dInex] & PROVISION_STATUS_DEVICE_UNIQUE_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 12a6cbc2..ddaece5c 100644 --- a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java @@ -1108,7 +1108,7 @@ public short ecSign256(KMDeviceUniqueKeyPair ecPrivKey, byte[] inputDataBuf, } @Override - public KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(KMDeviceUniqueKeyPair key, + public KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair(KMDeviceUniqueKeyPair key, byte[] pubKey, short pubKeyOff, short pubKeyLen, byte[] privKey, short privKeyOff, short privKeyLen) { if (key == null) { diff --git a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKey.java b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKeyPair.java similarity index 94% rename from Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKey.java rename to Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKeyPair.java index 08e60a3f..9bbccd8f 100644 --- a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKey.java +++ b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKeyPair.java @@ -15,7 +15,7 @@ */ package com.android.javacard.seprovider; -public interface KMDeviceUniqueKey { +public interface KMDeviceUniqueKeyPair { short getPublicKey(byte[] buf, short offset); } diff --git a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java index 1fe1467a..c4445114 100644 --- a/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java +++ b/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java @@ -626,7 +626,7 @@ KMOperation initAsymmetricOperation( * @param privKeyLen private key buffer length. * @return instance of KMDeviceUniqueKey. */ - KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(KMDeviceUniqueKeyPair key, + KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair(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 c335bca0..754cdcdb 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -396,6 +396,9 @@ public void process(APDU apdu) { case INS_GENERATE_KEY_CMD: processGenerateKey(apdu); break; + case INS_ATTEST_KEY_CMD: + processAttestKeyCmd(apdu); + break; case INS_IMPORT_KEY_CMD: processImportKeyCmd(apdu); break; @@ -1283,7 +1286,8 @@ private KMAttestationCert makeAttestationCert(short attKeyBlob, short attKeyPara // Add Tags addTags(hwParameters, true, cert); - addTags(swParameters, false, cert); + short swParams = KMKeyParameters.makeKeystoreEnforced(data[KEY_PARAMETERS], scratchPad); + addTags(swParams, false, cert); // Add Device Boot locked status cert.deviceLocked(kmDataStore.isDeviceBootLocked()); // VB data @@ -1291,8 +1295,8 @@ private KMAttestationCert makeAttestationCert(short attKeyBlob, short attKeyPara 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; } @@ -3294,13 +3298,9 @@ protected void setVendorPatchLevel(short patch){ private short generateKeyCmd(APDU apdu){ short params = KMKeyParameters.expAny(); - short blob = KMByteBlob.exp(); // Array of expected arguments - short cmd = KMArray.instance((short) 4); + short cmd = KMArray.instance((short) 1); KMArray.cast(cmd).add((short) 0, params); //key params - KMArray.cast(cmd).add((short) 1, blob); //attest key - KMArray.cast(cmd).add((short) 2, params); //attest key params - KMArray.cast(cmd).add((short) 3, blob); //issuer return receiveIncoming(apdu, cmd); } @@ -3310,10 +3310,6 @@ private void processGenerateKey(APDU apdu) { // Re-purpose the apdu buffer as scratch pad. byte[] scratchPad = apdu.getBuffer(); data[KEY_PARAMETERS] = KMArray.cast(cmd).get((short) 0); - data[ATTEST_KEY_BLOB] = KMArray.cast(cmd).get((short) 1); - data[ATTEST_KEY_PARAMS] = KMArray.cast(cmd).get((short) 2); - data[ATTEST_KEY_ISSUER] = KMArray.cast(cmd).get((short) 3); - data[CERTIFICATE] = KMArray.instance((short)0); //by default the cert is empty. // ROLLBACK_RESISTANCE not supported. KMTag.assertAbsence(data[KEY_PARAMETERS], KMType.BOOL_TAG,KMType.ROLLBACK_RESISTANCE, KMError.ROLLBACK_RESISTANCE_UNAVAILABLE); @@ -3359,7 +3355,6 @@ private void processGenerateKey(APDU apdu) { // create key blob and associated attestation. data[ORIGIN] = KMType.GENERATED; makeKeyCharacteristics(scratchPad); - generateAttestation(data[ATTEST_KEY_BLOB], data[ATTEST_KEY_PARAMS],scratchPad); createEncryptedKeyBlob(scratchPad); // Remove custom tags from key characteristics short teeParams = KMKeyCharacteristics.cast(data[KEY_CHARACTERISTICS]).getTeeEnforced(); @@ -3367,14 +3362,77 @@ private void processGenerateKey(APDU apdu) { KMKeyParameters.cast(teeParams).deleteCustomTags(); } // prepare the response - short resp = KMArray.instance((short) 4); + short resp = KMArray.instance((short) 3); KMArray.cast(resp).add((short) 0, KMInteger.uint_16(KMError.OK)); KMArray.cast(resp).add((short) 1, data[KEY_BLOB]); KMArray.cast(resp).add((short) 2, data[KEY_CHARACTERISTICS]); - KMArray.cast(resp).add((short) 3, data[CERTIFICATE]); sendOutgoing(apdu, resp); } + private short generateAttestKeyCmd(APDU apdu) { + short params = KMKeyParameters.expAny(); + short blob = KMByteBlob.exp(); + // Array of expected arguments + short cmd = KMArray.instance((short) 5); + KMArray.cast(cmd).add((short) 0, blob); // key blob + KMArray.cast(cmd).add((short) 1, params); // keyparamters to be attested. + KMArray.cast(cmd).add((short) 2, blob); // attest key blob + KMArray.cast(cmd).add((short) 3, params); // attest key params + KMArray.cast(cmd).add((short) 4, blob); // attest issuer + + return receiveIncoming(apdu, cmd); + } + + public void getAttestKeyInputParameters(short arrPtr, short[] data, byte keyBlobOff, + byte keyParametersOff, + byte attestKeyBlobOff, byte attestKeyParamsOff, byte attestKeyIssuerOff) { + data[keyBlobOff] = KMArray.cast(arrPtr).get((short) 0); + data[keyParametersOff] = KMArray.cast(arrPtr).get((short) 1); + data[attestKeyBlobOff] = KMType.INVALID_VALUE; + data[attestKeyParamsOff] = KMType.INVALID_VALUE; + data[attestKeyIssuerOff] = KMType.INVALID_VALUE; + } + + private void processAttestKeyCmd(APDU apdu) { + // Receive the incoming request fully from the master into buffer. + short cmd = generateAttestKeyCmd(apdu); + // Re-purpose the apdu buffer as scratch pad. + byte[] scratchPad = apdu.getBuffer(); + data[KEY_BLOB] = KMArray.cast(cmd).get((short) 0); + data[KEY_PARAMETERS] = KMArray.cast(cmd).get((short) 1); + data[ATTEST_KEY_BLOB] = KMArray.cast(cmd).get((short) 2); + data[ATTEST_KEY_PARAMS] = KMArray.cast(cmd).get((short) 3); + data[ATTEST_KEY_ISSUER] = KMArray.cast(cmd).get((short) 4); + + data[CERTIFICATE] = KMArray.instance((short) 0); //by default the cert is empty. + + // Check for app id and app data. + data[APP_ID] = + KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.APPLICATION_ID, data[KEY_PARAMETERS]); + data[APP_DATA] = + KMKeyParameters.findTag(KMType.BYTES_TAG, KMType.APPLICATION_DATA, data[KEY_PARAMETERS]); + if (data[APP_ID] != KMTag.INVALID_VALUE) { + data[APP_ID] = KMByteTag.cast(data[APP_ID]).getValue(); + } + if (data[APP_DATA] != KMTag.INVALID_VALUE) { + data[APP_DATA] = KMByteTag.cast(data[APP_DATA]).getValue(); + } + // parse key blob + parseEncryptedKeyBlob(data[KEY_BLOB], data[APP_ID], data[APP_DATA], scratchPad); + // The key which is being attested should be asymmetric i.e. RSA or EC + short alg = KMEnumTag.getValue(KMType.ALGORITHM, data[HW_PARAMETERS]); + if (alg != KMType.RSA && alg != KMType.EC) { + KMException.throwIt(KMError.INCOMPATIBLE_ALGORITHM); + } + // Build certificate + generateAttestation(data[ATTEST_KEY_BLOB], data[ATTEST_KEY_PARAMS], scratchPad); + + short resp = KMArray.instance((short) 2); + KMArray.cast(resp).add((short) 0, KMInteger.uint_16(KMError.OK)); + KMArray.cast(resp).add((short) 1, data[CERTIFICATE]); + sendOutgoing(apdu, resp); + } + private short getAttestationMode(short attKeyBlob, short attChallenge){ short alg = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, data[KEY_PARAMETERS]); short mode = KMType.NO_CERT; @@ -3419,7 +3477,7 @@ private void generateAttestation(short attKeyBlob, short attKeyParam, byte[] sc switch (mode){ case KMType.ATTESTATION_CERT: - cert = makeAttestationCert(attKeyBlob,attKeyParam, attChallenge, data[ATTEST_KEY_ISSUER],data[HW_PARAMETERS], + cert = makeAttestationCert(attKeyBlob, attKeyParam, attChallenge, data[ATTEST_KEY_ISSUER],data[HW_PARAMETERS], data[SW_PARAMETERS], scratchPad); break; case KMType.SELF_SIGNED_CERT: @@ -3838,7 +3896,7 @@ private static void makeAuthData(byte[] scratchPad) { KMArray.cast(params).add((short) 2, data[PUB_KEY]); } - short authIndex = repository.alloc(MAX_AUTH_DATA_SIZE); + short authIndex = repository.allocReclaimableMemory(MAX_AUTH_DATA_SIZE); short index = 0; short len = 0; short paramsLen = KMArray.cast(params).length(); @@ -3855,7 +3913,10 @@ private static void makeAuthData(byte[] scratchPad) { } index++; } - data[AUTH_DATA] = authIndex; + short authDataIndex = repository.alloc(len); + Util.arrayCopyNonAtomic(repository.getHeap(), authIndex, repository.getHeap(), authDataIndex, len); + repository.reclaimMemory(MAX_AUTH_DATA_SIZE); + data[AUTH_DATA] = authDataIndex; data[AUTH_DATA_LENGTH] = len; } @@ -4055,7 +4116,7 @@ public static short generateBcc(boolean testMode, byte[] scratchPad) { if (!testMode && kmDataStore.isProvisionLocked()) { KMException.throwIt(KMError.STATUS_FAILED); } - KMDeviceUniqueKeyPair deviceUniqueKey = kmDataStore.getDeviceUniqueKeyPair(testMode); + KMDeviceUniqueKeyPair deviceUniqueKey = kmDataStore.getRkpDeviceUniqueKeyPair(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 5f643ba5..2a1f24e8 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -530,35 +530,35 @@ public KMComputedHmacKey getComputedHmacKey() { return computedHmacKey; } - public KMDeviceUniqueKeyPair createTestDeviceUniqueKeyPair(byte[] pubKey, short pubKeyOff, short pubKeyLen, + public KMDeviceUniqueKeyPair createRkpTestDeviceUniqueKeyPair(byte[] pubKey, short pubKeyOff, short pubKeyLen, byte[] privKey, short privKeyOff, short privKeyLen) { if (testDeviceUniqueKeyPair == null) { - testDeviceUniqueKeyPair = seProvider.createDeviceUniqueKeyPair(testDeviceUniqueKeyPair, pubKey, pubKeyOff, + testDeviceUniqueKeyPair = seProvider.createRkpDeviceUniqueKeyPair(testDeviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, privKeyOff, privKeyLen); } else { - seProvider.createDeviceUniqueKeyPair(testDeviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, + seProvider.createRkpDeviceUniqueKeyPair(testDeviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, privKeyOff, privKeyLen); } return testDeviceUniqueKeyPair; } - public KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(byte[] pubKey, short pubKeyOff, short pubKeyLen, + public KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair(byte[] pubKey, short pubKeyOff, short pubKeyLen, byte[] privKey, short privKeyOff, short privKeyLen) { if (deviceUniqueKeyPair == null) { - deviceUniqueKeyPair = seProvider.createDeviceUniqueKeyPair(deviceUniqueKeyPair, pubKey, pubKeyOff, + deviceUniqueKeyPair = seProvider.createRkpDeviceUniqueKeyPair(deviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, privKeyOff, privKeyLen); } else { - seProvider.createDeviceUniqueKeyPair(deviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, + seProvider.createRkpDeviceUniqueKeyPair(deviceUniqueKeyPair, pubKey, pubKeyOff, pubKeyLen, privKey, privKeyOff, privKeyLen); } return deviceUniqueKeyPair; } - public KMDeviceUniqueKeyPair getDeviceUniqueKeyPair(boolean testMode) { + public KMDeviceUniqueKeyPair getRkpDeviceUniqueKeyPair(boolean testMode) { return ((KMDeviceUniqueKeyPair) (testMode ? testDeviceUniqueKeyPair : deviceUniqueKeyPair)); } diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 0a158878..1e6c8371 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -32,7 +32,7 @@ */ public class KMRepository { - public static final short HEAP_SIZE = 15000; + public static final short HEAP_SIZE = 10000; // Class Attributes private byte[] heap; diff --git a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java index bb62d0ec..19ac6a82 100644 --- a/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java +++ b/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java @@ -813,10 +813,10 @@ private KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(boolean testMode, byte[] (short) 128, lengths); deviceUniqueKeyPair = - storeDataInst.createTestDeviceUniqueKeyPair(scratchPad, (short) 128, lengths[1], + storeDataInst.createRkpTestDeviceUniqueKeyPair(scratchPad, (short) 128, lengths[1], scratchPad, (short) 0, lengths[0]); } else { - deviceUniqueKeyPair = storeDataInst.getDeviceUniqueKeyPair(false); + deviceUniqueKeyPair = storeDataInst.getRkpDeviceUniqueKeyPair(false); } return deviceUniqueKeyPair; } diff --git a/HAL/JavacardKeyMintDevice.cpp b/HAL/JavacardKeyMintDevice.cpp index 584c75ed..faa1cd43 100644 --- a/HAL/JavacardKeyMintDevice.cpp +++ b/HAL/JavacardKeyMintDevice.cpp @@ -33,6 +33,7 @@ #include namespace aidl::android::hardware::security::keymint { +using km_utils::KmParamSet; using namespace ::keymaster; using namespace ::keymint::javacard; @@ -81,19 +82,37 @@ ScopedAStatus JavacardKeyMintDevice::generateKey(const vector& key cppbor::Array array; // add key params cbor_.addKeyparameters(array, keyParams); - // add attestation key if any - cbor_.addAttestationKey(array, attestationKey); auto [item, err] = card_->sendRequest(Instruction::INS_GENERATE_KEY_CMD, array); if (err != KM_ERROR_OK) { LOG(ERROR) << "Error in sending generateKey."; return km_utils::kmError2ScopedAStatus(err); } if (!cbor_.getBinaryArray(item, 1, creationResult->keyBlob) || - !cbor_.getKeyCharacteristics(item, 2, creationResult->keyCharacteristics) || - !cbor_.getCertificateChain(item, 3, creationResult->certificateChain)) { + !cbor_.getKeyCharacteristics(item, 2, creationResult->keyCharacteristics)) { LOG(ERROR) << "Error in decoding og response in generateKey."; return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR); } + + AuthorizationSet paramSet; + paramSet.Reinitialize(KmParamSet(keyParams)); + // Call attestKey only Asymmetric algorithms. + keymaster_algorithm_t algorithm; + paramSet.GetTagValue(TAG_ALGORITHM, &algorithm); + if (algorithm == KM_ALGORITHM_RSA || algorithm == KM_ALGORITHM_EC) { + cppbor::Array attestKeyArray; + attestKeyArray.add(creationResult->keyBlob); + cbor_.addKeyparameters(attestKeyArray, keyParams); + cbor_.addAttestationKey(attestKeyArray, attestationKey); + auto [item, err] = card_->sendRequest(Instruction::INS_ATTEST_KEY_CMD, attestKeyArray); + if (err != KM_ERROR_OK) { + LOG(ERROR) << "Failed in attestKey err: "; + return km_utils::kmError2ScopedAStatus(err); + } + if (!cbor_.getCertificateChain(item, 1, creationResult->certificateChain)) { + LOG(ERROR) << "Error in decoding og response in generateKey."; + return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR); + } + } return ScopedAStatus::ok(); }