1 /*
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 
17 #ifndef KEYSTORE_OPERATION_H_
18 #define KEYSTORE_OPERATION_H_
19 
20 #include <binder/Binder.h>
21 #include <binder/IBinder.h>
22 #include <keystore/keymaster_tags.h>
23 #include <map>
24 #include <utils/LruCache.h>
25 #include <utils/StrongPointer.h>
26 #include <vector>
27 
28 namespace keystore {
29 
30 using ::android::IBinder;
31 using ::android::sp;
32 
33 /**
34  * OperationMap handles the translation of uint64_t's and keymaster2_device_t's to opaque binder
35  * tokens that can be used to reference that operation at a later time by applications. It also does
36  * LRU tracking for operation pruning and keeps a mapping of clients to operations to allow for
37  * graceful handling of application death.
38  */
39 
40 class OperationMap {
41     typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
42 
43   public:
44     explicit OperationMap(IBinder::DeathRecipient* deathRecipient);
45     android::sp<android::IBinder> addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
46                                                const km_device_t& dev,
47                                                const android::sp<android::IBinder>& appToken,
48                                                KeyCharacteristics&& characteristics,
49                                                bool pruneable);
50     bool getOperation(const android::sp<android::IBinder>& token, uint64_t* outHandle,
51                       uint64_t* outKeyid, KeyPurpose* outPurpose, km_device_t* outDev,
52                       const KeyCharacteristics** outCharacteristics);
53     bool removeOperation(const android::sp<android::IBinder>& token);
54     bool hasPruneableOperation() const;
getOperationCount()55     size_t getOperationCount() const { return mMap.size(); }
56     size_t getPruneableOperationCount() const;
57     bool getOperationAuthToken(const android::sp<android::IBinder>& token,
58                                const HardwareAuthToken** outToken);
59     bool setOperationAuthToken(const android::sp<android::IBinder>& token,
60                                const HardwareAuthToken* authToken);
61     android::sp<android::IBinder> getOldestPruneableOperation();
62     std::vector<android::sp<android::IBinder>>
63     getOperationsForToken(const android::sp<android::IBinder>& appToken);
64 
65   private:
66     void updateLru(const android::sp<android::IBinder>& token);
67     void removeOperationTracking(const android::sp<android::IBinder>& token,
68                                  const android::sp<android::IBinder>& appToken);
69     struct Operation {
70         Operation();
71         Operation(uint64_t handle, uint64_t keyid, KeyPurpose purpose, const km_device_t& device,
72                   KeyCharacteristics&& characteristics, android::sp<android::IBinder> appToken);
73         uint64_t handle;
74         uint64_t keyid;
75         KeyPurpose purpose;
76         km_device_t device;
77         KeyCharacteristics characteristics;
78         android::sp<android::IBinder> appToken;
79         std::unique_ptr<HardwareAuthToken> authToken;
80     };
81     std::map<android::sp<android::IBinder>, Operation> mMap;
82     std::vector<android::sp<android::IBinder>> mLru;
83     std::map<android::sp<android::IBinder>, std::vector<android::sp<android::IBinder>>>
84         mAppTokenMap;
85     android::IBinder::DeathRecipient* mDeathRecipient;
86 };
87 
88 }  // namespace keystore
89 
90 #endif
91