Home | History | Annotate | Download | only in keystore
      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 
     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 
     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 
    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 
    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
    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
    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
    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
    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 
    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 
    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 
    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
    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
    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
    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 
    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 
    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 
    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 
    386 uint64_t KeystoreClientImpl::getNextVirtualHandle() {
    387     return next_virtual_handle_++;
    388 }
    389 
    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 
    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 
    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 
    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