1 #include <android-base/logging.h>
2 #include <android/security/keystore/BnKeystoreOperationResultCallback.h>
3 #include <android/security/keystore/BnKeystoreResponseCallback.h>
4 #include <android/security/keystore/IKeystoreService.h>
5 #include <binder/IServiceManager.h>
6 #include <private/android_filesystem_config.h>
8 #include <keystore/KeyCharacteristics.h>
9 #include <keystore/KeymasterArguments.h>
10 #include <keystore/KeymasterBlob.h>
11 #include <keystore/KeystoreResponse.h>
12 #include <keystore/OperationResult.h>
13 #include <keystore/keymaster_types.h>
14 #include <keystore/keystore.h>
15 #include <keystore/keystore_hidl_support.h>
16 #include <keystore/keystore_promises.h>
17 #include <keystore/keystore_return_types.h>
21 #include "include/wifikeystorehal/keystore.h"
23 using android::hardware::keymaster::V4_0::Algorithm;
24 using android::hardware::keymaster::V4_0::authorizationValue;
25 using android::hardware::keymaster::V4_0::Digest;
26 using android::hardware::keymaster::V4_0::KeyFormat;
27 using android::hardware::keymaster::V4_0::KeyParameter;
28 using android::hardware::keymaster::V4_0::KeyPurpose;
29 using android::hardware::keymaster::V4_0::NullOr;
30 using android::hardware::keymaster::V4_0::PaddingMode;
31 using android::hardware::keymaster::V4_0::TAG_ALGORITHM;
32 using android::hardware::keymaster::V4_0::TAG_DIGEST;
33 using android::hardware::keymaster::V4_0::TAG_PADDING;
34 using android::security::keymaster::ExportResult;
35 using android::security::keymaster::KeyCharacteristics;
36 using android::security::keymaster::KeymasterArguments;
37 using android::security::keymaster::KeymasterBlob;
38 using android::security::keymaster::OperationResult;
40 using KSReturn = keystore::KeyStoreNativeReturnCode;
43 constexpr const char kKeystoreServiceName[] = "android.security.keystore";
44 constexpr int32_t UID_SELF = -1;
46 using keystore::KeyCharacteristicsPromise;
47 using keystore::KeystoreExportPromise;
48 using keystore::KeystoreResponsePromise;
49 using keystore::OperationResultPromise;
53 #define AT __func__ << ":" << __LINE__ << " "
60 namespace implementation {
62 using security::keystore::IKeystoreService;
63 // Methods from ::android::hardware::wifi::keystore::V1_0::IKeystore follow.
64 Return<void> Keystore::getBlob(const hidl_string& key, getBlob_cb _hidl_cb) {
65 sp<IKeystoreService> service = interface_cast<IKeystoreService>(
66 defaultServiceManager()->getService(String16(kKeystoreServiceName)));
67 if (service == nullptr) {
68 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
71 ::std::vector<uint8_t> value;
72 // Retrieve the blob as wifi user.
73 auto ret = service->get(String16(key.c_str()), AID_WIFI, &value);
75 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
78 _hidl_cb(KeystoreStatusCode::SUCCESS, (hidl_vec<uint8_t>)value);
82 Return<void> Keystore::getPublicKey(const hidl_string& keyId, getPublicKey_cb _hidl_cb) {
83 sp<IServiceManager> sm = defaultServiceManager();
84 sp<IBinder> binder = sm->getService(String16(kKeystoreServiceName));
85 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
87 if (service == nullptr) {
88 LOG(ERROR) << AT << "could not contact keystore";
89 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
94 android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
95 auto future = promise->get_future();
96 auto binder_result = service->exportKey(
97 promise, String16(keyId.c_str()), static_cast<int32_t>(KeyFormat::X509),
98 KeymasterBlob() /* clientId */, KeymasterBlob() /* appData */, UID_SELF, &error_code);
99 if (!binder_result.isOk()) {
100 LOG(ERROR) << AT << "communication error while calling keystore";
101 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
105 KSReturn rc(error_code);
107 LOG(ERROR) << AT << "exportKey failed: " << error_code;
108 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
112 auto export_result = future.get();
113 if (!export_result.resultCode.isOk()) {
114 LOG(ERROR) << AT << "exportKey failed: " << export_result.resultCode;
115 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
119 _hidl_cb(KeystoreStatusCode::SUCCESS, export_result.exportData);
123 static NullOr<const Algorithm&> getKeyAlgoritmFromKeyCharacteristics(
124 const ::android::security::keymaster::KeyCharacteristics& characteristics) {
125 for (const auto& param : characteristics.hardwareEnforced.getParameters()) {
126 auto algo = authorizationValue(TAG_ALGORITHM, param);
127 if (algo.isOk()) return algo;
129 for (const auto& param : characteristics.softwareEnforced.getParameters()) {
130 auto algo = authorizationValue(TAG_ALGORITHM, param);
131 if (algo.isOk()) return algo;
136 Return<void> Keystore::sign(const hidl_string& keyId, const hidl_vec<uint8_t>& dataToSign,
138 sp<IServiceManager> sm = defaultServiceManager();
139 sp<IBinder> binder = sm->getService(String16(kKeystoreServiceName));
140 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
142 if (service == nullptr) {
143 LOG(ERROR) << AT << "could not contact keystore";
144 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
148 String16 key_name16(keyId.c_str());
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);
154 if (!binder_result.isOk()) {
155 LOG(ERROR) << AT << "communication error while calling keystore";
156 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
159 KSReturn rc(error_code);
161 LOG(ERROR) << AT << "getKeyCharacteristics failed: " << error_code;
162 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
166 auto [km_response, characteristics] = kc_future.get();
168 if (!KSReturn(km_response.response_code()).isOk()) {
169 LOG(ERROR) << AT << "getKeyCharacteristics failed: " << km_response.response_code();
170 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
174 auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
175 if (!algorithm.isOk()) {
176 LOG(ERROR) << AT << "could not get algorithm from key characteristics";
177 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
181 hidl_vec<KeyParameter> params(3);
182 params[0] = Authorization(TAG_DIGEST, Digest::NONE);
183 params[1] = Authorization(TAG_PADDING, PaddingMode::NONE);
184 params[2] = Authorization(TAG_ALGORITHM, algorithm.value());
186 android::sp<android::IBinder> token(new android::BBinder);
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);
192 if (!binder_result.isOk()) {
193 LOG(ERROR) << AT << "communication error while calling keystore";
194 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
198 rc = KSReturn(error_code);
200 LOG(ERROR) << AT << "Keystore begin returned: " << rc;
201 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
205 OperationResult result = future.get();
206 if (!result.resultCode.isOk()) {
207 LOG(ERROR) << AT << "begin failed: " << result.resultCode;
208 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
211 auto handle = std::move(result.token);
213 const uint8_t* in = dataToSign.data();
214 size_t len = dataToSign.size();
217 binder_result = service->update(promise, handle, KeymasterArguments(params),
218 std::vector<uint8_t>(in, in + len), &error_code);
219 if (!binder_result.isOk()) {
220 LOG(ERROR) << AT << "communication error while calling keystore";
221 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
225 rc = KSReturn(error_code);
227 LOG(ERROR) << AT << "Keystore update returned: " << rc;
228 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
232 result = future.get();
234 if (!result.resultCode.isOk()) {
235 LOG(ERROR) << AT << "update failed: " << result.resultCode;
236 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
239 if ((size_t)result.inputConsumed > len) {
240 LOG(ERROR) << AT << "update consumed more data than provided";
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, {});
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: " << rc;
257 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
260 len -= result.inputConsumed;
261 in += result.inputConsumed;
265 promise = new OperationResultPromise();
266 future = promise->get_future();
268 binder_result = service->finish(promise, handle, KeymasterArguments(params),
269 std::vector<uint8_t>() /* signature */,
270 std::vector<uint8_t>() /* entropy */, &error_code);
271 if (!binder_result.isOk()) {
272 LOG(ERROR) << AT << "communication error while calling keystore";
273 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
277 rc = KSReturn(error_code);
279 LOG(ERROR) << AT << "Keystore finish returned: " << rc;
280 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
284 result = future.get();
286 if (!result.resultCode.isOk()) {
287 LOG(ERROR) << AT << "finish failed: " << result.resultCode;
288 _hidl_cb(KeystoreStatusCode::ERROR_UNKNOWN, {});
292 _hidl_cb(KeystoreStatusCode::SUCCESS, result.data);
296 IKeystore* HIDL_FETCH_IKeystore(const char* /* name */) {
297 return new Keystore();
299 } // namespace implementation
301 } // namespace keystore
303 } // namespace system
304 } // namespace android