blob: 1002b8d5a94e8969737480abdbfc8f8cc17060f5 [file] [log] [blame]
Janis Danisevskisff3d7f42018-10-08 07:15:09 -07001/*
2**
3** Copyright 2018, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17#define LOG_TAG "keymaster_worker"
18
19#include "keymaster_worker.h"
20
21#include "keystore_utils.h"
22
23#include <android-base/logging.h>
24
25#include "KeyStore.h"
26#include "keymaster_enforcement.h"
27
28#include "key_proto_handler.h"
29#include "keystore_utils.h"
30
31namespace keystore {
32
33constexpr size_t kMaxOperations = 15;
34
35using AndroidKeymasterArguments = android::security::keymaster::KeymasterArguments;
36using android::security::keymaster::ExportResult;
37using android::security::keymaster::operationFailed;
38using android::security::keymaster::OperationResult;
39
40Worker::Worker() {
41 worker_ = std::thread([this] {
42 std::unique_lock<std::mutex> lock(pending_requests_mutex_);
43 running_ = true;
44 while (running_) {
45 pending_requests_cond_var_.wait(
46 lock, [this]() { return !pending_requests_.empty() || !running_; });
47 if (!running_) break;
48 auto request = std::move(pending_requests_.front());
49 pending_requests_.pop();
50 lock.unlock();
51 request();
52 lock.lock();
53 }
54 });
55}
56Worker::~Worker() {
57 if (worker_.joinable()) {
58 running_ = false;
59 pending_requests_cond_var_.notify_all();
60 worker_.join();
61 }
62}
63void Worker::addRequest(WorkerTask request) {
64 std::unique_lock<std::mutex> lock(pending_requests_mutex_);
65 pending_requests_.push(std::move(request));
66 lock.unlock();
67 pending_requests_cond_var_.notify_all();
68}
69
70KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore)
71 : keymasterDevice_(std::move(keymasterDevice)), operationMap_(keyStore), keyStore_(keyStore) {
72 // make sure that hal version is cached.
73 if (keymasterDevice_) keymasterDevice_->halVersion();
74}
75
76std::tuple<KeyStoreServiceReturnCode, Blob>
77KeymasterWorker::upgradeKeyBlob(const LockedKeyBlobEntry& lockedEntry,
78 const AuthorizationSet& params) {
79 LOG(INFO) << "upgradeKeyBlob " << lockedEntry->alias() << " " << (uint32_t)lockedEntry->uid();
80
81 std::tuple<KeyStoreServiceReturnCode, Blob> result;
82
83 auto userState = keyStore_->getUserStateDB().getUserStateByUid(lockedEntry->uid());
84
85 Blob& blob = std::get<1>(result);
86 KeyStoreServiceReturnCode& error = std::get<0>(result);
87
88 Blob charBlob;
89 ResponseCode rc;
90
91 std::tie(rc, blob, charBlob) =
92 lockedEntry.readBlobs(userState->getEncryptionKey(), userState->getState());
93
94 if (rc != ResponseCode::NO_ERROR) {
95 return error = rc, result;
96 }
97
98 auto hidlKey = blob2hidlVec(blob);
99 auto& dev = keymasterDevice_;
100
101 auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& upgradedKeyBlob) {
102 error = ret;
103 if (!error.isOk()) {
104 if (error == ErrorCode::INVALID_KEY_BLOB) {
105 log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
106 }
107 return;
108 }
109
110 error = keyStore_->del(lockedEntry);
111 if (!error.isOk()) {
112 ALOGI("upgradeKeyBlob keystore->del failed %d", (int)error);
113 return;
114 }
115
116 Blob newBlob(&upgradedKeyBlob[0], upgradedKeyBlob.size(), nullptr /* info */,
117 0 /* infoLength */, ::TYPE_KEYMASTER_10);
118 newBlob.setSecurityLevel(blob.getSecurityLevel());
119 newBlob.setEncrypted(blob.isEncrypted());
120 newBlob.setSuperEncrypted(blob.isSuperEncrypted());
121 newBlob.setCriticalToDeviceEncryption(blob.isCriticalToDeviceEncryption());
122
123 error = keyStore_->put(lockedEntry, newBlob, charBlob);
124 if (!error.isOk()) {
125 ALOGI("upgradeKeyBlob keystore->put failed %d", (int)error);
126 return;
127 }
128 blob = std::move(newBlob);
129 };
130
131 KeyStoreServiceReturnCode error2;
132 error2 = KS_HANDLE_HIDL_ERROR(dev->upgradeKey(hidlKey, params.hidl_data(), hidlCb));
133 if (!error2.isOk()) {
134 return error = error2, result;
135 }
136
137 return result;
138}
139
140std::tuple<KeyStoreServiceReturnCode, KeyCharacteristics, Blob, Blob>
141KeymasterWorker::createKeyCharacteristicsCache(const LockedKeyBlobEntry& lockedEntry,
142 const hidl_vec<uint8_t>& clientId,
143 const hidl_vec<uint8_t>& appData, Blob keyBlob,
144 Blob charBlob) {
145 std::tuple<KeyStoreServiceReturnCode, KeyCharacteristics, Blob, Blob> result;
146
147#if __cplusplus == 201703L
148 auto& [rc, resultCharacteristics, outBlob, charOutBlob] = result;
149#else
150 KeyStoreServiceReturnCode& rc = std::get<0>(result);
151 KeyCharacteristics& resultCharacteristics = std::get<1>(result);
152 Blob& outBlob = std::get<2>(result);
153 Blob& charOutBlob = std::get<3>(result);
154#endif
155
156 rc = ResponseCode::SYSTEM_ERROR;
157 if (!keyBlob) return result;
158 auto hidlKeyBlob = blob2hidlVec(keyBlob);
159 auto& dev = keymasterDevice_;
160
161 KeyStoreServiceReturnCode error;
162
163 AuthorizationSet hwEnforced, swEnforced;
164 bool success = true;
165
166 if (charBlob) {
167 std::tie(success, hwEnforced, swEnforced) = charBlob.getKeyCharacteristics();
168 }
169 if (!success) {
170 LOG(ERROR) << "Failed to read cached key characteristics";
171 return rc = ResponseCode::SYSTEM_ERROR, result;
172 }
173
174 auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
175 error = ret;
176 if (!error.isOk()) {
177 if (error == ErrorCode::INVALID_KEY_BLOB) {
178 log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
179 }
180 return;
181 }
182
183 // Replace the sw_enforced set with those persisted to disk, minus hw_enforced
184 AuthorizationSet softwareEnforced = keyCharacteristics.softwareEnforced;
185 hwEnforced = keyCharacteristics.hardwareEnforced;
186 swEnforced.Union(softwareEnforced);
187 softwareEnforced.Subtract(hwEnforced);
188
189 // We only get the characteristics from keymaster if there was no cache file or the
190 // the chach file was a legacy cache file. So lets write a new cache file for the next time.
191 Blob newCharBlob;
192 success = newCharBlob.putKeyCharacteristics(hwEnforced, swEnforced);
193 if (!success) {
194 error = ResponseCode::SYSTEM_ERROR;
195 LOG(ERROR) << "Failed to serialize cached key characteristics";
196 return;
197 }
198
199 error = keyStore_->put(lockedEntry, {}, newCharBlob);
200 if (!error.isOk()) {
201 ALOGE("Failed to write key characteristics cache");
202 return;
203 }
204 charBlob = std::move(newCharBlob);
205 };
206
207 if (!charBlob || charBlob.getType() == TYPE_KEY_CHARACTERISTICS) {
208 // this updates the key characteristics cache file to the new format or creates one in
209 // in the first place
210 rc = KS_HANDLE_HIDL_ERROR(
211 dev->getKeyCharacteristics(hidlKeyBlob, clientId, appData, hidlCb));
212 if (!rc.isOk()) {
213 return result;
214 }
215
216 if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
217 AuthorizationSet upgradeParams;
218 if (clientId.size()) {
219 upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
220 }
221 if (appData.size()) {
222 upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
223 }
224 std::tie(rc, keyBlob) = upgradeKeyBlob(lockedEntry, upgradeParams);
225 if (!rc.isOk()) {
226 return result;
227 }
228
229 auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
230
231 rc = KS_HANDLE_HIDL_ERROR(
232 dev->getKeyCharacteristics(upgradedHidlKeyBlob, clientId, appData, hidlCb));
233 if (!rc.isOk()) {
234 return result;
235 }
236 }
237 }
238
239 resultCharacteristics.hardwareEnforced = hwEnforced.hidl_data();
240 resultCharacteristics.softwareEnforced = swEnforced.hidl_data();
241
242 outBlob = std::move(keyBlob);
243 charOutBlob = std::move(charBlob);
244 rc = error;
245 return result;
246}
247
248/**
249 * Get the auth token for this operation from the auth token table.
250 *
251 * Returns ResponseCode::NO_ERROR if the auth token was set or none was required.
252 * ::OP_AUTH_NEEDED if it is a per op authorization, no
253 * authorization token exists for that operation and
254 * failOnTokenMissing is false.
255 * KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
256 * token for the operation
257 */
258std::pair<KeyStoreServiceReturnCode, HardwareAuthToken>
259KeymasterWorker::getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle,
260 KeyPurpose purpose, bool failOnTokenMissing) {
261
262 AuthorizationSet allCharacteristics(characteristics.softwareEnforced);
263 allCharacteristics.append(characteristics.hardwareEnforced.begin(),
264 characteristics.hardwareEnforced.end());
265
266 HardwareAuthToken authToken;
267 AuthTokenTable::Error err;
268 std::tie(err, authToken) = keyStore_->getAuthTokenTable().FindAuthorization(
269 allCharacteristics, static_cast<KeyPurpose>(purpose), handle);
270
271 KeyStoreServiceReturnCode rc;
272
273 switch (err) {
274 case AuthTokenTable::OK:
275 case AuthTokenTable::AUTH_NOT_REQUIRED:
276 rc = ResponseCode::NO_ERROR;
277 break;
278
279 case AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
280 case AuthTokenTable::AUTH_TOKEN_EXPIRED:
281 case AuthTokenTable::AUTH_TOKEN_WRONG_SID:
282 ALOGE("getAuthToken failed: %d", err); // STOPSHIP: debug only, to be removed
283 rc = ErrorCode::KEY_USER_NOT_AUTHENTICATED;
284 break;
285
286 case AuthTokenTable::OP_HANDLE_REQUIRED:
287 rc = failOnTokenMissing ? KeyStoreServiceReturnCode(ErrorCode::KEY_USER_NOT_AUTHENTICATED)
288 : KeyStoreServiceReturnCode(ResponseCode::OP_AUTH_NEEDED);
289 break;
290
291 default:
292 ALOGE("Unexpected FindAuthorization return value %d", err);
293 rc = ErrorCode::INVALID_ARGUMENT;
294 }
295
296 return {rc, std::move(authToken)};
297}
298
299KeyStoreServiceReturnCode KeymasterWorker::abort(const sp<IBinder>& token) {
300 auto op = operationMap_.removeOperation(token, false /* wasOpSuccessful */);
301 if (op) {
302 keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
303 return KS_HANDLE_HIDL_ERROR(keymasterDevice_->abort(op->handle));
304 } else {
305 return ErrorCode::INVALID_OPERATION_HANDLE;
306 }
307}
308
309/**
310 * Prune the oldest pruneable operation.
311 */
312bool KeymasterWorker::pruneOperation() {
313 sp<IBinder> oldest = operationMap_.getOldestPruneableOperation();
314 ALOGD("Trying to prune operation %p", oldest.get());
315 size_t op_count_before_abort = operationMap_.getOperationCount();
316 // We mostly ignore errors from abort() because all we care about is whether at least
317 // one operation has been removed.
318 auto rc = abort(oldest);
319 if (operationMap_.getOperationCount() >= op_count_before_abort) {
320 ALOGE("Failed to abort pruneable operation %p, error: %d", oldest.get(), int32_t(rc));
321 return false;
322 }
323 return true;
324}
325
326// My IDE defines "CAPTURE_MOVE(x) x" because it does not understand generalized lambda captures.
327// It should never be redefined by a build system though.
328#ifndef CAPTURE_MOVE
329#define CAPTURE_MOVE(x) x = std::move(x)
330#endif
331
332void KeymasterWorker::begin(LockedKeyBlobEntry lockedEntry, sp<IBinder> appToken, Blob keyBlob,
333 Blob charBlob, bool pruneable, KeyPurpose purpose,
334 AuthorizationSet opParams, hidl_vec<uint8_t> entropy,
335 worker_begin_cb worker_cb) {
336
337 Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(appToken),
338 CAPTURE_MOVE(keyBlob), CAPTURE_MOVE(charBlob), pruneable, purpose,
339 CAPTURE_MOVE(opParams), CAPTURE_MOVE(entropy),
340 CAPTURE_MOVE(worker_cb)]() mutable {
341 // Concurrently executed
342
343 auto key = blob2hidlVec(keyBlob);
344 auto& dev = keymasterDevice_;
345
346 KeyCharacteristics characteristics;
347
348 {
349 hidl_vec<uint8_t> clientId;
350 hidl_vec<uint8_t> appData;
351 for (auto param : opParams) {
352 if (param.tag == Tag::APPLICATION_ID) {
353 clientId = authorizationValue(TAG_APPLICATION_ID, param).value();
354 } else if (param.tag == Tag::APPLICATION_DATA) {
355 appData = authorizationValue(TAG_APPLICATION_DATA, param).value();
356 }
357 }
358 KeyStoreServiceReturnCode error;
359 std::tie(error, characteristics, keyBlob, charBlob) = createKeyCharacteristicsCache(
360 lockedEntry, clientId, appData, std::move(keyBlob), std::move(charBlob));
361 if (!error.isOk()) {
362 worker_cb(operationFailed(error));
363 return;
364 }
365 }
366
367 KeyStoreServiceReturnCode rc, authRc;
368 HardwareAuthToken authToken;
369 std::tie(authRc, authToken) = getAuthToken(characteristics, 0 /* no challenge */, purpose,
370 /*failOnTokenMissing*/ false);
371
372 // If per-operation auth is needed we need to begin the operation and
373 // the client will need to authorize that operation before calling
374 // update. Any other auth issues stop here.
375 if (!authRc.isOk() && authRc != ResponseCode::OP_AUTH_NEEDED) {
376 return worker_cb(operationFailed(authRc));
377 }
378
379 // Add entropy to the device first.
380 if (entropy.size()) {
381 rc = KS_HANDLE_HIDL_ERROR(dev->addRngEntropy(entropy));
382 if (!rc.isOk()) {
383 return worker_cb(operationFailed(rc));
384 }
385 }
386
387 // Create a keyid for this key.
388 auto keyid = KeymasterEnforcement::CreateKeyId(key);
389 if (!keyid) {
390 ALOGE("Failed to create a key ID for authorization checking.");
391 return worker_cb(operationFailed(ErrorCode::UNKNOWN_ERROR));
392 }
393
394 // Check that all key authorization policy requirements are met.
395 AuthorizationSet key_auths = characteristics.hardwareEnforced;
396 key_auths.append(characteristics.softwareEnforced.begin(),
397 characteristics.softwareEnforced.end());
398
399 rc = keyStore_->getEnforcementPolicy().AuthorizeOperation(
400 purpose, *keyid, key_auths, opParams, authToken, 0 /* op_handle */,
401 true /* is_begin_operation */);
402 if (!rc.isOk()) {
403 return worker_cb(operationFailed(rc));
404 }
405
406 // If there are more than kMaxOperations, abort the oldest operation that was started as
407 // pruneable.
408 while (operationMap_.getOperationCount() >= kMaxOperations) {
409 ALOGD("Reached or exceeded concurrent operations limit");
410 if (!pruneOperation()) {
411 break;
412 }
413 }
414
415 android::security::keymaster::OperationResult result;
416
417 auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
418 uint64_t operationHandle) {
419 result.resultCode = ret;
420 if (!result.resultCode.isOk()) {
421 if (result.resultCode == ErrorCode::INVALID_KEY_BLOB) {
422 log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
423 }
424 return;
425 }
426 result.handle = operationHandle;
427 result.outParams = outParams;
428 };
429
430 do {
431 rc = KS_HANDLE_HIDL_ERROR(
432 dev->begin(purpose, key, opParams.hidl_data(), authToken, hidlCb));
433 if (!rc.isOk()) {
434 LOG(ERROR) << "Got error " << rc << " from begin()";
435 return worker_cb(operationFailed(ResponseCode::SYSTEM_ERROR));
436 }
437 // If there are too many operations abort the oldest operation that was
438 // started as pruneable and try again.
439 } while (result.resultCode == ErrorCode::TOO_MANY_OPERATIONS && pruneOperation());
440
441 rc = result.resultCode;
442 if (!rc.isOk()) {
443 return worker_cb(operationFailed(rc));
444 }
445
446 // Note: The operation map takes possession of the contents of "characteristics".
447 // It is safe to use characteristics after the following line but it will be empty.
448 sp<IBinder> operationToken =
449 operationMap_.addOperation(result.handle, *keyid, purpose, dev, appToken,
450 std::move(characteristics), opParams.hidl_data(), pruneable);
451 assert(characteristics.hardwareEnforced.size() == 0);
452 assert(characteristics.softwareEnforced.size() == 0);
453 result.token = operationToken;
454
455 auto operation = operationMap_.getOperation(operationToken);
456 if (!operation) {
457 return worker_cb(operationFailed(ResponseCode::SYSTEM_ERROR));
458 }
459
460 if (authRc.isOk() && authToken.mac.size() &&
461 dev->halVersion().securityLevel == SecurityLevel::STRONGBOX) {
462 operation->authTokenFuture = operation->authTokenPromise.get_future();
463 std::weak_ptr<Operation> weak_operation = operation;
464
465 auto verifyTokenCB = [weak_operation](KeyStoreServiceReturnCode rc,
466 HardwareAuthToken authToken,
467 VerificationToken verificationToken) {
468 auto operation = weak_operation.lock();
469 if (!operation) {
470 // operation aborted, nothing to do
471 return;
472 }
473 if (rc.isOk()) {
474 operation->authToken = std::move(authToken);
475 operation->verificationToken = std::move(verificationToken);
476 }
477 operation->authTokenPromise.set_value(rc);
478 };
479 auto teeKmDevice = keyStore_->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
480 teeKmDevice->verifyAuthorization(result.handle, {}, std::move(authToken),
481 std::move(verifyTokenCB));
482 }
483
484 // Return the authentication lookup result. If this is a per operation
485 // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the
486 // application should get an auth token using the handle before the
487 // first call to update, which will fail if keystore hasn't received the
488 // auth token.
489 if (result.resultCode.isOk()) {
490 result.resultCode = authRc;
491 }
492 return worker_cb(result);
493 });
494}
495
496KeyStoreServiceReturnCode
497KeymasterWorker::getOperationAuthTokenIfNeeded(std::shared_ptr<Operation> op) {
498 if (!op) return ErrorCode::INVALID_OPERATION_HANDLE;
499
500 if (op->authTokenFuture.valid()) {
501 LOG(INFO) << "Waiting for verification token";
502 op->authTokenFuture.wait();
503 auto rc = op->authTokenFuture.get();
504 if (!rc.isOk()) {
505 return rc;
506 }
507 op->authTokenFuture = {};
508 } else if (!op->hasAuthToken()) {
509 KeyStoreServiceReturnCode rc;
510 HardwareAuthToken found;
511 std::tie(rc, found) = getAuthToken(op->characteristics, op->handle, op->purpose);
512 if (!rc.isOk()) return rc;
513 op->authToken = std::move(found);
514 }
515
516 return ResponseCode::NO_ERROR;
517}
518
519namespace {
520
521class Finalize {
522 private:
523 std::function<void()> f_;
524
525 public:
526 Finalize(std::function<void()> f) : f_(f) {}
527 ~Finalize() {
528 if (f_) f_();
529 }
530 void release() { f_ = {}; }
531};
532
533} // namespace
534
535void KeymasterWorker::update(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> data,
536 update_cb worker_cb) {
537 Worker::addRequest([this, CAPTURE_MOVE(token), CAPTURE_MOVE(params), CAPTURE_MOVE(data),
538 CAPTURE_MOVE(worker_cb)]() {
539 KeyStoreServiceReturnCode rc;
540 auto op = operationMap_.getOperation(token);
541 if (!op) {
542 return worker_cb(operationFailed(ErrorCode::INVALID_OPERATION_HANDLE));
543 }
544
545 Finalize abort_operation_in_case_of_error([&] {
546 operationMap_.removeOperation(token, false);
547 keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
548 KS_HANDLE_HIDL_ERROR(keymasterDevice_->abort(op->handle));
549 });
550
551 rc = getOperationAuthTokenIfNeeded(op);
552 if (!rc.isOk()) return worker_cb(operationFailed(rc));
553
554 // Check that all key authorization policy requirements are met.
555 AuthorizationSet key_auths(op->characteristics.hardwareEnforced);
556 key_auths.append(op->characteristics.softwareEnforced.begin(),
557 op->characteristics.softwareEnforced.end());
558
559 rc = keyStore_->getEnforcementPolicy().AuthorizeOperation(op->purpose, op->keyid, key_auths,
560 params, op->authToken, op->handle,
561 false /* is_begin_operation */);
562 if (!rc.isOk()) return worker_cb(operationFailed(rc));
563
564 OperationResult result;
565 auto hidlCb = [&](ErrorCode ret, uint32_t inputConsumed,
566 const hidl_vec<KeyParameter>& outParams,
567 const ::std::vector<uint8_t>& output) {
568 result.resultCode = ret;
569 if (result.resultCode.isOk()) {
570 result.inputConsumed = inputConsumed;
571 result.outParams = outParams;
572 result.data = output;
573 }
574 };
575
576 rc = KS_HANDLE_HIDL_ERROR(op->device->update(op->handle, params.hidl_data(), data,
577 op->authToken, op->verificationToken, hidlCb));
578
579 // just a reminder: on success result->resultCode was set in the callback. So we only
580 // overwrite it if there was a communication error indicated by the ErrorCode.
581 if (!rc.isOk()) result.resultCode = rc;
582 if (result.resultCode.isOk()) {
583 // if everything went well we don't abort the operation.
584 abort_operation_in_case_of_error.release();
585 }
586 return worker_cb(std::move(result));
587 });
588}
589
590/**
591 * Check that all KeyParameters provided by the application are allowed. Any parameter that keystore
592 * adds itself should be disallowed here.
593 */
594template <typename ParamsIter>
595static bool checkAllowedOperationParams(ParamsIter begin, const ParamsIter end) {
596 while (begin != end) {
597 switch (begin->tag) {
598 case Tag::ATTESTATION_APPLICATION_ID:
599 case Tag::RESET_SINCE_ID_ROTATION:
600 return false;
601 default:
602 break;
603 }
604 ++begin;
605 }
606 return true;
607}
608
609void KeymasterWorker::finish(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> input,
610 hidl_vec<uint8_t> signature, hidl_vec<uint8_t> entropy,
611 finish_cb worker_cb) {
612 Worker::addRequest([this, CAPTURE_MOVE(token), CAPTURE_MOVE(params), CAPTURE_MOVE(input),
613 CAPTURE_MOVE(signature), CAPTURE_MOVE(entropy),
614 CAPTURE_MOVE(worker_cb)]() mutable {
615 KeyStoreServiceReturnCode rc;
616 auto op = operationMap_.getOperation(token);
617 if (!op) {
618 return worker_cb(operationFailed(ErrorCode::INVALID_OPERATION_HANDLE));
619 }
620
621 bool finished = false;
622 Finalize abort_operation_in_case_of_error([&] {
623 operationMap_.removeOperation(token, finished && rc.isOk());
624 keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
625 if (!finished) KS_HANDLE_HIDL_ERROR(keymasterDevice_->abort(op->handle));
626 });
627
628 if (!checkAllowedOperationParams(params.begin(), params.end())) {
629 return worker_cb(operationFailed(ErrorCode::INVALID_ARGUMENT));
630 }
631
632 rc = getOperationAuthTokenIfNeeded(op);
633 if (!rc.isOk()) return worker_cb(operationFailed(rc));
634
635 // Check that all key authorization policy requirements are met.
636 AuthorizationSet key_auths(op->characteristics.hardwareEnforced);
637 key_auths.append(op->characteristics.softwareEnforced.begin(),
638 op->characteristics.softwareEnforced.end());
639
640 if (key_auths.Contains(Tag::TRUSTED_CONFIRMATION_REQUIRED)) {
641 hidl_vec<uint8_t> confirmationToken =
642 keyStore_->getConfirmationManager().getLatestConfirmationToken();
643 if (confirmationToken.size() == 0) {
644 LOG(ERROR) << "Confirmation token required but none found";
645 return worker_cb(operationFailed(ErrorCode::NO_USER_CONFIRMATION));
646 }
647 params.push_back(keymaster::TAG_CONFIRMATION_TOKEN, std::move(confirmationToken));
648 }
649
650 rc = keyStore_->getEnforcementPolicy().AuthorizeOperation(op->purpose, op->keyid, key_auths,
651 params, op->authToken, op->handle,
652 false /* is_begin_operation */);
653 if (!rc.isOk()) return worker_cb(operationFailed(rc));
654
655 if (entropy.size()) {
656 rc = KS_HANDLE_HIDL_ERROR(op->device->addRngEntropy(entropy));
657 if (!rc.isOk()) {
658 return worker_cb(operationFailed(rc));
659 }
660 }
661
662 OperationResult result;
663 auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
664 const ::std::vector<uint8_t>& output) {
665 result.resultCode = ret;
666 if (result.resultCode.isOk()) {
667 result.outParams = outParams;
668 result.data = output;
669 }
670 };
671
672 rc = KS_HANDLE_HIDL_ERROR(op->device->finish(op->handle, params.hidl_data(), input,
673 signature, op->authToken,
674 op->verificationToken, hidlCb));
675
676 if (rc.isOk()) {
677 // inform the finalizer that the finish call went through
678 finished = true;
679 // and what the result was
680 rc = result.resultCode;
681 } else {
682 return worker_cb(operationFailed(rc));
683 }
684 return worker_cb(std::move(result));
685 });
686}
687
688void KeymasterWorker::abort(sp<IBinder> token, abort_cb worker_cb) {
689 Worker::addRequest(
690 [this, CAPTURE_MOVE(token), CAPTURE_MOVE(worker_cb)]() { return worker_cb(abort(token)); });
691}
692
693void KeymasterWorker::verifyAuthorization(uint64_t challenge, hidl_vec<KeyParameter> params,
694 HardwareAuthToken token,
695 verifyAuthorization_cb worker_cb) {
696 Worker::addRequest([this, challenge, CAPTURE_MOVE(params), CAPTURE_MOVE(token),
697 CAPTURE_MOVE(worker_cb)]() {
698 KeyStoreServiceReturnCode error;
699 VerificationToken verificationToken;
700 KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_->verifyAuthorization(
701 challenge, params, token, [&](ErrorCode error_, const VerificationToken& vToken) {
702 error = error_;
703 verificationToken = vToken;
704 }));
705 worker_cb(rc.isOk() ? error : rc, std::move(token), std::move(verificationToken));
706 });
707}
708
709void KeymasterWorker::addRngEntropy(hidl_vec<uint8_t> data, addRngEntropy_cb _hidl_cb) {
710 addRequest(&Keymaster::addRngEntropy, std::move(_hidl_cb), std::move(data));
711}
712
713namespace {
714bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
715 return params.end() !=
716 std::find_if(params.begin(), params.end(),
717 [&](const KeyParameter& param) { return param.tag == tag; });
718}
719
720bool isAuthenticationBound(const hidl_vec<KeyParameter>& params) {
721 return !containsTag(params, Tag::NO_AUTH_REQUIRED);
722}
723} // namespace
724
725void KeymasterWorker::generateKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyParameter> keyParams,
726 hidl_vec<uint8_t> entropy, int flags, generateKey_cb worker_cb) {
727 Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(keyParams),
728 CAPTURE_MOVE(entropy), CAPTURE_MOVE(worker_cb), flags]() mutable {
729 KeyStoreServiceReturnCode rc =
730 KS_HANDLE_HIDL_ERROR(keymasterDevice_->addRngEntropy(entropy));
731 if (!rc.isOk()) {
732 return worker_cb(rc, {});
733 }
734
735 SecurityLevel securityLevel = keymasterDevice_->halVersion().securityLevel;
736
737 // Fallback cannot be considered for Strongbox. Further versions restrictions are enforced
738 // by KeyStore::getFallbackDevice()
739 bool consider_fallback = securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT;
740
741 Finalize logOnFail(
742 [&] { uploadKeyCharacteristicsAsProto(keyParams, false /* wasCreationSuccessful */); });
743
744 KeyCharacteristics outCharacteristics;
745 KeyStoreServiceReturnCode error;
746 auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
747 const KeyCharacteristics& keyCharacteristics) {
748 error = ret;
749 if (!error.isOk()) {
750 return;
751 }
752 consider_fallback = false;
753 outCharacteristics = keyCharacteristics;
754
755 Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
756 keyBlob.setSecurityLevel(securityLevel);
757 keyBlob.setCriticalToDeviceEncryption(flags &
758 KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
759 if (isAuthenticationBound(keyParams) && !keyBlob.isCriticalToDeviceEncryption()) {
760 keyBlob.setSuperEncrypted(true);
761 }
762 keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
763
764 AuthorizationSet sw_enforced = keyParams;
765 sw_enforced.Subtract(outCharacteristics.hardwareEnforced);
766 sw_enforced.Union(outCharacteristics.softwareEnforced);
767 sw_enforced.Filter([](const KeyParameter& param) -> bool {
768 return !(param.tag == Tag::APPLICATION_DATA || param.tag == Tag::APPLICATION_ID);
769 });
770 if (!sw_enforced.Contains(Tag::USER_ID)) {
771 // Most Java processes don't have access to this tag
772 sw_enforced.push_back(keymaster::TAG_USER_ID, get_user_id(lockedEntry->uid()));
773 }
774 Blob keyCharBlob;
775 keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
776 error = keyStore_->put(lockedEntry, std::move(keyBlob), std::move(keyCharBlob));
777 };
778
779 rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_->generateKey(keyParams, hidl_cb));
780 if (!rc.isOk()) {
781 return worker_cb(rc, {});
782 }
783
784 if (consider_fallback && !error.isOk()) {
785 auto fallback = keyStore_->getFallbackDevice();
786 if (!fallback) {
787 return worker_cb(error, {});
788 }
789 // No fallback for 3DES
790 for (auto& param : keyParams) {
791 auto algorithm = authorizationValue(TAG_ALGORITHM, param);
792 if (algorithm.isOk() && algorithm.value() == Algorithm::TRIPLE_DES) {
793 return worker_cb(ErrorCode::UNSUPPORTED_ALGORITHM, {});
794 }
795 }
796
797 // delegate to fallback worker
798 fallback->generateKey(std::move(lockedEntry), std::move(keyParams), std::move(entropy),
799 flags, std::move(worker_cb));
800 // let fallback do the logging
801 logOnFail.release();
802 return;
803 }
804
805 if (!error.isOk()) return worker_cb(error, {});
806
807 // log on success
808 logOnFail.release();
809 uploadKeyCharacteristicsAsProto(keyParams, true /* wasCreationSuccessful */);
810
811 return worker_cb(error, std::move(outCharacteristics));
812 });
813}
814
815void KeymasterWorker::generateKey(hidl_vec<KeyParameter> keyParams, generateKey2_cb worker_cb) {
816 addRequest(&Keymaster::generateKey, std::move(worker_cb), std::move(keyParams));
817}
818
819void KeymasterWorker::getKeyCharacteristics(LockedKeyBlobEntry lockedEntry,
820 hidl_vec<uint8_t> clientId, hidl_vec<uint8_t> appData,
821 Blob keyBlob, Blob charBlob,
822 getKeyCharacteristics_cb worker_cb) {
823 Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(clientId),
824 CAPTURE_MOVE(appData), CAPTURE_MOVE(keyBlob), CAPTURE_MOVE(charBlob),
825 CAPTURE_MOVE(worker_cb)]() {
826 auto result = createKeyCharacteristicsCache(lockedEntry, clientId, appData,
827 std::move(keyBlob), std::move(charBlob));
828 return worker_cb(std::get<0>(result), std::move(std::get<1>(result)));
829 });
830}
831
832void KeymasterWorker::importKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyParameter> keyParams,
833 KeyFormat keyFormat, hidl_vec<uint8_t> keyData, int flags,
834 importKey_cb worker_cb) {
835 Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(keyParams), keyFormat,
836 CAPTURE_MOVE(keyData), flags, CAPTURE_MOVE(worker_cb)]() mutable {
837 SecurityLevel securityLevel = keymasterDevice_->halVersion().securityLevel;
838
839 // Fallback cannot be considered for Strongbox. Further versions restrictions are enforced
840 // by KeyStore::getFallbackDevice()
841 bool consider_fallback = securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT;
842
843 Finalize logOnFail(
844 [&] { uploadKeyCharacteristicsAsProto(keyParams, false /* wasCreationSuccessful */); });
845
846 KeyCharacteristics outCharacteristics;
847 KeyStoreServiceReturnCode error;
848 auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
849 const KeyCharacteristics& keyCharacteristics) {
850 error = ret;
851 if (!error.isOk()) {
852 LOG(INFO) << "importKey failed";
853 return;
854 }
855 consider_fallback = false;
856 outCharacteristics = keyCharacteristics;
857
858 Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
859 keyBlob.setSecurityLevel(securityLevel);
860 keyBlob.setCriticalToDeviceEncryption(flags &
861 KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
862 if (isAuthenticationBound(keyParams) && !keyBlob.isCriticalToDeviceEncryption()) {
863 keyBlob.setSuperEncrypted(true);
864 }
865 keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
866
867 AuthorizationSet sw_enforced = keyParams;
868 sw_enforced.Subtract(outCharacteristics.hardwareEnforced);
869 sw_enforced.Union(outCharacteristics.softwareEnforced);
870 sw_enforced.Filter([](const KeyParameter& param) -> bool {
871 return !(param.tag == Tag::APPLICATION_DATA || param.tag == Tag::APPLICATION_ID);
872 });
873 if (!sw_enforced.Contains(Tag::USER_ID)) {
874 // Most Java processes don't have access to this tag
875 sw_enforced.push_back(keymaster::TAG_USER_ID, get_user_id(lockedEntry->uid()));
876 }
877 Blob keyCharBlob;
878 keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
879 error = keyStore_->put(lockedEntry, std::move(keyBlob), std::move(keyCharBlob));
880 };
881
882 KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
883 keymasterDevice_->importKey(keyParams, keyFormat, keyData, hidl_cb));
884 if (!rc.isOk()) {
885 return worker_cb(rc, {});
886 }
887
888 if (consider_fallback && !error.isOk()) {
889 auto fallback = keyStore_->getFallbackDevice();
890 if (!fallback) {
891 return worker_cb(error, {});
892 }
893 // No fallback for 3DES
894 for (auto& param : keyParams) {
895 auto algorithm = authorizationValue(TAG_ALGORITHM, param);
896 if (algorithm.isOk() && algorithm.value() == Algorithm::TRIPLE_DES) {
897 return worker_cb(ErrorCode::UNSUPPORTED_ALGORITHM, {});
898 }
899 }
900
901 // delegate to fallback worker
902 fallback->importKey(std::move(lockedEntry), std::move(keyParams), keyFormat,
903 std::move(keyData), flags, std::move(worker_cb));
904 // let fallback to the logging
905 logOnFail.release();
906 return;
907 }
908
909 if (!error.isOk()) return worker_cb(error, {});
910
911 // log on success
912 logOnFail.release();
913 uploadKeyCharacteristicsAsProto(keyParams, true /* wasCreationSuccessful */);
914
915 return worker_cb(error, std::move(outCharacteristics));
916 });
917}
918
919void KeymasterWorker::importWrappedKey(LockedKeyBlobEntry wrappingLockedEntry,
920 LockedKeyBlobEntry wrapppedLockedEntry,
921 hidl_vec<uint8_t> wrappedKeyData,
922 hidl_vec<uint8_t> maskingKey,
923 hidl_vec<KeyParameter> unwrappingParams, Blob wrappingBlob,
924 Blob wrappingCharBlob, uint64_t passwordSid,
925 uint64_t biometricSid, importWrappedKey_cb worker_cb) {
926 Worker::addRequest([this, CAPTURE_MOVE(wrappingLockedEntry), CAPTURE_MOVE(wrapppedLockedEntry),
927 CAPTURE_MOVE(wrappedKeyData), CAPTURE_MOVE(maskingKey),
928 CAPTURE_MOVE(unwrappingParams), CAPTURE_MOVE(wrappingBlob),
929 CAPTURE_MOVE(wrappingCharBlob), passwordSid, biometricSid,
930 CAPTURE_MOVE(worker_cb)]() mutable {
931 auto hidlWrappingKey = blob2hidlVec(wrappingBlob);
932
933 SecurityLevel securityLevel = keymasterDevice_->halVersion().securityLevel;
934
935 KeyCharacteristics outCharacteristics;
936 KeyStoreServiceReturnCode error;
937
938 auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
939 const KeyCharacteristics& keyCharacteristics) {
940 error = ret;
941 if (!error.isOk()) {
942 return;
943 }
944 outCharacteristics = keyCharacteristics;
945
946 Blob keyBlob(hidlKeyBlob.data(), hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
947 keyBlob.setSecurityLevel(securityLevel);
948 if (isAuthenticationBound(keyCharacteristics.hardwareEnforced)) {
949 keyBlob.setSuperEncrypted(true);
950 }
951
952 AuthorizationSet sw_enforced = outCharacteristics.softwareEnforced;
953 if (!sw_enforced.Contains(Tag::USER_ID)) {
954 // Most Java processes don't have access to this tag
955 sw_enforced.push_back(keymaster::TAG_USER_ID,
956 get_user_id(wrapppedLockedEntry->uid()));
957 }
958 Blob keyCharBlob;
959 keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
960 error = keyStore_->put(wrapppedLockedEntry, std::move(keyBlob), std::move(keyCharBlob));
961 };
962
963 KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_->importWrappedKey(
964 wrappedKeyData, hidlWrappingKey, maskingKey, unwrappingParams, passwordSid,
965 biometricSid, hidlCb));
966
967 // possible hidl error
968 if (!rc.isOk()) {
969 return worker_cb(rc, {});
970 }
971
972 if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
973 std::tie(rc, wrappingBlob) = upgradeKeyBlob(wrappingLockedEntry, {});
974 if (!rc.isOk()) {
975 return worker_cb(rc, {});
976 }
977
978 auto upgradedHidlKeyBlob = blob2hidlVec(wrappingBlob);
979
980 rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_->importWrappedKey(
981 wrappedKeyData, upgradedHidlKeyBlob, maskingKey, unwrappingParams, passwordSid,
982 biometricSid, hidlCb));
983 if (!rc.isOk()) {
984 error = rc;
985 }
986 }
987 return worker_cb(error, std::move(outCharacteristics));
988 });
989}
990
991void KeymasterWorker::exportKey(LockedKeyBlobEntry lockedEntry, KeyFormat exportFormat,
992 hidl_vec<uint8_t> clientId, hidl_vec<uint8_t> appData, Blob keyBlob,
993 Blob charBlob, exportKey_cb worker_cb) {
994 Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), exportFormat, CAPTURE_MOVE(clientId),
995 CAPTURE_MOVE(appData), CAPTURE_MOVE(keyBlob), CAPTURE_MOVE(charBlob),
996 CAPTURE_MOVE(worker_cb)]() mutable {
997 auto key = blob2hidlVec(keyBlob);
998
999 ExportResult result;
1000 auto hidlCb = [&](ErrorCode ret,
1001 const ::android::hardware::hidl_vec<uint8_t>& keyMaterial) {
1002 result.resultCode = ret;
1003 if (!result.resultCode.isOk()) {
1004 if (result.resultCode == ErrorCode::INVALID_KEY_BLOB) {
1005 log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
1006 }
1007 return;
1008 }
1009 result.exportData = keyMaterial;
1010 };
1011 KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
1012 keymasterDevice_->exportKey(exportFormat, key, clientId, appData, hidlCb));
1013
1014 // Overwrite result->resultCode only on HIDL error. Otherwise we want the result set in the
1015 // callback hidlCb.
1016 if (!rc.isOk()) {
1017 result.resultCode = rc;
1018 }
1019
1020 if (result.resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
1021 AuthorizationSet upgradeParams;
1022 if (clientId.size()) {
1023 upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
1024 }
1025 if (appData.size()) {
1026 upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
1027 }
1028 std::tie(rc, keyBlob) = upgradeKeyBlob(lockedEntry, upgradeParams);
1029 if (!rc.isOk()) {
1030 return worker_cb(std::move(result));
1031 }
1032
1033 auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
1034
1035 rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_->exportKey(exportFormat, upgradedHidlKeyBlob,
1036 clientId, appData, hidlCb));
1037 if (!rc.isOk()) {
1038 result.resultCode = rc;
1039 }
1040 }
1041 return worker_cb(std::move(result));
1042 });
1043}
1044void KeymasterWorker::attestKey(hidl_vec<uint8_t> keyToAttest, hidl_vec<KeyParameter> attestParams,
1045 attestKey_cb worker_cb) {
1046 addRequest(&Keymaster::attestKey, std::move(worker_cb), std::move(keyToAttest),
1047 std::move(attestParams));
1048}
1049void KeymasterWorker::upgradeKey(hidl_vec<uint8_t> keyBlobToUpgrade,
1050 hidl_vec<KeyParameter> upgradeParams, upgradeKey_cb _hidl_cb) {
1051 addRequest(&Keymaster::upgradeKey, std::move(_hidl_cb), std::move(keyBlobToUpgrade),
1052 std::move(upgradeParams));
1053}
1054
1055void KeymasterWorker::deleteKey(hidl_vec<uint8_t> keyBlob, deleteKey_cb _hidl_cb) {
1056 addRequest(&Keymaster::deleteKey, std::move(_hidl_cb), std::move(keyBlob));
1057}
1058void KeymasterWorker::deleteAllKeys(deleteAllKeys_cb _hidl_cb) {
1059 addRequest(&Keymaster::deleteAllKeys, std::move(_hidl_cb));
1060}
1061void KeymasterWorker::destroyAttestationIds(destroyAttestationIds_cb _hidl_cb) {
1062 addRequest(&Keymaster::destroyAttestationIds, move(_hidl_cb));
1063}
1064
1065void KeymasterWorker::binderDied(android::wp<IBinder> who) {
1066 Worker::addRequest([this, who]() {
1067 auto operations = operationMap_.getOperationsForToken(who.unsafe_get());
1068 for (const auto& token : operations) {
1069 abort(token);
1070 }
1071 });
1072}
1073
1074} // namespace keystore