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