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 <keymaster/ec_key_factory.h>
     18 
     19 #include <openssl/evp.h>
     20 
     21 #include <keymaster/keymaster_context.h>
     22 
     23 #include "ec_key.h"
     24 #include "ecdsa_operation.h"
     25 #include "openssl_err.h"
     26 
     27 namespace keymaster {
     28 
     29 static EcdsaSignOperationFactory sign_factory;
     30 static EcdsaVerifyOperationFactory verify_factory;
     31 
     32 OperationFactory* EcKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
     33     switch (purpose) {
     34     case KM_PURPOSE_SIGN:
     35         return &sign_factory;
     36     case KM_PURPOSE_VERIFY:
     37         return &verify_factory;
     38     default:
     39         return nullptr;
     40     }
     41 }
     42 
     43 /* static */
     44 keymaster_error_t EcKeyFactory::GetCurveAndSize(const AuthorizationSet& key_description,
     45                                                 keymaster_ec_curve_t* curve,
     46                                                 uint32_t* key_size_bits) {
     47     if (!key_description.GetTagValue(TAG_EC_CURVE, curve)) {
     48         // Curve not specified. Fall back to deducing curve from key size.
     49         if (!key_description.GetTagValue(TAG_KEY_SIZE, key_size_bits)) {
     50             LOG_E("%s", "No curve or key size specified for EC key generation");
     51             return KM_ERROR_UNSUPPORTED_KEY_SIZE;
     52         }
     53         keymaster_error_t error = EcKeySizeToCurve(*key_size_bits, curve);
     54         if (error != KM_ERROR_OK) {
     55             return KM_ERROR_UNSUPPORTED_KEY_SIZE;
     56         }
     57     } else {
     58         keymaster_error_t error = EcCurveToKeySize(*curve, key_size_bits);
     59         if (error != KM_ERROR_OK) {
     60             return error;
     61         }
     62         uint32_t tag_key_size_bits;
     63         if (key_description.GetTagValue(TAG_KEY_SIZE, &tag_key_size_bits) &&
     64             *key_size_bits != tag_key_size_bits) {
     65             LOG_E("Curve key size %d and specified key size %d don't match", key_size_bits,
     66                   tag_key_size_bits);
     67             return KM_ERROR_INVALID_ARGUMENT;
     68         }
     69     }
     70 
     71     return KM_ERROR_OK;
     72 }
     73 
     74 keymaster_error_t EcKeyFactory::GenerateKey(const AuthorizationSet& key_description,
     75                                             KeymasterKeyBlob* key_blob,
     76                                             AuthorizationSet* hw_enforced,
     77                                             AuthorizationSet* sw_enforced) const {
     78     if (!key_blob || !hw_enforced || !sw_enforced)
     79         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     80 
     81     AuthorizationSet authorizations(key_description);
     82 
     83     keymaster_ec_curve_t ec_curve;
     84     uint32_t key_size;
     85     keymaster_error_t error = GetCurveAndSize(authorizations, &ec_curve, &key_size);
     86     if (error != KM_ERROR_OK) {
     87         return error;
     88     } else if (!authorizations.Contains(TAG_KEY_SIZE, key_size)) {
     89         authorizations.push_back(TAG_KEY_SIZE, key_size);
     90     } else if (!authorizations.Contains(TAG_EC_CURVE, ec_curve)) {
     91         authorizations.push_back(TAG_EC_CURVE, ec_curve);
     92     }
     93 
     94     UniquePtr<EC_KEY, EC_KEY_Delete> ec_key(EC_KEY_new());
     95     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
     96     if (ec_key.get() == NULL || pkey.get() == NULL)
     97         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
     98 
     99     UniquePtr<EC_GROUP, EC_GROUP_Delete> group(ChooseGroup(ec_curve));
    100     if (group.get() == NULL) {
    101         LOG_E("Unable to get EC group for curve %d", ec_curve);
    102         return KM_ERROR_UNSUPPORTED_KEY_SIZE;
    103     }
    104 
    105 #if !defined(OPENSSL_IS_BORINGSSL)
    106     EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED);
    107     EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
    108 #endif
    109 
    110     if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
    111         EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
    112         return TranslateLastOpenSslError();
    113     }
    114 
    115     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1)
    116         return TranslateLastOpenSslError();
    117 
    118     KeymasterKeyBlob key_material;
    119     error = EvpKeyToKeyMaterial(pkey.get(), &key_material);
    120     if (error != KM_ERROR_OK)
    121         return error;
    122 
    123     return context_->CreateKeyBlob(authorizations, KM_ORIGIN_GENERATED, key_material, key_blob,
    124                                    hw_enforced, sw_enforced);
    125 }
    126 
    127 keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_description,
    128                                           keymaster_key_format_t input_key_material_format,
    129                                           const KeymasterKeyBlob& input_key_material,
    130                                           KeymasterKeyBlob* output_key_blob,
    131                                           AuthorizationSet* hw_enforced,
    132                                           AuthorizationSet* sw_enforced) const {
    133     if (!output_key_blob || !hw_enforced || !sw_enforced)
    134         return KM_ERROR_OUTPUT_PARAMETER_NULL;
    135 
    136     AuthorizationSet authorizations;
    137     uint32_t key_size;
    138     keymaster_error_t error = UpdateImportKeyDescription(
    139         key_description, input_key_material_format, input_key_material, &authorizations, &key_size);
    140     if (error != KM_ERROR_OK)
    141         return error;
    142 
    143     return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material,
    144                                    output_key_blob, hw_enforced, sw_enforced);
    145 }
    146 
    147 keymaster_error_t EcKeyFactory::UpdateImportKeyDescription(const AuthorizationSet& key_description,
    148                                                            keymaster_key_format_t key_format,
    149                                                            const KeymasterKeyBlob& key_material,
    150                                                            AuthorizationSet* updated_description,
    151                                                            uint32_t* key_size_bits) const {
    152     if (!updated_description || !key_size_bits)
    153         return KM_ERROR_OUTPUT_PARAMETER_NULL;
    154 
    155     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey;
    156     keymaster_error_t error =
    157         KeyMaterialToEvpKey(key_format, key_material, keymaster_key_type(), &pkey);
    158     if (error != KM_ERROR_OK)
    159         return error;
    160 
    161     UniquePtr<EC_KEY, EC_KEY_Delete> ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
    162     if (!ec_key.get())
    163         return TranslateLastOpenSslError();
    164 
    165     updated_description->Reinitialize(key_description);
    166 
    167     size_t extracted_key_size_bits;
    168     error = ec_get_group_size(EC_KEY_get0_group(ec_key.get()), &extracted_key_size_bits);
    169     if (error != KM_ERROR_OK)
    170         return error;
    171 
    172     *key_size_bits = extracted_key_size_bits;
    173     if (!updated_description->GetTagValue(TAG_KEY_SIZE, key_size_bits)) {
    174         updated_description->push_back(TAG_KEY_SIZE, extracted_key_size_bits);
    175     } else if (*key_size_bits != extracted_key_size_bits) {
    176         return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    177     }
    178 
    179     keymaster_ec_curve_t curve_from_size;
    180     error = EcKeySizeToCurve(*key_size_bits, &curve_from_size);
    181     if (error != KM_ERROR_OK)
    182         return error;
    183     keymaster_ec_curve_t curve;
    184     if (!updated_description->GetTagValue(TAG_EC_CURVE, &curve)) {
    185         updated_description->push_back(TAG_EC_CURVE, curve_from_size);
    186     } else if (curve_from_size != curve) {
    187         return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    188     }
    189 
    190     keymaster_algorithm_t algorithm = KM_ALGORITHM_EC;
    191     if (!updated_description->GetTagValue(TAG_ALGORITHM, &algorithm)) {
    192         updated_description->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC);
    193     } else if (algorithm != KM_ALGORITHM_EC) {
    194         return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    195     }
    196 
    197     return KM_ERROR_OK;
    198 }
    199 
    200 /* static */
    201 EC_GROUP* EcKeyFactory::ChooseGroup(size_t key_size_bits) {
    202     switch (key_size_bits) {
    203     case 224:
    204         return EC_GROUP_new_by_curve_name(NID_secp224r1);
    205         break;
    206     case 256:
    207         return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
    208         break;
    209     case 384:
    210         return EC_GROUP_new_by_curve_name(NID_secp384r1);
    211         break;
    212     case 521:
    213         return EC_GROUP_new_by_curve_name(NID_secp521r1);
    214         break;
    215     default:
    216         return NULL;
    217         break;
    218     }
    219 }
    220 
    221 /* static */
    222 EC_GROUP* EcKeyFactory::ChooseGroup(keymaster_ec_curve_t ec_curve) {
    223     switch (ec_curve) {
    224     case KM_EC_CURVE_P_224:
    225         return EC_GROUP_new_by_curve_name(NID_secp224r1);
    226         break;
    227     case KM_EC_CURVE_P_256:
    228         return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
    229         break;
    230     case KM_EC_CURVE_P_384:
    231         return EC_GROUP_new_by_curve_name(NID_secp384r1);
    232         break;
    233     case KM_EC_CURVE_P_521:
    234         return EC_GROUP_new_by_curve_name(NID_secp521r1);
    235         break;
    236     default:
    237         return nullptr;
    238         break;
    239     }
    240 }
    241 
    242 keymaster_error_t EcKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced,
    243                                                const AuthorizationSet& sw_enforced,
    244                                                UniquePtr<AsymmetricKey>* key) const {
    245     keymaster_error_t error;
    246     key->reset(new (std::nothrow) EcKey(hw_enforced, sw_enforced, &error));
    247     if (!key->get())
    248         error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    249     return error;
    250 }
    251 
    252 }  // namespace keymaster
    253