xref: /aosp_15_r20/external/libese/ready_se/google/keymint/KM200/HAL/JavacardKeyMintDevice.cpp (revision 5c4dab75aa57366379dce576b1a9e082a44e2b3a)
1 /*
2  * Copyright 2020, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "javacard.keymint.device.strongbox-impl"
18 
19 #include "JavacardKeyMintDevice.h"
20 
21 #include <regex.h>
22 
23 #include <algorithm>
24 #include <iostream>
25 #include <iterator>
26 #include <memory>
27 #include <string>
28 #include <vector>
29 
30 #include <KeyMintUtils.h>
31 #include <android-base/logging.h>
32 #include <android-base/properties.h>
33 #include <hardware/hw_auth_token.h>
34 #include <keymaster/android_keymaster_messages.h>
35 #include <keymaster/wrapped_key.h>
36 
37 #include "JavacardKeyMintOperation.h"
38 #include "JavacardSharedSecret.h"
39 
40 namespace aidl::android::hardware::security::keymint {
41 using cppbor::Bstr;
42 using cppbor::EncodedItem;
43 using cppbor::Uint;
44 using ::keymaster::AuthorizationSet;
45 using ::keymaster::dup_buffer;
46 using ::keymaster::KeymasterBlob;
47 using ::keymaster::KeymasterKeyBlob;
48 using ::keymint::javacard::Instruction;
49 using std::string;
50 
defaultHwInfo(KeyMintHardwareInfo * info)51 ScopedAStatus JavacardKeyMintDevice::defaultHwInfo(KeyMintHardwareInfo* info) {
52     info->versionNumber = 2;
53     info->keyMintAuthorName = "Google";
54     info->keyMintName = "JavacardKeymintDevice";
55     info->securityLevel = securitylevel_;
56     info->timestampTokenRequired = true;
57     return ScopedAStatus::ok();
58 }
59 
getHardwareInfo(KeyMintHardwareInfo * info)60 ScopedAStatus JavacardKeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* info) {
61     auto [item, err] = card_->sendRequest(Instruction::INS_GET_HW_INFO_CMD);
62     std::optional<string> optKeyMintName;
63     std::optional<string> optKeyMintAuthorName;
64     std::optional<uint64_t> optSecLevel;
65     std::optional<uint64_t> optVersion;
66     std::optional<uint64_t> optTsRequired;
67     if (err != KM_ERROR_OK || !(optVersion = cbor_.getUint64(item, 1)) ||
68         !(optSecLevel = cbor_.getUint64(item, 2)) ||
69         !(optKeyMintName = cbor_.getByteArrayStr(item, 3)) ||
70         !(optKeyMintAuthorName = cbor_.getByteArrayStr(item, 4)) ||
71         !(optTsRequired = cbor_.getUint64(item, 5))) {
72         LOG(ERROR) << "Error in response of getHardwareInfo.";
73         LOG(INFO) << "Returning defaultHwInfo in getHardwareInfo.";
74         return defaultHwInfo(info);
75     }
76     card_->initializeJavacard();
77     info->keyMintName = std::move(optKeyMintName.value());
78     info->keyMintAuthorName = std::move(optKeyMintAuthorName.value());
79     info->timestampTokenRequired = (optTsRequired.value() == 1);
80     info->securityLevel = static_cast<SecurityLevel>(std::move(optSecLevel.value()));
81     info->versionNumber = static_cast<int32_t>(std::move(optVersion.value()));
82     return ScopedAStatus::ok();
83 }
84 
generateKey(const vector<KeyParameter> & keyParams,const optional<AttestationKey> & attestationKey,KeyCreationResult * creationResult)85 ScopedAStatus JavacardKeyMintDevice::generateKey(const vector<KeyParameter>& keyParams,
86                                                  const optional<AttestationKey>& attestationKey,
87                                                  KeyCreationResult* creationResult) {
88     card_->sendPendingEvents();
89     cppbor::Array array;
90     // add key params
91     cbor_.addKeyparameters(array, keyParams);
92     // add attestation key if any
93     cbor_.addAttestationKey(array, attestationKey);
94     auto [item, err] = card_->sendRequest(Instruction::INS_GENERATE_KEY_CMD, array);
95     if (err != KM_ERROR_OK) {
96         LOG(ERROR) << "Error in sending generateKey.";
97         return km_utils::kmError2ScopedAStatus(err);
98     }
99     auto optKeyBlob = cbor_.getByteArrayVec(item, 1);
100     auto optKeyChars = cbor_.getKeyCharacteristics(item, 2);
101     auto optCertChain = cbor_.getCertificateChain(item, 3);
102     if (!optKeyBlob || !optKeyChars || !optCertChain) {
103         LOG(ERROR) << "Error in decoding og response in generateKey.";
104         return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
105     }
106     creationResult->keyCharacteristics = std::move(optKeyChars.value());
107     creationResult->certificateChain = std::move(optCertChain.value());
108     creationResult->keyBlob = std::move(optKeyBlob.value());
109     return ScopedAStatus::ok();
110 }
111 
addRngEntropy(const vector<uint8_t> & data)112 ScopedAStatus JavacardKeyMintDevice::addRngEntropy(const vector<uint8_t>& data) {
113     cppbor::Array request;
114     // add key data
115     request.add(Bstr(data));
116     auto [item, err] = card_->sendRequest(Instruction::INS_ADD_RNG_ENTROPY_CMD, request);
117     if (err != KM_ERROR_OK) {
118         LOG(ERROR) << "Error in sending addRngEntropy.";
119         return km_utils::kmError2ScopedAStatus(err);
120     }
121     return ScopedAStatus::ok();
122 }
123 
importKey(const vector<KeyParameter> & keyParams,KeyFormat keyFormat,const vector<uint8_t> & keyData,const optional<AttestationKey> & attestationKey,KeyCreationResult * creationResult)124 ScopedAStatus JavacardKeyMintDevice::importKey(const vector<KeyParameter>& keyParams,
125                                                KeyFormat keyFormat, const vector<uint8_t>& keyData,
126                                                const optional<AttestationKey>& attestationKey,
127                                                KeyCreationResult* creationResult) {
128 
129     card_->sendPendingEvents();
130     cppbor::Array request;
131     // add key params
132     cbor_.addKeyparameters(request, keyParams);
133     // add key format
134     request.add(Uint(static_cast<uint8_t>(keyFormat)));
135     // add key data
136     request.add(Bstr(keyData));
137     // add attestation key if any
138     cbor_.addAttestationKey(request, attestationKey);
139 
140     auto [item, err] = card_->sendRequest(Instruction::INS_IMPORT_KEY_CMD, request);
141     if (err != KM_ERROR_OK) {
142         LOG(ERROR) << "Error in sending data in importKey.";
143         return km_utils::kmError2ScopedAStatus(err);
144     }
145     auto optKeyBlob = cbor_.getByteArrayVec(item, 1);
146     auto optKeyChars = cbor_.getKeyCharacteristics(item, 2);
147     auto optCertChain = cbor_.getCertificateChain(item, 3);
148     if (!optKeyBlob || !optKeyChars || !optCertChain) {
149         LOG(ERROR) << "Error in decoding response in importKey.";
150         return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
151     }
152     creationResult->keyCharacteristics = std::move(optKeyChars.value());
153     creationResult->certificateChain = std::move(optCertChain.value());
154     creationResult->keyBlob = std::move(optKeyBlob.value());
155     return ScopedAStatus::ok();
156 }
157 
158 // import wrapped key is divided into 2 stage operation.
importWrappedKey(const vector<uint8_t> & wrappedKeyData,const vector<uint8_t> & wrappingKeyBlob,const vector<uint8_t> & maskingKey,const vector<KeyParameter> & unwrappingParams,int64_t passwordSid,int64_t biometricSid,KeyCreationResult * creationResult)159 ScopedAStatus JavacardKeyMintDevice::importWrappedKey(const vector<uint8_t>& wrappedKeyData,
160                                                       const vector<uint8_t>& wrappingKeyBlob,
161                                                       const vector<uint8_t>& maskingKey,
162                                                       const vector<KeyParameter>& unwrappingParams,
163                                                       int64_t passwordSid, int64_t biometricSid,
164                                                       KeyCreationResult* creationResult) {
165     card_->sendPendingEvents();
166     cppbor::Array request;
167     std::unique_ptr<Item> item;
168     vector<uint8_t> keyBlob;
169     std::vector<uint8_t> response;
170     vector<KeyCharacteristics> keyCharacteristics;
171     std::vector<uint8_t> iv;
172     std::vector<uint8_t> transitKey;
173     std::vector<uint8_t> secureKey;
174     std::vector<uint8_t> tag;
175     vector<KeyParameter> authList;
176     KeyFormat keyFormat;
177     std::vector<uint8_t> wrappedKeyDescription;
178     keymaster_error_t errorCode = parseWrappedKey(wrappedKeyData, iv, transitKey, secureKey, tag,
179                                                   authList, keyFormat, wrappedKeyDescription);
180     if (errorCode != KM_ERROR_OK) {
181         LOG(ERROR) << "Error in parse wrapped key in importWrappedKey.";
182         return km_utils::kmError2ScopedAStatus(errorCode);
183     }
184 
185     // begin import
186     std::tie(item, errorCode) =
187         sendBeginImportWrappedKeyCmd(transitKey, wrappingKeyBlob, maskingKey, unwrappingParams);
188     if (errorCode != KM_ERROR_OK) {
189         LOG(ERROR) << "Error in send begin import wrapped key in importWrappedKey.";
190         return km_utils::kmError2ScopedAStatus(errorCode);
191     }
192     // Finish the import
193     std::tie(item, errorCode) = sendFinishImportWrappedKeyCmd(
194         authList, keyFormat, secureKey, tag, iv, wrappedKeyDescription, passwordSid, biometricSid);
195     if (errorCode != KM_ERROR_OK) {
196         LOG(ERROR) << "Error in send finish import wrapped key in importWrappedKey.";
197         return km_utils::kmError2ScopedAStatus(errorCode);
198     }
199     auto optKeyBlob = cbor_.getByteArrayVec(item, 1);
200     auto optKeyChars = cbor_.getKeyCharacteristics(item, 2);
201     auto optCertChain = cbor_.getCertificateChain(item, 3);
202     if (!optKeyBlob || !optKeyChars || !optCertChain) {
203         LOG(ERROR) << "Error in decoding the response in importWrappedKey.";
204         return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
205     }
206     creationResult->keyCharacteristics = std::move(optKeyChars.value());
207     creationResult->certificateChain = std::move(optCertChain.value());
208     creationResult->keyBlob = std::move(optKeyBlob.value());
209     return ScopedAStatus::ok();
210 }
211 
212 std::tuple<std::unique_ptr<Item>, keymaster_error_t>
sendBeginImportWrappedKeyCmd(const std::vector<uint8_t> & transitKey,const std::vector<uint8_t> & wrappingKeyBlob,const std::vector<uint8_t> & maskingKey,const vector<KeyParameter> & unwrappingParams)213 JavacardKeyMintDevice::sendBeginImportWrappedKeyCmd(const std::vector<uint8_t>& transitKey,
214                                                     const std::vector<uint8_t>& wrappingKeyBlob,
215                                                     const std::vector<uint8_t>& maskingKey,
216                                                     const vector<KeyParameter>& unwrappingParams) {
217     Array request;
218     request.add(std::vector<uint8_t>(transitKey));
219     request.add(std::vector<uint8_t>(wrappingKeyBlob));
220     request.add(std::vector<uint8_t>(maskingKey));
221     cbor_.addKeyparameters(request, unwrappingParams);
222     return card_->sendRequest(Instruction::INS_BEGIN_IMPORT_WRAPPED_KEY_CMD, request);
223 }
224 
225 std::tuple<std::unique_ptr<Item>, keymaster_error_t>
sendFinishImportWrappedKeyCmd(const vector<KeyParameter> & keyParams,KeyFormat keyFormat,const std::vector<uint8_t> & secureKey,const std::vector<uint8_t> & tag,const std::vector<uint8_t> & iv,const std::vector<uint8_t> & wrappedKeyDescription,int64_t passwordSid,int64_t biometricSid)226 JavacardKeyMintDevice::sendFinishImportWrappedKeyCmd(
227     const vector<KeyParameter>& keyParams, KeyFormat keyFormat,
228     const std::vector<uint8_t>& secureKey, const std::vector<uint8_t>& tag,
229     const std::vector<uint8_t>& iv, const std::vector<uint8_t>& wrappedKeyDescription,
230     int64_t passwordSid, int64_t biometricSid) {
231     Array request;
232     cbor_.addKeyparameters(request, keyParams);
233     request.add(static_cast<uint64_t>(keyFormat));
234     request.add(std::vector<uint8_t>(secureKey));
235     request.add(std::vector<uint8_t>(tag));
236     request.add(std::vector<uint8_t>(iv));
237     request.add(std::vector<uint8_t>(wrappedKeyDescription));
238     request.add(Uint(passwordSid));
239     request.add(Uint(biometricSid));
240     return card_->sendRequest(Instruction::INS_FINISH_IMPORT_WRAPPED_KEY_CMD, request);
241 }
242 
upgradeKey(const vector<uint8_t> & keyBlobToUpgrade,const vector<KeyParameter> & upgradeParams,vector<uint8_t> * keyBlob)243 ScopedAStatus JavacardKeyMintDevice::upgradeKey(const vector<uint8_t>& keyBlobToUpgrade,
244                                                 const vector<KeyParameter>& upgradeParams,
245                                                 vector<uint8_t>* keyBlob) {
246     card_->sendPendingEvents();
247     cppbor::Array request;
248     // add key blob
249     request.add(Bstr(keyBlobToUpgrade));
250     // add key params
251     cbor_.addKeyparameters(request, upgradeParams);
252     auto [item, err] = card_->sendRequest(Instruction::INS_UPGRADE_KEY_CMD, request);
253     if (err != KM_ERROR_OK) {
254         LOG(ERROR) << "Error in sending in upgradeKey.";
255         return km_utils::kmError2ScopedAStatus(err);
256     }
257     auto optKeyBlob = cbor_.getByteArrayVec(item, 1);
258     if (!optKeyBlob) {
259         LOG(ERROR) << "Error in decoding the response in upgradeKey.";
260         return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
261     }
262     *keyBlob = std::move(optKeyBlob.value());
263     return ScopedAStatus::ok();
264 }
265 
deleteKey(const vector<uint8_t> & keyBlob)266 ScopedAStatus JavacardKeyMintDevice::deleteKey(const vector<uint8_t>& keyBlob) {
267     Array request;
268     request.add(Bstr(keyBlob));
269     auto [item, err] = card_->sendRequest(Instruction::INS_DELETE_KEY_CMD, request);
270     if (err != KM_ERROR_OK) {
271         LOG(ERROR) << "Error in sending in deleteKey.";
272         return km_utils::kmError2ScopedAStatus(err);
273     }
274     return ScopedAStatus::ok();
275 }
276 
deleteAllKeys()277 ScopedAStatus JavacardKeyMintDevice::deleteAllKeys() {
278     auto [_, err] = card_->sendRequest(Instruction::INS_DELETE_ALL_KEYS_CMD);
279     if (err != KM_ERROR_OK) {
280         LOG(ERROR) << "Error in sending deleteAllKeys.";
281         card_->setDeleteAllKeysPending();
282         return km_utils::kmError2ScopedAStatus(err);
283     }
284     return ScopedAStatus::ok();
285 }
286 
destroyAttestationIds()287 ScopedAStatus JavacardKeyMintDevice::destroyAttestationIds() {
288     auto [item, err] = card_->sendRequest(Instruction::INS_DESTROY_ATT_IDS_CMD);
289     if (err != KM_ERROR_OK) {
290         LOG(ERROR) << "Error in sending in destroyAttestationIds.";
291         return km_utils::kmError2ScopedAStatus(err);
292     }
293     return ScopedAStatus::ok();
294 }
295 
begin(KeyPurpose purpose,const std::vector<uint8_t> & keyBlob,const std::vector<KeyParameter> & params,const std::optional<HardwareAuthToken> & authToken,BeginResult * result)296 ScopedAStatus JavacardKeyMintDevice::begin(KeyPurpose purpose, const std::vector<uint8_t>& keyBlob,
297                                            const std::vector<KeyParameter>& params,
298                                            const std::optional<HardwareAuthToken>& authToken,
299                                            BeginResult* result) {
300     card_->sendPendingEvents();
301     cppbor::Array array;
302     std::vector<uint8_t> response;
303     // make request
304     array.add(Uint(static_cast<uint64_t>(purpose)));
305     array.add(Bstr(keyBlob));
306     cbor_.addKeyparameters(array, params);
307     HardwareAuthToken token = authToken.value_or(HardwareAuthToken());
308     cbor_.addHardwareAuthToken(array, token);
309 
310     auto [item, err] = card_->sendRequest(Instruction::INS_BEGIN_OPERATION_CMD, array);
311     if (err != KM_ERROR_OK) {
312         LOG(ERROR) << "Error in sending in begin.";
313         return km_utils::kmError2ScopedAStatus(err);
314     }
315     // return the result
316     auto keyParams = cbor_.getKeyParameters(item, 1);
317     auto optOpHandle = cbor_.getUint64(item, 2);
318     auto optBufMode = cbor_.getUint64(item, 3);
319     auto optMacLength = cbor_.getUint64(item, 4);
320 
321     if (!keyParams || !optOpHandle || !optBufMode || !optMacLength) {
322         LOG(ERROR) << "Error in decoding the response in begin.";
323         return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
324     }
325     result->params = std::move(keyParams.value());
326     result->challenge = optOpHandle.value();
327     result->operation = ndk::SharedRefBase::make<JavacardKeyMintOperation>(
328         static_cast<keymaster_operation_handle_t>(optOpHandle.value()),
329         static_cast<BufferingMode>(optBufMode.value()), optMacLength.value(), card_);
330     return ScopedAStatus::ok();
331 }
332 
333 ScopedAStatus
deviceLocked(bool passwordOnly,const std::optional<TimeStampToken> & timestampToken)334 JavacardKeyMintDevice::deviceLocked(bool passwordOnly,
335                                     const std::optional<TimeStampToken>& timestampToken) {
336     Array request;
337     int8_t password = 1;
338     if (!passwordOnly) {
339         password = 0;
340     }
341     request.add(Uint(password));
342     cbor_.addTimeStampToken(request, timestampToken.value_or(TimeStampToken()));
343     auto [item, err] = card_->sendRequest(Instruction::INS_DEVICE_LOCKED_CMD, request);
344     if (err != KM_ERROR_OK) {
345         return km_utils::kmError2ScopedAStatus(err);
346     }
347     return ScopedAStatus::ok();
348 }
349 
earlyBootEnded()350 ScopedAStatus JavacardKeyMintDevice::earlyBootEnded() {
351     auto [_, err] = card_->sendRequest(Instruction::INS_EARLY_BOOT_ENDED_CMD);
352     if (err != KM_ERROR_OK) {
353         LOG(ERROR) << "Error in sending earlyBootEnded.";
354         card_->setEarlyBootEndedPending();
355         return km_utils::kmError2ScopedAStatus(err);
356     }
357     return ScopedAStatus::ok();
358 }
359 
getKeyCharacteristics(const std::vector<uint8_t> & keyBlob,const std::vector<uint8_t> & appId,const std::vector<uint8_t> & appData,std::vector<KeyCharacteristics> * result)360 ScopedAStatus JavacardKeyMintDevice::getKeyCharacteristics(
361     const std::vector<uint8_t>& keyBlob, const std::vector<uint8_t>& appId,
362     const std::vector<uint8_t>& appData, std::vector<KeyCharacteristics>* result) {
363     card_->sendPendingEvents();
364     cppbor::Array request;
365     request.add(vector<uint8_t>(keyBlob));
366     request.add(vector<uint8_t>(appId));
367     request.add(vector<uint8_t>(appData));
368     auto [item, err] = card_->sendRequest(Instruction::INS_GET_KEY_CHARACTERISTICS_CMD, request);
369     if (err != KM_ERROR_OK) {
370         LOG(ERROR) << "Error in sending in getKeyCharacteristics.";
371         return km_utils::kmError2ScopedAStatus(err);
372     }
373     auto optKeyChars = cbor_.getKeyCharacteristics(item, 1);
374     if (!optKeyChars) {
375         LOG(ERROR) << "Error in sending in upgradeKey.";
376         return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
377     }
378     *result = std::move(optKeyChars.value());
379     return ScopedAStatus::ok();
380 }
381 
382 keymaster_error_t
parseWrappedKey(const vector<uint8_t> & wrappedKeyData,std::vector<uint8_t> & iv,std::vector<uint8_t> & transitKey,std::vector<uint8_t> & secureKey,std::vector<uint8_t> & tag,vector<KeyParameter> & authList,KeyFormat & keyFormat,std::vector<uint8_t> & wrappedKeyDescription)383 JavacardKeyMintDevice::parseWrappedKey(const vector<uint8_t>& wrappedKeyData,
384                                        std::vector<uint8_t>& iv, std::vector<uint8_t>& transitKey,
385                                        std::vector<uint8_t>& secureKey, std::vector<uint8_t>& tag,
386                                        vector<KeyParameter>& authList, KeyFormat& keyFormat,
387                                        std::vector<uint8_t>& wrappedKeyDescription) {
388     KeymasterBlob kmIv;
389     KeymasterKeyBlob kmTransitKey;
390     KeymasterKeyBlob kmSecureKey;
391     KeymasterBlob kmTag;
392     AuthorizationSet authSet;
393     keymaster_key_format_t kmKeyFormat;
394     KeymasterBlob kmWrappedKeyDescription;
395 
396     size_t keyDataLen = wrappedKeyData.size();
397     uint8_t* keyData = dup_buffer(wrappedKeyData.data(), keyDataLen);
398     keymaster_key_blob_t keyMaterial = {keyData, keyDataLen};
399     keymaster_error_t error =
400         parse_wrapped_key(KeymasterKeyBlob(keyMaterial), &kmIv, &kmTransitKey, &kmSecureKey, &kmTag,
401                           &authSet, &kmKeyFormat, &kmWrappedKeyDescription);
402     if (error != KM_ERROR_OK) {
403         LOG(ERROR) << "Error parsing wrapped key.";
404         return error;
405     }
406     iv = km_utils::kmBlob2vector(kmIv);
407     transitKey = km_utils::kmBlob2vector(kmTransitKey);
408     secureKey = km_utils::kmBlob2vector(kmSecureKey);
409     tag = km_utils::kmBlob2vector(kmTag);
410     authList = km_utils::kmParamSet2Aidl(authSet);
411     keyFormat = static_cast<KeyFormat>(kmKeyFormat);
412     wrappedKeyDescription = km_utils::kmBlob2vector(kmWrappedKeyDescription);
413     return KM_ERROR_OK;
414 }
415 
convertStorageKeyToEphemeral(const std::vector<uint8_t> &,std::vector<uint8_t> *)416 ScopedAStatus JavacardKeyMintDevice::convertStorageKeyToEphemeral(
417     const std::vector<uint8_t>& /* storageKeyBlob */,
418     std::vector<uint8_t>* /* ephemeralKeyBlob */) {
419     return km_utils::kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
420 }
421 
getRootOfTrustChallenge(array<uint8_t,16> * challenge)422 ScopedAStatus JavacardKeyMintDevice::getRootOfTrustChallenge(array<uint8_t, 16>* challenge) {
423     auto [item, err] = card_->sendRequest(Instruction::INS_GET_ROT_CHALLENGE_CMD);
424     if (err != KM_ERROR_OK) {
425         LOG(ERROR) << "Error in sending in getRootOfTrustChallenge.";
426         return km_utils::kmError2ScopedAStatus(err);
427     }
428     auto optChallenge = cbor_.getByteArrayVec(item, 1);
429     if (!optChallenge) {
430         LOG(ERROR) << "Error in sending in upgradeKey.";
431         return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
432     }
433     std::move(optChallenge->begin(), optChallenge->begin() + 16, challenge->begin());
434     return ScopedAStatus::ok();
435 }
436 
getRootOfTrust(const array<uint8_t,16> &,vector<uint8_t> *)437 ScopedAStatus JavacardKeyMintDevice::getRootOfTrust(const array<uint8_t, 16>& /*challenge*/,
438                                                     vector<uint8_t>* /*rootOfTrust*/) {
439     return km_utils::kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
440 }
441 
sendRootOfTrust(const vector<uint8_t> & rootOfTrust)442 ScopedAStatus JavacardKeyMintDevice::sendRootOfTrust(const vector<uint8_t>& rootOfTrust) {
443     cppbor::Array request;
444     request.add(EncodedItem(rootOfTrust));  // taggedItem.
445     auto [item, err] = card_->sendRequest(Instruction::INS_SEND_ROT_DATA_CMD, request);
446     if (err != KM_ERROR_OK) {
447         LOG(ERROR) << "Error in sending in sendRootOfTrust.";
448         return km_utils::kmError2ScopedAStatus(err);
449     }
450     LOG(INFO) << "JavacardKeyMintDevice::sendRootOfTrust success";
451     return ScopedAStatus::ok();
452 }
453 
454 }  // namespace aidl::android::hardware::security::keymint
455