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