Home | History | Annotate | Download | only in keymaster
      1 /*
      2  * Copyright 2014 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 <openssl/evp.h>
     18 #include <openssl/x509.h>
     19 
     20 #include <keymaster/key_blob.h>
     21 #include <keymaster/keymaster_defs.h>
     22 
     23 #include "asymmetric_key.h"
     24 #include "dsa_operation.h"
     25 #include "ecdsa_operation.h"
     26 #include "openssl_utils.h"
     27 #include "rsa_operation.h"
     28 
     29 namespace keymaster {
     30 
     31 const uint32_t RSA_DEFAULT_KEY_SIZE = 2048;
     32 const uint64_t RSA_DEFAULT_EXPONENT = 65537;
     33 
     34 const uint32_t DSA_DEFAULT_KEY_SIZE = 2048;
     35 
     36 const uint32_t ECDSA_DEFAULT_KEY_SIZE = 192;
     37 
     38 keymaster_error_t AsymmetricKey::LoadKey(const KeyBlob& blob) {
     39     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> evp_key(EVP_PKEY_new());
     40     if (evp_key.get() == NULL)
     41         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
     42 
     43     EVP_PKEY* tmp_pkey = evp_key.get();
     44     const uint8_t* key_material = blob.key_material();
     45     if (d2i_PrivateKey(evp_key_type(), &tmp_pkey, &key_material, blob.key_material_length()) ==
     46         NULL) {
     47         return KM_ERROR_INVALID_KEY_BLOB;
     48     }
     49     if (!EvpToInternal(evp_key.get()))
     50         return KM_ERROR_UNKNOWN_ERROR;
     51 
     52     return KM_ERROR_OK;
     53 }
     54 
     55 keymaster_error_t AsymmetricKey::key_material(UniquePtr<uint8_t[]>* material, size_t* size) const {
     56     if (material == NULL || size == NULL)
     57         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     58 
     59     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
     60     if (pkey.get() == NULL)
     61         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
     62 
     63     if (!InternalToEvp(pkey.get()))
     64         return KM_ERROR_UNKNOWN_ERROR;
     65 
     66     *size = i2d_PrivateKey(pkey.get(), NULL /* key_data*/);
     67     if (*size <= 0)
     68         return KM_ERROR_UNKNOWN_ERROR;
     69 
     70     material->reset(new uint8_t[*size]);
     71     uint8_t* tmp = material->get();
     72     i2d_PrivateKey(pkey.get(), &tmp);
     73 
     74     return KM_ERROR_OK;
     75 }
     76 
     77 keymaster_error_t AsymmetricKey::formatted_key_material(keymaster_key_format_t format,
     78                                                         UniquePtr<uint8_t[]>* material,
     79                                                         size_t* size) const {
     80     if (format != KM_KEY_FORMAT_X509)
     81         return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
     82 
     83     if (material == NULL || size == NULL)
     84         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     85 
     86     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
     87     if (!InternalToEvp(pkey.get()))
     88         return KM_ERROR_UNKNOWN_ERROR;
     89 
     90     int key_data_length = i2d_PUBKEY(pkey.get(), NULL);
     91     if (key_data_length <= 0)
     92         return KM_ERROR_UNKNOWN_ERROR;
     93 
     94     material->reset(new uint8_t[key_data_length]);
     95     if (material->get() == NULL)
     96         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
     97 
     98     uint8_t* tmp = material->get();
     99     if (i2d_PUBKEY(pkey.get(), &tmp) != key_data_length) {
    100         material->reset();
    101         return KM_ERROR_UNKNOWN_ERROR;
    102     }
    103 
    104     *size = key_data_length;
    105     return KM_ERROR_OK;
    106 }
    107 
    108 Operation* AsymmetricKey::CreateOperation(keymaster_purpose_t purpose, keymaster_error_t* error) {
    109     keymaster_digest_t digest;
    110     if (!authorizations().GetTagValue(TAG_DIGEST, &digest) || digest != KM_DIGEST_NONE) {
    111         *error = KM_ERROR_UNSUPPORTED_DIGEST;
    112         return NULL;
    113     }
    114 
    115     keymaster_padding_t padding;
    116     if (!authorizations().GetTagValue(TAG_PADDING, &padding) || padding != KM_PAD_NONE) {
    117         *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
    118         return NULL;
    119     }
    120 
    121     return CreateOperation(purpose, digest, padding, error);
    122 }
    123 
    124 /* static */
    125 RsaKey* RsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
    126                             keymaster_error_t* error) {
    127     if (!error)
    128         return NULL;
    129 
    130     AuthorizationSet authorizations(key_description);
    131 
    132     uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
    133     if (!authorizations.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
    134         authorizations.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent));
    135 
    136     uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
    137     if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size))
    138         authorizations.push_back(Authorization(TAG_KEY_SIZE, key_size));
    139 
    140     UniquePtr<BIGNUM, BIGNUM_Delete> exponent(BN_new());
    141     UniquePtr<RSA, RSA_Delete> rsa_key(RSA_new());
    142     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
    143     if (rsa_key.get() == NULL || pkey.get() == NULL) {
    144         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    145         return NULL;
    146     }
    147 
    148     if (!BN_set_word(exponent.get(), public_exponent) ||
    149         !RSA_generate_key_ex(rsa_key.get(), key_size, exponent.get(), NULL /* callback */)) {
    150         *error = KM_ERROR_UNKNOWN_ERROR;
    151         return NULL;
    152     }
    153 
    154     RsaKey* new_key = new RsaKey(rsa_key.release(), authorizations, logger);
    155     *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
    156     return new_key;
    157 }
    158 
    159 /* static */
    160 RsaKey* RsaKey::ImportKey(const AuthorizationSet& key_description, EVP_PKEY* pkey,
    161                           const Logger& logger, keymaster_error_t* error) {
    162     if (!error)
    163         return NULL;
    164     *error = KM_ERROR_UNKNOWN_ERROR;
    165 
    166     UniquePtr<RSA, RSA_Delete> rsa_key(EVP_PKEY_get1_RSA(pkey));
    167     if (!rsa_key.get())
    168         return NULL;
    169 
    170     AuthorizationSet authorizations(key_description);
    171 
    172     uint64_t public_exponent;
    173     if (authorizations.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) {
    174         // public_exponent specified, make sure it matches the key
    175         UniquePtr<BIGNUM, BIGNUM_Delete> public_exponent_bn(BN_new());
    176         if (!BN_set_word(public_exponent_bn.get(), public_exponent))
    177             return NULL;
    178         if (BN_cmp(public_exponent_bn.get(), rsa_key->e) != 0) {
    179             *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    180             return NULL;
    181         }
    182     } else {
    183         // public_exponent not specified, use the one from the key.
    184         public_exponent = BN_get_word(rsa_key->e);
    185         if (public_exponent == 0xffffffffL) {
    186             *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    187             return NULL;
    188         }
    189         authorizations.push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
    190     }
    191 
    192     uint32_t key_size;
    193     if (authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) {
    194         // key_size specified, make sure it matches the key.
    195         if (RSA_size(rsa_key.get()) != (int)key_size) {
    196             *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    197             return NULL;
    198         }
    199     } else {
    200         key_size = RSA_size(rsa_key.get()) * 8;
    201         authorizations.push_back(TAG_KEY_SIZE, key_size);
    202     }
    203 
    204     keymaster_algorithm_t algorithm;
    205     if (authorizations.GetTagValue(TAG_ALGORITHM, &algorithm)) {
    206         if (algorithm != KM_ALGORITHM_RSA) {
    207             *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    208             return NULL;
    209         }
    210     } else {
    211         authorizations.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
    212     }
    213 
    214     // Don't bother with the other parameters.  If the necessary padding, digest, purpose, etc. are
    215     // missing, the error will be diagnosed when the key is used (when auth checking is
    216     // implemented).
    217     *error = KM_ERROR_OK;
    218     return new RsaKey(rsa_key.release(), authorizations, logger);
    219 }
    220 
    221 RsaKey::RsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error)
    222     : AsymmetricKey(blob, logger) {
    223     if (error)
    224         *error = LoadKey(blob);
    225 }
    226 
    227 Operation* RsaKey::CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
    228                                    keymaster_padding_t padding, keymaster_error_t* error) {
    229     Operation* op;
    230     switch (purpose) {
    231     case KM_PURPOSE_SIGN:
    232         op = new RsaSignOperation(purpose, logger_, digest, padding, rsa_key_.release());
    233         break;
    234     case KM_PURPOSE_VERIFY:
    235         op = new RsaVerifyOperation(purpose, logger_, digest, padding, rsa_key_.release());
    236         break;
    237     default:
    238         *error = KM_ERROR_UNIMPLEMENTED;
    239         return NULL;
    240     }
    241     *error = op ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
    242     return op;
    243 }
    244 
    245 bool RsaKey::EvpToInternal(const EVP_PKEY* pkey) {
    246     rsa_key_.reset(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pkey)));
    247     return rsa_key_.get() != NULL;
    248 }
    249 
    250 bool RsaKey::InternalToEvp(EVP_PKEY* pkey) const {
    251     return EVP_PKEY_set1_RSA(pkey, rsa_key_.get()) == 1;
    252 }
    253 
    254 template <keymaster_tag_t Tag>
    255 static void GetDsaParamData(const AuthorizationSet& auths, TypedTag<KM_BIGNUM, Tag> tag,
    256                             keymaster_blob_t* blob) {
    257     if (!auths.GetTagValue(tag, blob))
    258         blob->data = NULL;
    259 }
    260 
    261 // Store the specified DSA param in auths
    262 template <keymaster_tag_t Tag>
    263 static void SetDsaParamData(AuthorizationSet* auths, TypedTag<KM_BIGNUM, Tag> tag, BIGNUM* number) {
    264     keymaster_blob_t blob;
    265     convert_bn_to_blob(number, &blob);
    266     auths->push_back(Authorization(tag, blob));
    267     delete[] blob.data;
    268 }
    269 
    270 DsaKey* DsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
    271                             keymaster_error_t* error) {
    272     if (!error)
    273         return NULL;
    274 
    275     AuthorizationSet authorizations(key_description);
    276 
    277     keymaster_blob_t g_blob;
    278     GetDsaParamData(authorizations, TAG_DSA_GENERATOR, &g_blob);
    279 
    280     keymaster_blob_t p_blob;
    281     GetDsaParamData(authorizations, TAG_DSA_P, &p_blob);
    282 
    283     keymaster_blob_t q_blob;
    284     GetDsaParamData(authorizations, TAG_DSA_Q, &q_blob);
    285 
    286     uint32_t key_size = DSA_DEFAULT_KEY_SIZE;
    287     if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size))
    288         authorizations.push_back(Authorization(TAG_KEY_SIZE, key_size));
    289 
    290     UniquePtr<DSA, DSA_Delete> dsa_key(DSA_new());
    291     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
    292     if (dsa_key.get() == NULL || pkey.get() == NULL) {
    293         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    294         return NULL;
    295     }
    296 
    297     // If anything goes wrong in the next section, it's a param problem.
    298     *error = KM_ERROR_INVALID_DSA_PARAMS;
    299 
    300     if (g_blob.data == NULL && p_blob.data == NULL && q_blob.data == NULL) {
    301         logger.info("DSA parameters unspecified, generating them for key size %d", key_size);
    302         if (!DSA_generate_parameters_ex(dsa_key.get(), key_size, NULL /* seed */, 0 /* seed_len */,
    303                                         NULL /* counter_ret */, NULL /* h_ret */,
    304                                         NULL /* callback */)) {
    305             logger.severe("DSA parameter generation failed.");
    306             return NULL;
    307         }
    308 
    309         SetDsaParamData(&authorizations, TAG_DSA_GENERATOR, dsa_key->g);
    310         SetDsaParamData(&authorizations, TAG_DSA_P, dsa_key->p);
    311         SetDsaParamData(&authorizations, TAG_DSA_Q, dsa_key->q);
    312     } else if (g_blob.data == NULL || p_blob.data == NULL || q_blob.data == NULL) {
    313         logger.severe("Some DSA parameters provided.  Provide all or none");
    314         return NULL;
    315     } else {
    316         // All params provided. Use them.
    317         dsa_key->g = BN_bin2bn(g_blob.data, g_blob.data_length, NULL);
    318         dsa_key->p = BN_bin2bn(p_blob.data, p_blob.data_length, NULL);
    319         dsa_key->q = BN_bin2bn(q_blob.data, q_blob.data_length, NULL);
    320 
    321         if (dsa_key->g == NULL || dsa_key->p == NULL || dsa_key->q == NULL) {
    322             return NULL;
    323         }
    324     }
    325 
    326     if (!DSA_generate_key(dsa_key.get())) {
    327         *error = KM_ERROR_UNKNOWN_ERROR;
    328         return NULL;
    329     }
    330 
    331     DsaKey* new_key = new DsaKey(dsa_key.release(), authorizations, logger);
    332     *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
    333     return new_key;
    334 }
    335 
    336 template <keymaster_tag_t T>
    337 keymaster_error_t GetOrCheckDsaParam(TypedTag<KM_BIGNUM, T> tag, BIGNUM* bn,
    338                                      AuthorizationSet* auths) {
    339     keymaster_blob_t blob;
    340     if (auths->GetTagValue(tag, &blob)) {
    341         // value specified, make sure it matches
    342         UniquePtr<BIGNUM, BIGNUM_Delete> extracted_bn(BN_bin2bn(blob.data, blob.data_length, NULL));
    343         if (extracted_bn.get() == NULL)
    344             return KM_ERROR_MEMORY_ALLOCATION_FAILED;
    345         if (BN_cmp(extracted_bn.get(), bn) != 0)
    346             return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    347     } else {
    348         // value not specified, add it
    349         UniquePtr<uint8_t[]> data(new uint8_t[BN_num_bytes(bn)]);
    350         BN_bn2bin(bn, data.get());
    351         auths->push_back(tag, data.get(), BN_num_bytes(bn));
    352     }
    353     return KM_ERROR_OK;
    354 }
    355 
    356 /* static */
    357 size_t DsaKey::key_size_bits(DSA* dsa_key) {
    358     // Openssl provides no convenient way to get a DSA key size, but dsa_key->p is L bits long.
    359     // There may be some leading zeros that mess up this calculation, but DSA key sizes are also
    360     // constrained to be multiples of 64 bits.  So the key size is the bit length of p rounded up to
    361     // the nearest 64.
    362     return ((BN_num_bytes(dsa_key->p) * 8) + 63) / 64 * 64;
    363 }
    364 
    365 /* static */
    366 DsaKey* DsaKey::ImportKey(const AuthorizationSet& key_description, EVP_PKEY* pkey,
    367                           const Logger& logger, keymaster_error_t* error) {
    368     if (!error)
    369         return NULL;
    370     *error = KM_ERROR_UNKNOWN_ERROR;
    371 
    372     UniquePtr<DSA, DSA_Delete> dsa_key(EVP_PKEY_get1_DSA(pkey));
    373     if (!dsa_key.get())
    374         return NULL;
    375 
    376     AuthorizationSet authorizations(key_description);
    377 
    378     *error = GetOrCheckDsaParam(TAG_DSA_GENERATOR, dsa_key->g, &authorizations);
    379     if (*error != KM_ERROR_OK)
    380         return NULL;
    381 
    382     *error = GetOrCheckDsaParam(TAG_DSA_P, dsa_key->p, &authorizations);
    383     if (*error != KM_ERROR_OK)
    384         return NULL;
    385 
    386     *error = GetOrCheckDsaParam(TAG_DSA_Q, dsa_key->q, &authorizations);
    387     if (*error != KM_ERROR_OK)
    388         return NULL;
    389 
    390     // There's no convenient way to get a DSA key size, but dsa_key->p is L bits long.  There may be
    391     // some leading zeros that mess up this calculation, but DSA key sizes are also constrained to
    392     // be multiples of 64 bits.  So the bit length of p, rounded up to the nearest 64 bits, is the
    393     // key size.
    394     uint32_t extracted_key_size_bits = ((BN_num_bytes(dsa_key->p) * 8) + 63) / 64 * 64;
    395 
    396     uint32_t key_size_bits;
    397     if (authorizations.GetTagValue(TAG_KEY_SIZE, &key_size_bits)) {
    398         // key_size_bits specified, make sure it matches the key.
    399         if (key_size_bits != extracted_key_size_bits) {
    400             *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    401             return NULL;
    402         }
    403     } else {
    404         // key_size_bits not specified, add it.
    405         authorizations.push_back(TAG_KEY_SIZE, extracted_key_size_bits);
    406     }
    407 
    408     keymaster_algorithm_t algorithm;
    409     if (authorizations.GetTagValue(TAG_ALGORITHM, &algorithm)) {
    410         if (algorithm != KM_ALGORITHM_DSA) {
    411             *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    412             return NULL;
    413         }
    414     } else {
    415         authorizations.push_back(TAG_ALGORITHM, KM_ALGORITHM_DSA);
    416     }
    417 
    418     // Don't bother with the other parameters.  If the necessary padding, digest, purpose, etc. are
    419     // missing, the error will be diagnosed when the key is used (when auth checking is
    420     // implemented).
    421     *error = KM_ERROR_OK;
    422     return new DsaKey(dsa_key.release(), authorizations, logger);
    423 }
    424 
    425 DsaKey::DsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error)
    426     : AsymmetricKey(blob, logger) {
    427     if (error)
    428         *error = LoadKey(blob);
    429 }
    430 
    431 Operation* DsaKey::CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
    432                                    keymaster_padding_t padding, keymaster_error_t* error) {
    433     Operation* op;
    434     switch (purpose) {
    435     case KM_PURPOSE_SIGN:
    436         op = new DsaSignOperation(purpose, logger_, digest, padding, dsa_key_.release());
    437         break;
    438     case KM_PURPOSE_VERIFY:
    439         op = new DsaVerifyOperation(purpose, logger_, digest, padding, dsa_key_.release());
    440         break;
    441     default:
    442         *error = KM_ERROR_UNIMPLEMENTED;
    443         return NULL;
    444     }
    445     *error = op ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
    446     return op;
    447 }
    448 
    449 bool DsaKey::EvpToInternal(const EVP_PKEY* pkey) {
    450     dsa_key_.reset(EVP_PKEY_get1_DSA(const_cast<EVP_PKEY*>(pkey)));
    451     return dsa_key_.get() != NULL;
    452 }
    453 
    454 bool DsaKey::InternalToEvp(EVP_PKEY* pkey) const {
    455     return EVP_PKEY_set1_DSA(pkey, dsa_key_.get()) == 1;
    456 }
    457 
    458 /* static */
    459 EcdsaKey* EcdsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
    460                                 keymaster_error_t* error) {
    461     if (!error)
    462         return NULL;
    463 
    464     AuthorizationSet authorizations(key_description);
    465 
    466     uint32_t key_size = ECDSA_DEFAULT_KEY_SIZE;
    467     if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size))
    468         authorizations.push_back(Authorization(TAG_KEY_SIZE, key_size));
    469 
    470     UniquePtr<EC_KEY, ECDSA_Delete> ecdsa_key(EC_KEY_new());
    471     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
    472     if (ecdsa_key.get() == NULL || pkey.get() == NULL) {
    473         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    474         return NULL;
    475     }
    476 
    477     UniquePtr<EC_GROUP, EC_GROUP_Delete> group(choose_group(key_size));
    478     if (group.get() == NULL) {
    479         // Technically, could also have been a memory allocation problem.
    480         *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
    481         return NULL;
    482     }
    483 
    484     EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED);
    485     EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
    486 
    487     if (EC_KEY_set_group(ecdsa_key.get(), group.get()) != 1 ||
    488         EC_KEY_generate_key(ecdsa_key.get()) != 1 || EC_KEY_check_key(ecdsa_key.get()) < 0) {
    489         *error = KM_ERROR_UNKNOWN_ERROR;
    490         return NULL;
    491     }
    492 
    493     EcdsaKey* new_key = new EcdsaKey(ecdsa_key.release(), authorizations, logger);
    494     *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
    495     return new_key;
    496 }
    497 
    498 /* static */
    499 EcdsaKey* EcdsaKey::ImportKey(const AuthorizationSet& key_description, EVP_PKEY* pkey,
    500                               const Logger& logger, keymaster_error_t* error) {
    501     if (!error)
    502         return NULL;
    503     *error = KM_ERROR_UNKNOWN_ERROR;
    504 
    505     UniquePtr<EC_KEY, ECDSA_Delete> ecdsa_key(EVP_PKEY_get1_EC_KEY(pkey));
    506     if (!ecdsa_key.get())
    507         return NULL;
    508 
    509     AuthorizationSet authorizations(key_description);
    510 
    511     size_t extracted_key_size_bits;
    512     *error = get_group_size(*EC_KEY_get0_group(ecdsa_key.get()), &extracted_key_size_bits);
    513     if (*error != KM_ERROR_OK)
    514         return NULL;
    515 
    516     uint32_t key_size_bits;
    517     if (authorizations.GetTagValue(TAG_KEY_SIZE, &key_size_bits)) {
    518         // key_size_bits specified, make sure it matches the key.
    519         if (key_size_bits != extracted_key_size_bits) {
    520             *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    521             return NULL;
    522         }
    523     } else {
    524         // key_size_bits not specified, add it.
    525         authorizations.push_back(TAG_KEY_SIZE, extracted_key_size_bits);
    526     }
    527 
    528     keymaster_algorithm_t algorithm;
    529     if (authorizations.GetTagValue(TAG_ALGORITHM, &algorithm)) {
    530         if (algorithm != KM_ALGORITHM_ECDSA) {
    531             *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH;
    532             return NULL;
    533         }
    534     } else {
    535         authorizations.push_back(TAG_ALGORITHM, KM_ALGORITHM_ECDSA);
    536     }
    537 
    538     // Don't bother with the other parameters.  If the necessary padding, digest, purpose, etc. are
    539     // missing, the error will be diagnosed when the key is used (when auth checking is
    540     // implemented).
    541     *error = KM_ERROR_OK;
    542     return new EcdsaKey(ecdsa_key.release(), authorizations, logger);
    543 }
    544 
    545 /* static */
    546 EC_GROUP* EcdsaKey::choose_group(size_t key_size_bits) {
    547     switch (key_size_bits) {
    548     case 192:
    549         return EC_GROUP_new_by_curve_name(NID_X9_62_prime192v1);
    550         break;
    551     case 224:
    552         return EC_GROUP_new_by_curve_name(NID_secp224r1);
    553         break;
    554     case 256:
    555         return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
    556         break;
    557     case 384:
    558         return EC_GROUP_new_by_curve_name(NID_secp384r1);
    559         break;
    560     case 521:
    561         return EC_GROUP_new_by_curve_name(NID_secp521r1);
    562         break;
    563     default:
    564         return NULL;
    565         break;
    566     }
    567 }
    568 
    569 /* static */
    570 keymaster_error_t EcdsaKey::get_group_size(const EC_GROUP& group, size_t* key_size_bits) {
    571     switch (EC_GROUP_get_curve_name(&group)) {
    572     case NID_X9_62_prime192v1:
    573         *key_size_bits = 192;
    574         break;
    575     case NID_secp224r1:
    576         *key_size_bits = 224;
    577         break;
    578     case NID_X9_62_prime256v1:
    579         *key_size_bits = 256;
    580         break;
    581     case NID_secp384r1:
    582         *key_size_bits = 384;
    583         break;
    584     case NID_secp521r1:
    585         *key_size_bits = 521;
    586         break;
    587     default:
    588         return KM_ERROR_UNSUPPORTED_EC_FIELD;
    589     }
    590     return KM_ERROR_OK;
    591 }
    592 
    593 EcdsaKey::EcdsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error)
    594     : AsymmetricKey(blob, logger) {
    595     if (error)
    596         *error = LoadKey(blob);
    597 }
    598 
    599 Operation* EcdsaKey::CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
    600                                      keymaster_padding_t padding, keymaster_error_t* error) {
    601     Operation* op;
    602     switch (purpose) {
    603     case KM_PURPOSE_SIGN:
    604         op = new EcdsaSignOperation(purpose, logger_, digest, padding, ecdsa_key_.release());
    605         break;
    606     case KM_PURPOSE_VERIFY:
    607         op = new EcdsaVerifyOperation(purpose, logger_, digest, padding, ecdsa_key_.release());
    608         break;
    609     default:
    610         *error = KM_ERROR_UNIMPLEMENTED;
    611         return NULL;
    612     }
    613     *error = op ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
    614     return op;
    615 }
    616 
    617 bool EcdsaKey::EvpToInternal(const EVP_PKEY* pkey) {
    618     ecdsa_key_.reset(EVP_PKEY_get1_EC_KEY(const_cast<EVP_PKEY*>(pkey)));
    619     return ecdsa_key_.get() != NULL;
    620 }
    621 
    622 bool EcdsaKey::InternalToEvp(EVP_PKEY* pkey) const {
    623     return EVP_PKEY_set1_EC_KEY(pkey, ecdsa_key_.get()) == 1;
    624 }
    625 
    626 }  // namespace keymaster
    627