blob: e09d5151756d75ecc3d248ff2a5fb0af23aa7252 [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"
19
20#include <algorithm>
21
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010022namespace keystore {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010023
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080024OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
Shawn Willden715d0232016-01-21 00:45:13 -070025 : mDeathRecipient(deathRecipient) {}
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080026
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010027sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
Shawn Willden0329a822017-12-04 13:55:14 -070028 const sp<Keymaster>& dev, const sp<IBinder>& appToken,
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010029 KeyCharacteristics&& characteristics, bool pruneable) {
Shawn Willdenda6dcc32017-12-03 14:56:05 -070030 sp<IBinder> token = new ::android::BBinder();
31 mMap.emplace(token,
32 Operation(handle, keyid, purpose, dev, std::move(characteristics), appToken));
33 if (pruneable) mLru.push_back(token);
34 if (mAppTokenMap.find(appToken) == mAppTokenMap.end()) appToken->linkToDeath(mDeathRecipient);
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080035 mAppTokenMap[appToken].push_back(token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070036
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080037 return token;
38}
39
Shawn Willdenda6dcc32017-12-03 14:56:05 -070040NullOr<const OperationMap::Operation&> OperationMap::getOperation(const sp<IBinder>& token) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080041 auto entry = mMap.find(token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070042 if (entry == mMap.end()) return {};
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080043
Shawn Willdenda6dcc32017-12-03 14:56:05 -070044 updateLru(token);
45 return entry->second;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080046}
47
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070048void OperationMap::updateLru(const sp<IBinder>& token) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080049 auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
50 if (lruEntry != mLru.end()) {
51 mLru.erase(lruEntry);
52 mLru.push_back(token);
53 }
54}
55
Shawn Willdenda6dcc32017-12-03 14:56:05 -070056NullOr<OperationMap::Operation> OperationMap::removeOperation(const sp<IBinder>& token) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080057 auto entry = mMap.find(token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070058 if (entry == mMap.end()) return {};
59
60 Operation op = std::move(entry->second);
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080061 mMap.erase(entry);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070062
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080063 auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070064 if (lruEntry != mLru.end()) mLru.erase(lruEntry);
65 removeOperationTracking(token, op.appToken);
66
67 return op;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080068}
69
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070070void OperationMap::removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080071 auto appEntry = mAppTokenMap.find(appToken);
72 if (appEntry == mAppTokenMap.end()) {
73 ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
74 return;
75 }
76 auto tokenEntry = std::find(appEntry->second.begin(), appEntry->second.end(), token);
77 appEntry->second.erase(tokenEntry);
78 // Stop listening for death if all operations tied to the token have finished.
79 if (appEntry->second.size() == 0) {
80 appToken->unlinkToDeath(mDeathRecipient);
81 mAppTokenMap.erase(appEntry);
82 }
83}
84
Alex Klyubin700c1a32015-06-23 15:21:51 -070085bool OperationMap::hasPruneableOperation() const {
Shawn Willdenda6dcc32017-12-03 14:56:05 -070086 return !mLru.empty();
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080087}
88
Alex Klyubin700c1a32015-06-23 15:21:51 -070089size_t OperationMap::getPruneableOperationCount() const {
90 return mLru.size();
91}
92
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080093sp<IBinder> OperationMap::getOldestPruneableOperation() {
Shawn Willdenda6dcc32017-12-03 14:56:05 -070094 if (!hasPruneableOperation()) return sp<IBinder>(nullptr);
95 return mLru.front();
Chad Brubaker0cf34a22015-04-23 11:06:16 -070096}
97
Shawn Willdendebb61e2017-12-03 12:51:19 -070098bool OperationMap::setOperationAuthToken(const sp<IBinder>& token, HardwareAuthToken authToken) {
Chad Brubaker0cf34a22015-04-23 11:06:16 -070099 auto entry = mMap.find(token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -0700100 if (entry == mMap.end()) return false;
101
Shawn Willden0329a822017-12-04 13:55:14 -0700102 entry->second.authToken = std::move(authToken);
Chad Brubaker0cf34a22015-04-23 11:06:16 -0700103 return true;
104}
105
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -0700106std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -0800107 auto appEntry = mAppTokenMap.find(appToken);
Shawn Willdenda6dcc32017-12-03 14:56:05 -0700108 if (appEntry == mAppTokenMap.end()) return {};
109 return appEntry->second;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -0800110}
111
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100112OperationMap::Operation::Operation(uint64_t handle_, uint64_t keyid_, KeyPurpose purpose_,
Shawn Willden0329a822017-12-04 13:55:14 -0700113 const sp<Keymaster>& device_,
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100114 KeyCharacteristics&& characteristics_, sp<IBinder> appToken_)
Shawn Willden715d0232016-01-21 00:45:13 -0700115 : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_),
116 characteristics(characteristics_), appToken(appToken_) {}
Chad Brubaker40a1a9b2015-02-20 14:08:13 -0800117
Shawn Willdenda6dcc32017-12-03 14:56:05 -0700118} // namespace keystore