• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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