1 /*
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 
18 #ifndef KEYSTORE_KEYMASTER_WORKER_H_
19 #define KEYSTORE_KEYMASTER_WORKER_H_
20 
21 #include <condition_variable>
22 #include <functional>
23 #include <keymasterV4_1/Keymaster.h>
24 #include <memory>
25 #include <mutex>
26 #include <optional>
27 #include <queue>
28 #include <thread>
29 #include <tuple>
30 
31 #include <keystore/ExportResult.h>
32 #include <keystore/KeyCharacteristics.h>
33 #include <keystore/KeymasterBlob.h>
34 #include <keystore/OperationResult.h>
35 #include <keystore/keymaster_types.h>
36 #include <keystore/keystore_return_types.h>
37 
38 #include "blob.h"
39 #include "operation.h"
40 
41 namespace keystore {
42 
43 using android::sp;
44 using ::android::hardware::hidl_vec;
45 using ::android::hardware::Return;
46 using ::android::hardware::Void;
47 using android::hardware::keymaster::V4_1::support::Keymaster;
48 using ::android::security::keymaster::KeymasterBlob;
49 
50 class KeyStore;
51 
52 class Worker {
53 
54     /*
55      * NonCopyableFunction works similar to std::function in that it wraps callable objects and
56      * erases their type. The rationale for using a custom class instead of
57      * std::function is that std::function requires the wrapped object to be copy contructible.
58      * NonCopyableFunction is itself not copyable and never attempts to copy the wrapped object.
59      * TODO use similar optimization as std::function to remove the extra make_unique allocation.
60      */
61     template <typename Fn> class NonCopyableFunction;
62 
63     template <typename Ret, typename... Args> class NonCopyableFunction<Ret(Args...)> {
64 
65         class NonCopyableFunctionBase {
66           public:
67             NonCopyableFunctionBase() = default;
~NonCopyableFunctionBase()68             virtual ~NonCopyableFunctionBase() {}
69             virtual Ret operator()(Args... args) = 0;
70             NonCopyableFunctionBase(const NonCopyableFunctionBase&) = delete;
71             NonCopyableFunctionBase& operator=(const NonCopyableFunctionBase&) = delete;
72         };
73 
74         template <typename Fn>
75         class NonCopyableFunctionTypeEraser : public NonCopyableFunctionBase {
76           private:
77             Fn f_;
78 
79           public:
80             NonCopyableFunctionTypeEraser() = default;
NonCopyableFunctionTypeEraser(Fn f)81             explicit NonCopyableFunctionTypeEraser(Fn f) : f_(std::move(f)) {}
operator()82             Ret operator()(Args... args) override { return f_(std::move(args)...); }
83         };
84 
85       private:
86         std::unique_ptr<NonCopyableFunctionBase> f_;
87 
88       public:
89         NonCopyableFunction() = default;
90         // NOLINTNEXTLINE(google-explicit-constructor)
NonCopyableFunction(F f)91         template <typename F> NonCopyableFunction(F f) {
92             f_ = std::make_unique<NonCopyableFunctionTypeEraser<F>>(std::move(f));
93         }
94         NonCopyableFunction(NonCopyableFunction&& other) = default;
95         NonCopyableFunction& operator=(NonCopyableFunction&& other) = default;
96         NonCopyableFunction(const NonCopyableFunction& other) = delete;
97         NonCopyableFunction& operator=(const NonCopyableFunction& other) = delete;
98 
operator()99         Ret operator()(Args... args) {
100             if (f_) return (*f_)(std::move(args)...);
101         }
102     };
103 
104     using WorkerTask = NonCopyableFunction<void()>;
105 
106     std::queue<WorkerTask> pending_requests_;
107     std::mutex pending_requests_mutex_;
108     std::condition_variable pending_requests_cond_var_;
109     bool running_ = false;
110     bool terminate_ = false;
111 
112   public:
113     Worker();
114     ~Worker();
115     void addRequest(WorkerTask request);
116 };
117 
118 template <typename... Args> struct MakeKeymasterWorkerCB;
119 
120 template <typename ErrorType, typename... Args>
121 struct MakeKeymasterWorkerCB<ErrorType, std::function<void(Args...)>> {
122     using type = std::function<void(ErrorType, std::tuple<std::decay_t<Args>...>&&)>;
123 };
124 
125 template <typename ErrorType> struct MakeKeymasterWorkerCB<ErrorType> {
126     using type = std::function<void(ErrorType)>;
127 };
128 
129 template <typename... Args>
130 using MakeKeymasterWorkerCB_t = typename MakeKeymasterWorkerCB<Args...>::type;
131 
132 class KeymasterWorker : protected Worker {
133   private:
134     sp<Keymaster> keymasterDevice_;
135     OperationMap operationMap_;
136     KeyStore* keyStore_;
137 
138     template <typename KMFn, typename ErrorType, typename... Args, size_t... I>
139     void unwrap_tuple(KMFn kmfn, std::function<void(ErrorType)> cb,
140                       const std::tuple<Args...>& tuple, std::index_sequence<I...>) {
141         cb(((*keymasterDevice_).*kmfn)(std::get<I>(tuple)...));
142     }
143 
144     template <typename KMFn, typename ErrorType, typename... ReturnTypes, typename... Args,
145               size_t... I>
146     void unwrap_tuple(KMFn kmfn, std::function<void(ErrorType, std::tuple<ReturnTypes...>&&)> cb,
147                       const std::tuple<Args...>& tuple, std::index_sequence<I...>) {
148         std::tuple<ReturnTypes...> returnValue;
149         auto result = ((*keymasterDevice_).*kmfn)(
150             std::get<I>(tuple)...,
151             [&returnValue](const ReturnTypes&... args) { returnValue = std::make_tuple(args...); });
152         cb(std::move(result), std::move(returnValue));
153     }
154 
155     template <typename KMFn, typename ErrorType, typename... Args>
156     void addRequest(KMFn kmfn, std::function<void(ErrorType)> cb, Args&&... args) {
157         Worker::addRequest([this, kmfn, cb = std::move(cb),
158                             tuple = std::make_tuple(std::forward<Args>(args)...)]() {
159             unwrap_tuple(kmfn, std::move(cb), tuple, std::index_sequence_for<Args...>{});
160         });
161     }
162 
163     template <typename KMFn, typename ErrorType, typename... ReturnTypes, typename... Args>
164     void addRequest(KMFn kmfn, std::function<void(ErrorType, std::tuple<ReturnTypes...>&&)> cb,
165                     Args&&... args) {
166         Worker::addRequest([this, kmfn, cb = std::move(cb),
167                             tuple = std::make_tuple(std::forward<Args>(args)...)]() {
168             unwrap_tuple(kmfn, std::move(cb), tuple, std::index_sequence_for<Args...>{});
169         });
170     }
171 
172     void deleteOldKeyOnUpgrade(const LockedKeyBlobEntry& blobfile, Blob keyBlob);
173     std::tuple<KeyStoreServiceReturnCode, Blob>
174     upgradeKeyBlob(const LockedKeyBlobEntry& lockedEntry, const AuthorizationSet& params);
175     std::tuple<KeyStoreServiceReturnCode, KeyCharacteristics, Blob, Blob>
176     createKeyCharacteristicsCache(const LockedKeyBlobEntry& lockedEntry,
177                                   const hidl_vec<uint8_t>& clientId,
178                                   const hidl_vec<uint8_t>& appData, Blob keyBlob, Blob charBlob);
179 
180     /**
181      * Get the auth token for this operation from the auth token table.
182      *
183      * Returns NO_ERROR if the auth token was found or none was required.  If not needed, the
184      *             token will be empty (which keymaster interprets as no auth token).
185      *         OP_AUTH_NEEDED if it is a per op authorization, no authorization token exists for
186      *             that operation and  failOnTokenMissing is false.
187      *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth token for the operation
188      */
189     std::pair<KeyStoreServiceReturnCode, HardwareAuthToken>
190     getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle, KeyPurpose purpose,
191                  bool failOnTokenMissing = true);
192 
193     KeyStoreServiceReturnCode abort(const sp<IBinder>& token);
194 
195     bool pruneOperation();
196 
197     KeyStoreServiceReturnCode getOperationAuthTokenIfNeeded(std::shared_ptr<Operation> op);
198 
199     void appendConfirmationTokenIfNeeded(const KeyCharacteristics& keyCharacteristics,
200                                          hidl_vec<KeyParameter>* params);
201 
202   public:
203     KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore);
204 
205     void logIfKeymasterVendorError(ErrorCode ec) const;
206 
207     using worker_begin_cb = std::function<void(::android::security::keymaster::OperationResult)>;
208     void begin(LockedKeyBlobEntry, sp<IBinder> appToken, Blob keyBlob, Blob charBlob,
209                bool pruneable, KeyPurpose purpose, AuthorizationSet opParams,
210                hidl_vec<uint8_t> entropy, worker_begin_cb worker_cb);
211 
212     using update_cb = std::function<void(::android::security::keymaster::OperationResult)>;
213     void update(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> data,
214                 update_cb _hidl_cb);
215 
216     using finish_cb = std::function<void(::android::security::keymaster::OperationResult)>;
217     void finish(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> input,
218                 hidl_vec<uint8_t> signature, hidl_vec<uint8_t> entorpy, finish_cb worker_cb);
219 
220     using abort_cb = std::function<void(KeyStoreServiceReturnCode)>;
221     void abort(sp<IBinder> token, abort_cb _hidl_cb);
222 
223     using getHardwareInfo_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::getHardwareInfo_cb>;
224     void getHardwareInfo(getHardwareInfo_cb _hidl_cb);
225 
226     using getHmacSharingParameters_cb =
227         MakeKeymasterWorkerCB_t<Return<void>, Keymaster::getHmacSharingParameters_cb>;
228     void getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb);
229 
230     using computeSharedHmac_cb =
231         MakeKeymasterWorkerCB_t<Return<void>, Keymaster::computeSharedHmac_cb>;
232     void computeSharedHmac(hidl_vec<HmacSharingParameters> params, computeSharedHmac_cb _hidl_cb);
233 
234     using verifyAuthorization_cb =
235         std::function<void(KeyStoreServiceReturnCode ec, HardwareAuthToken, VerificationToken)>;
236     void verifyAuthorization(uint64_t challenge, hidl_vec<KeyParameter> params,
237                              HardwareAuthToken token, verifyAuthorization_cb _hidl_cb);
238 
239     using addRngEntropy_cb = MakeKeymasterWorkerCB_t<Return<ErrorCode>>;
240     void addRngEntropy(hidl_vec<uint8_t> data, addRngEntropy_cb _hidl_cb);
241 
242     using generateKey_cb = std::function<void(
243         KeyStoreServiceReturnCode, ::android::hardware::keymaster::V4_0::KeyCharacteristics)>;
244     void generateKey(LockedKeyBlobEntry, hidl_vec<KeyParameter> keyParams,
245                      hidl_vec<uint8_t> entropy, int flags, generateKey_cb _hidl_cb);
246 
247     using generateKey2_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::generateKey_cb>;
248     void generateKey(hidl_vec<KeyParameter> keyParams, generateKey2_cb _hidl_cb);
249 
250     using getKeyCharacteristics_cb = std::function<void(
251         KeyStoreServiceReturnCode, ::android::hardware::keymaster::V4_0::KeyCharacteristics)>;
252     void getKeyCharacteristics(LockedKeyBlobEntry lockedEntry, hidl_vec<uint8_t> clientId,
253                                hidl_vec<uint8_t> appData, Blob keyBlob, Blob charBlob,
254                                getKeyCharacteristics_cb _hidl_cb);
255 
256     using importKey_cb = std::function<void(
257         KeyStoreServiceReturnCode, ::android::hardware::keymaster::V4_0::KeyCharacteristics)>;
258     void importKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyParameter> params,
259                    KeyFormat keyFormat, hidl_vec<uint8_t> keyData, int flags,
260                    importKey_cb _hidl_cb);
261 
262     using importWrappedKey_cb = std::function<void(
263         KeyStoreServiceReturnCode, ::android::hardware::keymaster::V4_0::KeyCharacteristics)>;
264     void importWrappedKey(LockedKeyBlobEntry wrappingLockedEntry,
265                           LockedKeyBlobEntry wrapppedLockedEntry, hidl_vec<uint8_t> wrappedKeyData,
266                           hidl_vec<uint8_t> maskingKey, hidl_vec<KeyParameter> unwrappingParams,
267                           Blob wrappingBlob, Blob wrappingCharBlob, uint64_t passwordSid,
268                           uint64_t biometricSid, importWrappedKey_cb worker_cb);
269 
270     using exportKey_cb = std::function<void(::android::security::keymaster::ExportResult)>;
271     void exportKey(LockedKeyBlobEntry lockedEntry, KeyFormat exportFormat,
272                    hidl_vec<uint8_t> clientId, hidl_vec<uint8_t> appData, Blob keyBlob,
273                    Blob charBlob, exportKey_cb _hidl_cb);
274 
275     using attestKey_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::attestKey_cb>;
276     void attestKey(hidl_vec<uint8_t> keyToAttest, hidl_vec<KeyParameter> attestParams,
277                    attestKey_cb _hidl_cb);
278 
279     using deleteKey_cb = MakeKeymasterWorkerCB_t<Return<ErrorCode>>;
280     void deleteKey(hidl_vec<uint8_t> keyBlob, deleteKey_cb _hidl_cb);
281 
282     using begin_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::begin_cb>;
283     void begin(KeyPurpose purpose, hidl_vec<uint8_t> key, hidl_vec<KeyParameter> inParams,
284                HardwareAuthToken authToken, begin_cb _hidl_cb);
285 
286     void binderDied(android::wp<IBinder> who);
287 
288     const Keymaster::VersionResult& halVersion() { return keymasterDevice_->halVersion(); }
289 };
290 
291 }  // namespace keystore
292 
293 #endif  // KEYSTORE_KEYMASTER_WORKER_H_
294