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