system/hardware/interfaces
Revision | 091884aedcec117521134fda7faffa0cf4cbc344 (tree) |
---|---|
Zeit | 2018-11-15 10:57:41 |
Autor | Janis Danisevskis <jdanis@goog...> |
Commiter | android-build-merger |
Merge "Multi-threaded Keystore" am: 7d6ca3b265
am: f4db2f14ca
Change-Id: I032441d60f79538785974e704a81c79b1d5a1027
@@ -20,4 +20,5 @@ cc_library_shared { | ||
20 | 20 | "libutils", |
21 | 21 | ], |
22 | 22 | export_include_dirs: ["include"], |
23 | + cpp_std: "c++17", | |
23 | 24 | } |
@@ -5,7 +5,7 @@ | ||
5 | 5 | #include <hidl/MQDescriptor.h> |
6 | 6 | #include <hidl/Status.h> |
7 | 7 | |
8 | -#include <android/security/IKeystoreService.h> | |
8 | +#include <android/security/keystore/IKeystoreService.h> | |
9 | 9 | #include <binder/IServiceManager.h> |
10 | 10 | |
11 | 11 | namespace android { |
@@ -1,17 +1,22 @@ | ||
1 | 1 | #include <android-base/logging.h> |
2 | -#include <android/security/IKeystoreService.h> | |
2 | +#include <android/security/keystore/BnKeystoreOperationResultCallback.h> | |
3 | +#include <android/security/keystore/BnKeystoreResponseCallback.h> | |
4 | +#include <android/security/keystore/IKeystoreService.h> | |
3 | 5 | #include <binder/IServiceManager.h> |
4 | 6 | #include <private/android_filesystem_config.h> |
5 | 7 | |
6 | 8 | #include <keystore/KeyCharacteristics.h> |
7 | 9 | #include <keystore/KeymasterArguments.h> |
8 | 10 | #include <keystore/KeymasterBlob.h> |
11 | +#include <keystore/KeystoreResponse.h> | |
9 | 12 | #include <keystore/OperationResult.h> |
10 | 13 | #include <keystore/keymaster_types.h> |
11 | 14 | #include <keystore/keystore.h> |
12 | 15 | #include <keystore/keystore_hidl_support.h> |
16 | +#include <keystore/keystore_promises.h> | |
13 | 17 | #include <keystore/keystore_return_types.h> |
14 | 18 | |
19 | +#include <future> | |
15 | 20 | #include <vector> |
16 | 21 | #include "include/wifikeystorehal/keystore.h" |
17 | 22 |
@@ -37,6 +42,12 @@ using KSReturn = keystore::KeyStoreNativeReturnCode; | ||
37 | 42 | namespace { |
38 | 43 | constexpr const char kKeystoreServiceName[] = "android.security.keystore"; |
39 | 44 | constexpr int32_t UID_SELF = -1; |
45 | + | |
46 | +using keystore::KeyCharacteristicsPromise; | |
47 | +using keystore::KeystoreExportPromise; | |
48 | +using keystore::KeystoreResponsePromise; | |
49 | +using keystore::OperationResultPromise; | |
50 | + | |
40 | 51 | }; // namespace |
41 | 52 | |
42 | 53 | #define AT __func__ << ":" << __LINE__ << " " |
@@ -48,7 +59,7 @@ namespace keystore { | ||
48 | 59 | namespace V1_0 { |
49 | 60 | namespace implementation { |
50 | 61 | |
51 | -using security::IKeystoreService; | |
62 | +using security::keystore::IKeystoreService; | |
52 | 63 | // Methods from ::android::hardware::wifi::keystore::V1_0::IKeystore follow. |
53 | 64 | Return<void> Keystore::getBlob(const hidl_string& key, getBlob_cb _hidl_cb) { |
54 | 65 | sp<IKeystoreService> service = interface_cast<IKeystoreService>( |
@@ -79,22 +90,33 @@ Return<void> Keystore::getPublicKey(const hidl_string& keyId, getPublicKey_cb _h | ||
79 | 90 | return Void(); |
80 | 91 | } |
81 | 92 | |
82 | - ExportResult result; | |
93 | + int32_t error_code; | |
94 | + android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise); | |
95 | + auto future = promise->get_future(); | |
83 | 96 | auto binder_result = service->exportKey( |
84 | - String16(keyId.c_str()), static_cast<int32_t>(KeyFormat::X509), | |
85 | - KeymasterBlob() /* clientId */, KeymasterBlob() /* appData */, UID_SELF, &result); | |
97 | + promise, String16(keyId.c_str()), static_cast<int32_t>(KeyFormat::X509), | |
98 | + KeymasterBlob() /* clientId */, KeymasterBlob() /* appData */, UID_SELF, &error_code); | |
86 | 99 | if (!binder_result.isOk()) { |
87 | 100 | LOG(ERROR) << AT << "communication error while calling keystore"; |
88 | 101 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
89 | 102 | return Void(); |
90 | 103 | } |
91 | - if (!result.resultCode.isOk()) { | |
92 | - LOG(ERROR) << AT << "exportKey failed: " << int32_t(result.resultCode); | |
104 | + | |
105 | + KSReturn rc(error_code); | |
106 | + if (!rc.isOk()) { | |
107 | + LOG(ERROR) << AT << "exportKey failed: " << error_code; | |
93 | 108 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
94 | 109 | return Void(); |
95 | 110 | } |
96 | 111 | |
97 | - _hidl_cb(KeystoreStatusCode::SUCCESS, result.exportData); | |
112 | + auto export_result = future.get(); | |
113 | + if (!export_result.resultCode.isOk()) { | |
114 | + LOG(ERROR) << AT << "exportKey failed: " << int32_t(export_result.resultCode); | |
115 | + _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); | |
116 | + return Void(); | |
117 | + } | |
118 | + | |
119 | + _hidl_cb(KeystoreStatusCode::SUCCESS, export_result.exportData); | |
98 | 120 | return Void(); |
99 | 121 | } |
100 | 122 |
@@ -123,21 +145,33 @@ Return<void> Keystore::sign(const hidl_string& keyId, const hidl_vec<uint8_t>& d | ||
123 | 145 | return Void(); |
124 | 146 | } |
125 | 147 | |
126 | - KeyCharacteristics keyCharacteristics; | |
127 | 148 | String16 key_name16(keyId.c_str()); |
128 | - int32_t aidl_result; | |
129 | - auto binder_result = service->getKeyCharacteristics( | |
130 | - key_name16, KeymasterBlob(), KeymasterBlob(), UID_SELF, &keyCharacteristics, &aidl_result); | |
149 | + int32_t error_code; | |
150 | + android::sp<KeyCharacteristicsPromise> kc_promise(new KeyCharacteristicsPromise); | |
151 | + auto kc_future = kc_promise->get_future(); | |
152 | + auto binder_result = service->getKeyCharacteristics(kc_promise, key_name16, KeymasterBlob(), | |
153 | + KeymasterBlob(), UID_SELF, &error_code); | |
131 | 154 | if (!binder_result.isOk()) { |
132 | 155 | LOG(ERROR) << AT << "communication error while calling keystore"; |
133 | 156 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
134 | 157 | return Void(); |
135 | 158 | } |
136 | - if (KSReturn(aidl_result).isOk()) { | |
137 | - LOG(ERROR) << AT << "getKeyCharacteristics failed: " << aidl_result; | |
159 | + KSReturn rc(error_code); | |
160 | + if (!rc.isOk()) { | |
161 | + LOG(ERROR) << AT << "getKeyCharacteristics failed: " << error_code; | |
162 | + _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); | |
163 | + return Void(); | |
164 | + } | |
165 | + | |
166 | + auto [km_response, characteristics] = kc_future.get(); | |
167 | + | |
168 | + if (KSReturn(km_response.response_code()).isOk()) { | |
169 | + LOG(ERROR) << AT << "getKeyCharacteristics failed: " << km_response.response_code(); | |
170 | + _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); | |
171 | + return Void(); | |
138 | 172 | } |
139 | 173 | |
140 | - auto algorithm = getKeyAlgoritmFromKeyCharacteristics(keyCharacteristics); | |
174 | + auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics); | |
141 | 175 | if (!algorithm.isOk()) { |
142 | 176 | LOG(ERROR) << AT << "could not get algorithm from key characteristics"; |
143 | 177 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
@@ -150,15 +184,25 @@ Return<void> Keystore::sign(const hidl_string& keyId, const hidl_vec<uint8_t>& d | ||
150 | 184 | params[2] = Authorization(TAG_ALGORITHM, algorithm.value()); |
151 | 185 | |
152 | 186 | android::sp<android::IBinder> token(new android::BBinder); |
153 | - OperationResult result; | |
154 | - binder_result = service->begin(token, key_name16, (int)KeyPurpose::SIGN, true /*pruneable*/, | |
155 | - KeymasterArguments(params), std::vector<uint8_t>() /* entropy */, | |
156 | - UID_SELF, &result); | |
187 | + sp<OperationResultPromise> promise(new OperationResultPromise()); | |
188 | + auto future = promise->get_future(); | |
189 | + binder_result = service->begin(promise, token, key_name16, (int)KeyPurpose::SIGN, | |
190 | + true /*pruneable*/, KeymasterArguments(params), | |
191 | + std::vector<uint8_t>() /* entropy */, UID_SELF, &error_code); | |
157 | 192 | if (!binder_result.isOk()) { |
158 | 193 | LOG(ERROR) << AT << "communication error while calling keystore"; |
159 | 194 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
160 | 195 | return Void(); |
161 | 196 | } |
197 | + | |
198 | + rc = KSReturn(error_code); | |
199 | + if (!rc.isOk()) { | |
200 | + LOG(ERROR) << AT << "Keystore begin returned: " << int32_t(rc); | |
201 | + _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); | |
202 | + return Void(); | |
203 | + } | |
204 | + | |
205 | + OperationResult result = future.get(); | |
162 | 206 | if (!result.resultCode.isOk()) { |
163 | 207 | LOG(ERROR) << AT << "begin failed: " << int32_t(result.resultCode); |
164 | 208 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
@@ -169,13 +213,24 @@ Return<void> Keystore::sign(const hidl_string& keyId, const hidl_vec<uint8_t>& d | ||
169 | 213 | const uint8_t* in = dataToSign.data(); |
170 | 214 | size_t len = dataToSign.size(); |
171 | 215 | do { |
172 | - binder_result = service->update(handle, KeymasterArguments(params), | |
173 | - std::vector<uint8_t>(in, in + len), &result); | |
216 | + future = {}; | |
217 | + binder_result = service->update(promise, handle, KeymasterArguments(params), | |
218 | + std::vector<uint8_t>(in, in + len), &error_code); | |
174 | 219 | if (!binder_result.isOk()) { |
175 | 220 | LOG(ERROR) << AT << "communication error while calling keystore"; |
176 | 221 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
177 | 222 | return Void(); |
178 | 223 | } |
224 | + | |
225 | + rc = KSReturn(error_code); | |
226 | + if (!rc.isOk()) { | |
227 | + LOG(ERROR) << AT << "Keystore update returned: " << int32_t(rc); | |
228 | + _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); | |
229 | + return Void(); | |
230 | + } | |
231 | + | |
232 | + result = future.get(); | |
233 | + | |
179 | 234 | if (!result.resultCode.isOk()) { |
180 | 235 | LOG(ERROR) << AT << "update failed: " << int32_t(result.resultCode); |
181 | 236 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
@@ -183,7 +238,22 @@ Return<void> Keystore::sign(const hidl_string& keyId, const hidl_vec<uint8_t>& d | ||
183 | 238 | } |
184 | 239 | if ((size_t)result.inputConsumed > len) { |
185 | 240 | LOG(ERROR) << AT << "update consumed more data than provided"; |
186 | - service->abort(handle, &aidl_result); | |
241 | + sp<KeystoreResponsePromise> abortPromise(new KeystoreResponsePromise); | |
242 | + auto abortFuture = abortPromise->get_future(); | |
243 | + binder_result = service->abort(abortPromise, handle, &error_code); | |
244 | + if (!binder_result.isOk()) { | |
245 | + LOG(ERROR) << AT << "communication error while calling keystore"; | |
246 | + _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); | |
247 | + return Void(); | |
248 | + } | |
249 | + // This is mainly for logging since we already failed. | |
250 | + // But if abort returned OK we have to wait untill abort calls the callback | |
251 | + // hence the call to abortFuture.get(). | |
252 | + if (!KSReturn(error_code).isOk()) { | |
253 | + LOG(ERROR) << AT << "abort failed: " << error_code; | |
254 | + } else if (!(rc = KSReturn(abortFuture.get().response_code())).isOk()) { | |
255 | + LOG(ERROR) << AT << "abort failed: " << int32_t(rc); | |
256 | + } | |
187 | 257 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
188 | 258 | return Void(); |
189 | 259 | } |
@@ -191,14 +261,28 @@ Return<void> Keystore::sign(const hidl_string& keyId, const hidl_vec<uint8_t>& d | ||
191 | 261 | in += result.inputConsumed; |
192 | 262 | } while (len > 0); |
193 | 263 | |
194 | - binder_result = | |
195 | - service->finish(handle, KeymasterArguments(params), std::vector<uint8_t>() /* signature */, | |
196 | - std::vector<uint8_t>() /* entropy */, &result); | |
264 | + future = {}; | |
265 | + promise = new OperationResultPromise(); | |
266 | + future = promise->get_future(); | |
267 | + | |
268 | + binder_result = service->finish(promise, handle, KeymasterArguments(params), | |
269 | + std::vector<uint8_t>() /* signature */, | |
270 | + std::vector<uint8_t>() /* entropy */, &error_code); | |
197 | 271 | if (!binder_result.isOk()) { |
198 | 272 | LOG(ERROR) << AT << "communication error while calling keystore"; |
199 | 273 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |
200 | 274 | return Void(); |
201 | 275 | } |
276 | + | |
277 | + rc = KSReturn(error_code); | |
278 | + if (!rc.isOk()) { | |
279 | + LOG(ERROR) << AT << "Keystore finish returned: " << int32_t(rc); | |
280 | + _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); | |
281 | + return Void(); | |
282 | + } | |
283 | + | |
284 | + result = future.get(); | |
285 | + | |
202 | 286 | if (!result.resultCode.isOk()) { |
203 | 287 | LOG(ERROR) << AT << "finish failed: " << int32_t(result.resultCode); |
204 | 288 | _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {}); |