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