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