blob: bd4bd5ef79b7ea7f195a2ad1b2684256b2086d07 [file] [log] [blame]
Chad Brubaker40a1a9b2015-02-20 14:08:13 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#define LOG_TAG "KeystoreOperation"
17
18#include "operation.h"
Hasini Gunasinghe242460e2020-06-05 14:06:02 +000019#include "key_operation_log_handler.h"
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080020
21#include <algorithm>
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070022#include <android-base/logging.h>
23#include <mutex>
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080024
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010025namespace keystore {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010026
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080027OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
Shawn Willden715d0232016-01-21 00:45:13 -070028 : mDeathRecipient(deathRecipient) {}
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080029
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010030sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
Shawn Willden0329a822017-12-04 13:55:14 -070031 const sp<Keymaster>& dev, const sp<IBinder>& appToken,
Max Bires33aac2d2018-02-23 10:53:10 -080032 KeyCharacteristics&& characteristics,
33 const hidl_vec<KeyParameter>& params, bool pruneable) {
Shawn Willdenda6dcc32017-12-03 14:56:05 -070034 sp<IBinder> token = new ::android::BBinder();
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070035 mMap.emplace(token, std::make_shared<Operation>(handle, keyid, purpose, dev,
36 std::move(characteristics), appToken, params));
Shawn Willdenda6dcc32017-12-03 14:56:05 -070037 if (pruneable) mLru.push_back(token);
38 if (mAppTokenMap.find(appToken) == mAppTokenMap.end()) appToken->linkToDeath(mDeathRecipient);
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080039 mAppTokenMap[appToken].push_back(token);
40 return token;
41}
42
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070043std::shared_ptr<Operation> OperationMap::getOperation(const sp<IBinder>& token) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080044 auto entry = mMap.find(token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070045 if (entry == mMap.end()) return {};
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080046
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070047 auto op = entry->second;
48
Shawn Willdenda6dcc32017-12-03 14:56:05 -070049 updateLru(token);
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070050 return op;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080051}
52
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070053void OperationMap::updateLru(const sp<IBinder>& token) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080054 auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
55 if (lruEntry != mLru.end()) {
56 mLru.erase(lruEntry);
57 mLru.push_back(token);
58 }
59}
60
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070061std::shared_ptr<Operation> OperationMap::removeOperation(const sp<IBinder>& token,
Hasini Gunasinghe242460e2020-06-05 14:06:02 +000062 bool wasSuccessful, int32_t responseCode) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080063 auto entry = mMap.find(token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070064 if (entry == mMap.end()) return {};
65
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070066 auto op = entry->second;
Hasini Gunasinghe242460e2020-06-05 14:06:02 +000067 logKeystoreKeyOperationEvent(*op, wasSuccessful, responseCode);
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080068 mMap.erase(entry);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070069
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080070 auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070071 if (lruEntry != mLru.end()) mLru.erase(lruEntry);
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070072 removeOperationTracking(token, op->appToken);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070073 return op;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080074}
75
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070076void OperationMap::removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080077 auto appEntry = mAppTokenMap.find(appToken);
78 if (appEntry == mAppTokenMap.end()) {
79 ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
80 return;
81 }
82 auto tokenEntry = std::find(appEntry->second.begin(), appEntry->second.end(), token);
83 appEntry->second.erase(tokenEntry);
84 // Stop listening for death if all operations tied to the token have finished.
85 if (appEntry->second.size() == 0) {
86 appToken->unlinkToDeath(mDeathRecipient);
87 mAppTokenMap.erase(appEntry);
88 }
89}
90
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080091sp<IBinder> OperationMap::getOldestPruneableOperation() {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070092 if (mLru.size() == 0) return {};
Chad Brubaker0cf34a22015-04-23 11:06:16 -070093
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070094 return {mLru.front()};
Chad Brubaker0cf34a22015-04-23 11:06:16 -070095}
96
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070097std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080098 auto appEntry = mAppTokenMap.find(appToken);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070099 if (appEntry == mAppTokenMap.end()) return {};
100 return appEntry->second;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -0800101}
102
Shawn Willdenda6dcc32017-12-03 14:56:05 -0700103} // namespace keystore