1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #define LOG_TAG "keystore_client"
16
17 #include "keystore/keystore_client_impl.h"
18
19 #include <future>
20 #include <string>
21 #include <vector>
22
23 #include <android/security/keystore/IKeystoreService.h>
24 #include <binder/IBinder.h>
25 #include <binder/IInterface.h>
26 #include <binder/IServiceManager.h>
27 #include <keystore/keystore.h>
28 #include <log/log.h>
29 #include <utils/String16.h>
30 #include <utils/String8.h>
31
32 #include <keystore/keymaster_types.h>
33 #include <keystore/keystore_hidl_support.h>
34 #include <keystore/keystore_promises.h>
35
36 #include "keystore_client.pb.h"
37
38 namespace {
39
40 // Use the UID of the current process.
41 const int kDefaultUID = -1;
42 const char kEncryptSuffix[] = "_ENC";
43 const char kAuthenticateSuffix[] = "_AUTH";
44 constexpr uint32_t kAESKeySize = 256; // bits
45 constexpr uint32_t kHMACKeySize = 256; // bits
46 constexpr uint32_t kHMACOutputSize = 256; // bits
47
48 using android::String16;
49 using android::security::keymaster::ExportResult;
50 using android::security::keymaster::OperationResult;
51 using android::security::keystore::KeystoreResponse;
52 using keystore::AuthorizationSet;
53 using keystore::AuthorizationSetBuilder;
54 using keystore::KeyCharacteristics;
55 using keystore::KeyStoreServiceReturnCode;
56 } // namespace
57
58 namespace keystore {
59
KeystoreClientImpl()60 KeystoreClientImpl::KeystoreClientImpl() {
61 service_manager_ = android::defaultServiceManager();
62 keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
63 keystore_ =
64 android::interface_cast<android::security::keystore::IKeystoreService>(keystore_binder_);
65 }
66
encryptWithAuthentication(const std::string & key_name,const std::string & data,int32_t flags,std::string * encrypted_data)67 bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
68 const std::string& data, int32_t flags,
69 std::string* encrypted_data) {
70 // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
71 // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
72 // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
73 // because hardware support for GCM is not mandatory for all Brillo devices.
74 std::string encryption_key_name = key_name + kEncryptSuffix;
75 if (!createOrVerifyEncryptionKey(encryption_key_name, flags)) {
76 return false;
77 }
78 std::string authentication_key_name = key_name + kAuthenticateSuffix;
79 if (!createOrVerifyAuthenticationKey(authentication_key_name, flags)) {
80 return false;
81 }
82 AuthorizationSetBuilder encrypt_params;
83 encrypt_params.Padding(PaddingMode::PKCS7);
84 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
85 AuthorizationSet output_params;
86 std::string raw_encrypted_data;
87 if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
88 std::string(), /* signature_to_verify */
89 &output_params, &raw_encrypted_data)) {
90 ALOGE("Encrypt: AES operation failed.");
91 return false;
92 }
93 auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
94 if (!init_vector_blob.isOk()) {
95 ALOGE("Encrypt: Missing initialization vector.");
96 return false;
97 }
98 std::string init_vector = hidlVec2String(init_vector_blob.value());
99
100 AuthorizationSetBuilder authenticate_params;
101 authenticate_params.Digest(Digest::SHA_2_256);
102 authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
103 std::string raw_authentication_data;
104 if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
105 init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */
106 &output_params, &raw_authentication_data)) {
107 ALOGE("Encrypt: HMAC operation failed.");
108 return false;
109 }
110 EncryptedData protobuf;
111 protobuf.set_init_vector(init_vector);
112 protobuf.set_authentication_data(raw_authentication_data);
113 protobuf.set_encrypted_data(raw_encrypted_data);
114 if (!protobuf.SerializeToString(encrypted_data)) {
115 ALOGE("Encrypt: Failed to serialize EncryptedData protobuf.");
116 return false;
117 }
118 return true;
119 }
120
decryptWithAuthentication(const std::string & key_name,const std::string & encrypted_data,std::string * data)121 bool KeystoreClientImpl::decryptWithAuthentication(const std::string& key_name,
122 const std::string& encrypted_data,
123 std::string* data) {
124 EncryptedData protobuf;
125 if (!protobuf.ParseFromString(encrypted_data)) {
126 ALOGE("Decrypt: Failed to parse EncryptedData protobuf.");
127 }
128 // Verify authentication before attempting decryption.
129 std::string authentication_key_name = key_name + kAuthenticateSuffix;
130 AuthorizationSetBuilder authenticate_params;
131 authenticate_params.Digest(Digest::SHA_2_256);
132 AuthorizationSet output_params;
133 std::string output_data;
134 if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
135 protobuf.init_vector() + protobuf.encrypted_data(),
136 protobuf.authentication_data(), &output_params, &output_data)) {
137 ALOGE("Decrypt: HMAC operation failed.");
138 return false;
139 }
140 std::string encryption_key_name = key_name + kEncryptSuffix;
141 AuthorizationSetBuilder encrypt_params;
142 encrypt_params.Padding(PaddingMode::PKCS7);
143 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
144 encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
145 protobuf.init_vector().size());
146 if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
147 protobuf.encrypted_data(), std::string(), /* signature_to_verify */
148 &output_params, data)) {
149 ALOGE("Decrypt: AES operation failed.");
150 return false;
151 }
152 return true;
153 }
154
oneShotOperation(KeyPurpose purpose,const std::string & key_name,const AuthorizationSet & input_parameters,const std::string & input_data,const std::string & signature_to_verify,AuthorizationSet * output_parameters,std::string * output_data)155 bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
156 const AuthorizationSet& input_parameters,
157 const std::string& input_data,
158 const std::string& signature_to_verify,
159 AuthorizationSet* output_parameters,
160 std::string* output_data) {
161 uint64_t handle;
162 auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
163 if (!result.isOk()) {
164 ALOGE("BeginOperation failed: %d", result.getErrorCode());
165 return false;
166 }
167 AuthorizationSet empty_params;
168 size_t num_input_bytes_consumed;
169 AuthorizationSet ignored_params;
170 result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed,
171 &ignored_params, output_data);
172 if (!result.isOk()) {
173 ALOGE("UpdateOperation failed: %d", result.getErrorCode());
174 return false;
175 }
176 result =
177 finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
178 if (!result.isOk()) {
179 ALOGE("FinishOperation failed: %d", result.getErrorCode());
180 return false;
181 }
182 return true;
183 }
184
185 KeyStoreNativeReturnCode
addRandomNumberGeneratorEntropy(const std::string & entropy,int32_t flags)186 KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy, int32_t flags) {
187 int32_t error_code;
188
189 android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise());
190 auto future = promise->get_future();
191
192 auto binder_result =
193 keystore_->addRngEntropy(promise, blob2hidlVec(entropy), flags, &error_code);
194 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
195
196 KeyStoreNativeReturnCode rc(error_code);
197 if (!rc.isOk()) return rc;
198
199 auto result = future.get();
200
201 return KeyStoreNativeReturnCode(result.response_code());
202 }
203
204 KeyStoreNativeReturnCode
generateKey(const std::string & key_name,const AuthorizationSet & key_parameters,int32_t flags,AuthorizationSet * hardware_enforced_characteristics,AuthorizationSet * software_enforced_characteristics)205 KeystoreClientImpl::generateKey(const std::string& key_name, const AuthorizationSet& key_parameters,
206 int32_t flags, AuthorizationSet* hardware_enforced_characteristics,
207 AuthorizationSet* software_enforced_characteristics) {
208 String16 key_name16(key_name.data(), key_name.size());
209 int32_t error_code;
210 android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
211 auto future = promise->get_future();
212 auto binder_result = keystore_->generateKey(
213 promise, key_name16,
214 ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
215 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, flags, &error_code);
216 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
217
218 KeyStoreNativeReturnCode rc(error_code);
219 if (!rc.isOk()) return rc;
220
221 auto [km_response, characteristics] = future.get();
222
223 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
224 * There are no references to Parcel memory after that, and ownership of the newly acquired
225 * memory is with the AuthorizationSet objects. */
226 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
227 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
228 return KeyStoreNativeReturnCode(km_response.response_code());
229 }
230
231 KeyStoreNativeReturnCode
getKeyCharacteristics(const std::string & key_name,AuthorizationSet * hardware_enforced_characteristics,AuthorizationSet * software_enforced_characteristics)232 KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
233 AuthorizationSet* hardware_enforced_characteristics,
234 AuthorizationSet* software_enforced_characteristics) {
235 String16 key_name16(key_name.data(), key_name.size());
236 int32_t error_code;
237 android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
238 auto future = promise->get_future();
239 auto binder_result = keystore_->getKeyCharacteristics(
240 promise, key_name16, android::security::keymaster::KeymasterBlob(),
241 android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
242 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
243
244 KeyStoreNativeReturnCode rc(error_code);
245 if (!rc.isOk()) return rc;
246
247 auto [km_response, characteristics] = future.get();
248
249 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
250 * There are no references to Parcel memory after that, and ownership of the newly acquired
251 * memory is with the AuthorizationSet objects. */
252 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
253 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
254 return KeyStoreNativeReturnCode(km_response.response_code());
255 }
256
257 KeyStoreNativeReturnCode
importKey(const std::string & key_name,const AuthorizationSet & key_parameters,KeyFormat key_format,const std::string & key_data,AuthorizationSet * hardware_enforced_characteristics,AuthorizationSet * software_enforced_characteristics)258 KeystoreClientImpl::importKey(const std::string& key_name, const AuthorizationSet& key_parameters,
259 KeyFormat key_format, const std::string& key_data,
260 AuthorizationSet* hardware_enforced_characteristics,
261 AuthorizationSet* software_enforced_characteristics) {
262 String16 key_name16(key_name.data(), key_name.size());
263 auto hidlKeyData = blob2hidlVec(key_data);
264 int32_t error_code;
265 android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
266 auto future = promise->get_future();
267 auto binder_result = keystore_->importKey(
268 promise, key_name16,
269 ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
270 (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &error_code);
271 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
272
273 KeyStoreNativeReturnCode rc(error_code);
274 if (!rc.isOk()) return rc;
275
276 auto [km_response, characteristics] = future.get();
277
278 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
279 * There are no references to Parcel memory after that, and ownership of the newly acquired
280 * memory is with the AuthorizationSet objects. */
281 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
282 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
283 return KeyStoreNativeReturnCode(km_response.response_code());
284 }
285
exportKey(KeyFormat export_format,const std::string & key_name,std::string * export_data)286 KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
287 const std::string& key_name,
288 std::string* export_data) {
289 String16 key_name16(key_name.data(), key_name.size());
290 int32_t error_code;
291 android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
292 auto future = promise->get_future();
293 auto binder_result = keystore_->exportKey(
294 promise, key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
295 android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
296 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
297
298 KeyStoreNativeReturnCode rc(error_code);
299 if (!rc.isOk()) return rc;
300
301 auto export_result = future.get();
302 if (!export_result.resultCode.isOk()) return export_result.resultCode;
303
304 *export_data = hidlVec2String(export_result.exportData);
305
306 return export_result.resultCode;
307 }
308
deleteKey(const std::string & key_name)309 KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
310 String16 key_name16(key_name.data(), key_name.size());
311 int32_t result;
312 auto binder_result = keystore_->del(key_name16, kDefaultUID, &result);
313 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
314 return KeyStoreNativeReturnCode(result);
315 }
316
deleteAllKeys()317 KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
318 int32_t result;
319 auto binder_result = keystore_->clear_uid(kDefaultUID, &result);
320 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
321 return KeyStoreNativeReturnCode(result);
322 }
323
324 KeyStoreNativeReturnCode
beginOperation(KeyPurpose purpose,const std::string & key_name,const AuthorizationSet & input_parameters,AuthorizationSet * output_parameters,uint64_t * handle)325 KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
326 const AuthorizationSet& input_parameters,
327 AuthorizationSet* output_parameters, uint64_t* handle) {
328 android::sp<android::IBinder> token(new android::BBinder);
329 String16 key_name16(key_name.data(), key_name.size());
330 int32_t error_code;
331 android::sp<OperationResultPromise> promise(new OperationResultPromise{});
332 auto future = promise->get_future();
333 auto binder_result = keystore_->begin(
334 promise, token, key_name16, (int)purpose, true /*pruneable*/,
335 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
336 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &error_code);
337 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
338 KeyStoreNativeReturnCode rc(error_code);
339 if (!rc.isOk()) return rc;
340
341 OperationResult result = future.get();
342 if (result.resultCode.isOk()) {
343 *handle = getNextVirtualHandle();
344 active_operations_[*handle] = result.token;
345 if (result.outParams.size()) {
346 *output_parameters = result.outParams;
347 }
348 }
349 return result.resultCode;
350 }
351
352 KeyStoreNativeReturnCode
updateOperation(uint64_t handle,const AuthorizationSet & input_parameters,const std::string & input_data,size_t * num_input_bytes_consumed,AuthorizationSet * output_parameters,std::string * output_data)353 KeystoreClientImpl::updateOperation(uint64_t handle, const AuthorizationSet& input_parameters,
354 const std::string& input_data, size_t* num_input_bytes_consumed,
355 AuthorizationSet* output_parameters, std::string* output_data) {
356 if (active_operations_.count(handle) == 0) {
357 return ErrorCode::INVALID_OPERATION_HANDLE;
358 }
359 auto hidlInputData = blob2hidlVec(input_data);
360 int32_t error_code;
361 android::sp<OperationResultPromise> promise(new OperationResultPromise{});
362 auto future = promise->get_future();
363 auto binder_result = keystore_->update(
364 promise, active_operations_[handle],
365 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
366 hidlInputData, &error_code);
367 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
368 KeyStoreNativeReturnCode rc(error_code);
369 if (!rc.isOk()) return rc;
370
371 OperationResult result = future.get();
372
373 if (result.resultCode.isOk()) {
374 *num_input_bytes_consumed = result.inputConsumed;
375 if (result.outParams.size()) {
376 *output_parameters = result.outParams;
377 }
378 // TODO verify that append should not be assign
379 output_data->append(hidlVec2String(result.data));
380 }
381 return result.resultCode;
382 }
383
384 KeyStoreNativeReturnCode
finishOperation(uint64_t handle,const AuthorizationSet & input_parameters,const std::string & signature_to_verify,AuthorizationSet * output_parameters,std::string * output_data)385 KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& input_parameters,
386 const std::string& signature_to_verify,
387 AuthorizationSet* output_parameters, std::string* output_data) {
388 if (active_operations_.count(handle) == 0) {
389 return ErrorCode::INVALID_OPERATION_HANDLE;
390 }
391 int32_t error_code;
392 auto hidlSignature = blob2hidlVec(signature_to_verify);
393 android::sp<OperationResultPromise> promise(new OperationResultPromise{});
394 auto future = promise->get_future();
395 auto binder_result = keystore_->finish(
396 promise, active_operations_[handle],
397 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
398 (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &error_code);
399 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
400 KeyStoreNativeReturnCode rc(error_code);
401 if (!rc.isOk()) return rc;
402
403 OperationResult result = future.get();
404 if (result.resultCode.isOk()) {
405 if (result.outParams.size()) {
406 *output_parameters = result.outParams;
407 }
408 // TODO verify that append should not be assign
409 output_data->append(hidlVec2String(result.data));
410 active_operations_.erase(handle);
411 }
412 return result.resultCode;
413 }
414
abortOperation(uint64_t handle)415 KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
416 if (active_operations_.count(handle) == 0) {
417 return ErrorCode::INVALID_OPERATION_HANDLE;
418 }
419 int32_t result;
420 android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise{});
421 auto future = promise->get_future();
422 // Current implementation does not return exceptions in android::binder::Status
423 auto binder_result = keystore_->abort(promise, active_operations_[handle], &result);
424 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
425 KeyStoreNativeReturnCode rc(result);
426 if (!rc.isOk()) return rc;
427 rc = KeyStoreNativeReturnCode(future.get().response_code());
428 if (rc.isOk()) {
429 active_operations_.erase(handle);
430 }
431 return rc;
432 }
433
doesKeyExist(const std::string & key_name)434 bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
435 String16 key_name16(key_name.data(), key_name.size());
436 int32_t result;
437 auto binder_result = keystore_->exist(key_name16, kDefaultUID, &result);
438 if (!binder_result.isOk()) return false; // binder error
439 return result == static_cast<int32_t>(ResponseCode::NO_ERROR);
440 }
441
listKeys(const std::string & prefix,std::vector<std::string> * key_name_list)442 bool KeystoreClientImpl::listKeys(const std::string& prefix,
443 std::vector<std::string>* key_name_list) {
444 String16 prefix16(prefix.data(), prefix.size());
445 std::vector<::android::String16> matches;
446 auto binder_result = keystore_->list(prefix16, kDefaultUID, &matches);
447 if (!binder_result.isOk()) return false;
448
449 for (const auto& match : matches) {
450 android::String8 key_name(match);
451 key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
452 }
453 return true;
454 }
455
getNextVirtualHandle()456 uint64_t KeystoreClientImpl::getNextVirtualHandle() {
457 return next_virtual_handle_++;
458 }
459
createOrVerifyEncryptionKey(const std::string & key_name,int32_t flags)460 bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name, int32_t flags) {
461 bool key_exists = doesKeyExist(key_name);
462 if (key_exists) {
463 bool verified = false;
464 if (!verifyEncryptionKeyAttributes(key_name, &verified)) {
465 return false;
466 }
467 if (!verified) {
468 auto result = deleteKey(key_name);
469 if (!result.isOk()) {
470 ALOGE("Failed to delete invalid encryption key: %d", result.getErrorCode());
471 return false;
472 }
473 key_exists = false;
474 }
475 }
476 if (!key_exists) {
477 AuthorizationSetBuilder key_parameters;
478 key_parameters.AesEncryptionKey(kAESKeySize)
479 .Padding(PaddingMode::PKCS7)
480 .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
481 .Authorization(TAG_NO_AUTH_REQUIRED);
482 AuthorizationSet hardware_enforced_characteristics;
483 AuthorizationSet software_enforced_characteristics;
484 auto result =
485 generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
486 &software_enforced_characteristics);
487 if (!result.isOk()) {
488 ALOGE("Failed to generate encryption key: %d", result.getErrorCode());
489 return false;
490 }
491 if (hardware_enforced_characteristics.size() == 0) {
492 ALOGW("WARNING: Encryption key is not hardware-backed.");
493 }
494 }
495 return true;
496 }
497
createOrVerifyAuthenticationKey(const std::string & key_name,int32_t flags)498 bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name,
499 int32_t flags) {
500 bool key_exists = doesKeyExist(key_name);
501 if (key_exists) {
502 bool verified = false;
503 if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
504 return false;
505 }
506 if (!verified) {
507 auto result = deleteKey(key_name);
508 if (!result.isOk()) {
509 ALOGE("Failed to delete invalid authentication key: %d", result.getErrorCode());
510 return false;
511 }
512 key_exists = false;
513 }
514 }
515 if (!key_exists) {
516 AuthorizationSetBuilder key_parameters;
517 key_parameters.HmacKey(kHMACKeySize)
518 .Digest(Digest::SHA_2_256)
519 .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
520 .Authorization(TAG_NO_AUTH_REQUIRED);
521 AuthorizationSet hardware_enforced_characteristics;
522 AuthorizationSet software_enforced_characteristics;
523 auto result =
524 generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
525 &software_enforced_characteristics);
526 if (!result.isOk()) {
527 ALOGE("Failed to generate authentication key: %d", result.getErrorCode());
528 return false;
529 }
530 if (hardware_enforced_characteristics.size() == 0) {
531 ALOGW("WARNING: Authentication key is not hardware-backed.");
532 }
533 }
534 return true;
535 }
536
verifyEncryptionKeyAttributes(const std::string & key_name,bool * verified)537 bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
538 bool* verified) {
539 AuthorizationSet hardware_enforced_characteristics;
540 AuthorizationSet software_enforced_characteristics;
541 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
542 &software_enforced_characteristics);
543 if (!result.isOk()) {
544 ALOGE("Failed to query encryption key: %d", result.getErrorCode());
545 return false;
546 }
547 *verified = true;
548 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
549 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
550 if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
551 ALOGW("Found encryption key with invalid algorithm.");
552 *verified = false;
553 }
554 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
555 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
556 if (!key_size.isOk() || key_size.value() != kAESKeySize) {
557 ALOGW("Found encryption key with invalid size.");
558 *verified = false;
559 }
560 auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
561 software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
562 if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
563 ALOGW("Found encryption key with invalid block mode.");
564 *verified = false;
565 }
566 auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
567 software_enforced_characteristics.GetTagValue(TAG_PADDING));
568 if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
569 ALOGW("Found encryption key with invalid padding mode.");
570 *verified = false;
571 }
572 if (hardware_enforced_characteristics.size() == 0) {
573 ALOGW("WARNING: Encryption key is not hardware-backed.");
574 }
575 return true;
576 }
577
verifyAuthenticationKeyAttributes(const std::string & key_name,bool * verified)578 bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
579 bool* verified) {
580 AuthorizationSet hardware_enforced_characteristics;
581 AuthorizationSet software_enforced_characteristics;
582 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
583 &software_enforced_characteristics);
584 if (!result.isOk()) {
585 ALOGE("Failed to query authentication key: %d", result.getErrorCode());
586 return false;
587 }
588 *verified = true;
589 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
590 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
591 if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
592 ALOGW("Found authentication key with invalid algorithm.");
593 *verified = false;
594 }
595 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
596 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
597 if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
598 ALOGW("Found authentication key with invalid size.");
599 *verified = false;
600 }
601 auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
602 software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
603 if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
604 ALOGW("Found authentication key with invalid minimum mac size.");
605 *verified = false;
606 }
607 auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
608 software_enforced_characteristics.GetTagValue(TAG_DIGEST));
609 if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
610 ALOGW("Found authentication key with invalid digest list.");
611 *verified = false;
612 }
613 if (hardware_enforced_characteristics.size() == 0) {
614 ALOGW("WARNING: Authentication key is not hardware-backed.");
615 }
616 return true;
617 }
618
619 } // namespace keystore
620