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