Home | History | Annotate | Download | only in keymaster
      1 /*
      2  * Copyright 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "ec_keymaster1_key.h"
     18 
     19 #include <memory>
     20 
     21 #include <keymaster/logger.h>
     22 
     23 #include "ecdsa_keymaster1_operation.h"
     24 #include "ecdsa_operation.h"
     25 
     26 using std::unique_ptr;
     27 
     28 namespace keymaster {
     29 
     30 EcdsaKeymaster1KeyFactory::EcdsaKeymaster1KeyFactory(const SoftKeymasterContext* context,
     31                                                      const Keymaster1Engine* engine)
     32     : EcKeyFactory(context), engine_(engine),
     33       sign_factory_(new EcdsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)),
     34       // For pubkey ops we can use the normal operation factories.
     35       verify_factory_(new EcdsaVerifyOperationFactory) {}
     36 
     37 static bool is_supported(uint32_t digest) {
     38     return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256;
     39 }
     40 
     41 static void UpdateToWorkAroundUnsupportedDigests(const AuthorizationSet& key_description,
     42                                                  AuthorizationSet* new_description) {
     43     bool have_unsupported_digests = false;
     44     bool have_digest_none = false;
     45     for (const keymaster_key_param_t& entry : key_description) {
     46         new_description->push_back(entry);
     47 
     48         if (entry.tag == TAG_DIGEST) {
     49             if (entry.enumerated == KM_DIGEST_NONE) {
     50                 have_digest_none = true;
     51             } else if (!is_supported(entry.enumerated)) {
     52                 LOG_D("Found request for unsupported digest %u", entry.enumerated);
     53                 have_unsupported_digests = true;
     54             }
     55         }
     56     }
     57 
     58     if (have_unsupported_digests && !have_digest_none) {
     59         LOG_I("Adding KM_DIGEST_NONE to key authorization, to enable software digesting", 0);
     60         new_description->push_back(TAG_DIGEST, KM_DIGEST_NONE);
     61     }
     62 }
     63 
     64 keymaster_error_t EcdsaKeymaster1KeyFactory::GenerateKey(const AuthorizationSet& key_description,
     65                                                          KeymasterKeyBlob* key_blob,
     66                                                          AuthorizationSet* hw_enforced,
     67                                                          AuthorizationSet* sw_enforced) const {
     68     AuthorizationSet key_params_copy;
     69     UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
     70 
     71     keymaster_ec_curve_t ec_curve;
     72     uint32_t key_size;
     73     keymaster_error_t error = GetCurveAndSize(key_description, &ec_curve, &key_size);
     74     if (error != KM_ERROR_OK) {
     75         return error;
     76     } else if (!key_description.Contains(TAG_KEY_SIZE, key_size)) {
     77         key_params_copy.push_back(TAG_KEY_SIZE, key_size);
     78     }
     79     return engine_->GenerateKey(key_params_copy, key_blob, hw_enforced, sw_enforced);
     80 }
     81 
     82 keymaster_error_t EcdsaKeymaster1KeyFactory::ImportKey(
     83     const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
     84     const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
     85     AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
     86     AuthorizationSet key_params_copy;
     87     UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
     88     return engine_->ImportKey(key_params_copy, input_key_material_format, input_key_material,
     89                               output_key_blob, hw_enforced, sw_enforced);
     90 }
     91 
     92 keymaster_error_t EcdsaKeymaster1KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
     93                                                      const AuthorizationSet& additional_params,
     94                                                      const AuthorizationSet& hw_enforced,
     95                                                      const AuthorizationSet& sw_enforced,
     96                                                      UniquePtr<Key>* key) const {
     97     if (!key)
     98         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     99 
    100     keymaster_error_t error;
    101     unique_ptr<EC_KEY, EC_KEY_Delete> ecdsa(
    102         engine_->BuildEcKey(key_material, additional_params, &error));
    103     if (!ecdsa)
    104         return error;
    105 
    106     key->reset(new (std::nothrow)
    107                    EcdsaKeymaster1Key(ecdsa.release(), hw_enforced, sw_enforced, &error));
    108     if (!key->get())
    109         error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    110 
    111     if (error != KM_ERROR_OK)
    112         return error;
    113 
    114     return KM_ERROR_OK;
    115 }
    116 
    117 OperationFactory*
    118 EcdsaKeymaster1KeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
    119     switch (purpose) {
    120     case KM_PURPOSE_SIGN:
    121         return sign_factory_.get();
    122     case KM_PURPOSE_VERIFY:
    123         return verify_factory_.get();
    124     default:
    125         return nullptr;
    126     }
    127 }
    128 
    129 }  // namespace keymaster
    130