blob: 71ab340560b4dd302d992ce217d300817ce677cf [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>
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070021#include <android-base/logging.h>
22#include <mutex>
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080023
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010024namespace keystore {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010025
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080026OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
Shawn Willden715d0232016-01-21 00:45:13 -070027 : mDeathRecipient(deathRecipient) {}
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080028
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010029sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
Shawn Willden0329a822017-12-04 13:55:14 -070030 const sp<Keymaster>& dev, const sp<IBinder>& appToken,
Max Bires33aac2d2018-02-23 10:53:10 -080031 KeyCharacteristics&& characteristics,
32 const hidl_vec<KeyParameter>& params, bool pruneable) {
Shawn Willdenda6dcc32017-12-03 14:56:05 -070033 sp<IBinder> token = new ::android::BBinder();
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070034 mMap.emplace(token, std::make_shared<Operation>(handle, keyid, purpose, dev,
35 std::move(characteristics), appToken, params));
Shawn Willdenda6dcc32017-12-03 14:56:05 -070036 if (pruneable) mLru.push_back(token);
37 if (mAppTokenMap.find(appToken) == mAppTokenMap.end()) appToken->linkToDeath(mDeathRecipient);
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080038 mAppTokenMap[appToken].push_back(token);
39 return token;
40}
41
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070042std::shared_ptr<Operation> OperationMap::getOperation(const sp<IBinder>& token) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080043 auto entry = mMap.find(token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070044 if (entry == mMap.end()) return {};
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080045
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070046 auto op = entry->second;
47
Shawn Willdenda6dcc32017-12-03 14:56:05 -070048 updateLru(token);
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070049 return op;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080050}
51
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070052void OperationMap::updateLru(const sp<IBinder>& token) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080053 auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
54 if (lruEntry != mLru.end()) {
55 mLru.erase(lruEntry);
56 mLru.push_back(token);
57 }
58}
59
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070060std::shared_ptr<Operation> OperationMap::removeOperation(const sp<IBinder>& token,
61 bool wasSuccessful) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080062 auto entry = mMap.find(token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070063 if (entry == mMap.end()) return {};
64
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070065 auto op = entry->second;
Max Bires091ed1b2018-12-05 12:13:30 -080066 operationUploader.uploadOpAsProto(*op, wasSuccessful);
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080067 mMap.erase(entry);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070068
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080069 auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070070 if (lruEntry != mLru.end()) mLru.erase(lruEntry);
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070071 removeOperationTracking(token, op->appToken);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070072 return op;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080073}
74
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070075void OperationMap::removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080076 auto appEntry = mAppTokenMap.find(appToken);
77 if (appEntry == mAppTokenMap.end()) {
78 ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
79 return;
80 }
81 auto tokenEntry = std::find(appEntry->second.begin(), appEntry->second.end(), token);
82 appEntry->second.erase(tokenEntry);
83 // Stop listening for death if all operations tied to the token have finished.
84 if (appEntry->second.size() == 0) {
85 appToken->unlinkToDeath(mDeathRecipient);
86 mAppTokenMap.erase(appEntry);
87 }
88}
89
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080090sp<IBinder> OperationMap::getOldestPruneableOperation() {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070091 if (mLru.size() == 0) return {};
Chad Brubaker0cf34a22015-04-23 11:06:16 -070092
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070093 return {mLru.front()};
Chad Brubaker0cf34a22015-04-23 11:06:16 -070094}
95
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070096std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
Chad Brubaker40a1a9b2015-02-20 14:08:13 -080097 auto appEntry = mAppTokenMap.find(appToken);
Shawn Willdenda6dcc32017-12-03 14:56:05 -070098 if (appEntry == mAppTokenMap.end()) return {};
99 return appEntry->second;
Chad Brubaker40a1a9b2015-02-20 14:08:13 -0800100}
101
Shawn Willdenda6dcc32017-12-03 14:56:05 -0700102} // namespace keystore