1 /* $OpenBSD: ec_ameth.c,v 1.13 2014/07/13 15:47:51 logan Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 2006. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <stdio.h> 60 61 #include <openssl/opensslconf.h> 62 63 #include <openssl/bn.h> 64 #include <openssl/ec.h> 65 #include <openssl/err.h> 66 #include <openssl/x509.h> 67 68 #ifndef OPENSSL_NO_CMS 69 #include <openssl/cms.h> 70 #endif 71 72 #include "asn1_locl.h" 73 74 static int 75 eckey_param2type(int *pptype, void **ppval, EC_KEY * ec_key) 76 { 77 const EC_GROUP *group; 78 int nid; 79 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { 80 ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); 81 return 0; 82 } 83 if (EC_GROUP_get_asn1_flag(group) && 84 (nid = EC_GROUP_get_curve_name(group))) { 85 /* we have a 'named curve' => just set the OID */ 86 *ppval = OBJ_nid2obj(nid); 87 *pptype = V_ASN1_OBJECT; 88 } else { 89 /* explicit parameters */ 90 ASN1_STRING *pstr = NULL; 91 pstr = ASN1_STRING_new(); 92 if (!pstr) 93 return 0; 94 pstr->length = i2d_ECParameters(ec_key, &pstr->data); 95 if (pstr->length <= 0) { 96 ASN1_STRING_free(pstr); 97 ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); 98 return 0; 99 } 100 *ppval = pstr; 101 *pptype = V_ASN1_SEQUENCE; 102 } 103 return 1; 104 } 105 106 static int 107 eckey_pub_encode(X509_PUBKEY * pk, const EVP_PKEY * pkey) 108 { 109 EC_KEY *ec_key = pkey->pkey.ec; 110 void *pval = NULL; 111 int ptype; 112 unsigned char *penc = NULL, *p; 113 int penclen; 114 115 if (!eckey_param2type(&ptype, &pval, ec_key)) { 116 ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); 117 return 0; 118 } 119 penclen = i2o_ECPublicKey(ec_key, NULL); 120 if (penclen <= 0) 121 goto err; 122 penc = malloc(penclen); 123 if (!penc) 124 goto err; 125 p = penc; 126 penclen = i2o_ECPublicKey(ec_key, &p); 127 if (penclen <= 0) 128 goto err; 129 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), 130 ptype, pval, penc, penclen)) 131 return 1; 132 err: 133 if (ptype == V_ASN1_OBJECT) 134 ASN1_OBJECT_free(pval); 135 else 136 ASN1_STRING_free(pval); 137 free(penc); 138 return 0; 139 } 140 141 static EC_KEY * 142 eckey_type2param(int ptype, void *pval) 143 { 144 EC_KEY *eckey = NULL; 145 146 if (ptype == V_ASN1_SEQUENCE) { 147 ASN1_STRING *pstr = pval; 148 const unsigned char *pm = NULL; 149 int pmlen; 150 151 pm = pstr->data; 152 pmlen = pstr->length; 153 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) { 154 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); 155 goto ecerr; 156 } 157 } else if (ptype == V_ASN1_OBJECT) { 158 ASN1_OBJECT *poid = pval; 159 EC_GROUP *group; 160 161 /* 162 * type == V_ASN1_OBJECT => the parameters are given by an 163 * asn1 OID 164 */ 165 if ((eckey = EC_KEY_new()) == NULL) { 166 ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); 167 goto ecerr; 168 } 169 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); 170 if (group == NULL) 171 goto ecerr; 172 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 173 if (EC_KEY_set_group(eckey, group) == 0) 174 goto ecerr; 175 EC_GROUP_free(group); 176 } else { 177 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); 178 goto ecerr; 179 } 180 181 return eckey; 182 183 ecerr: 184 if (eckey) 185 EC_KEY_free(eckey); 186 return NULL; 187 } 188 189 static int 190 eckey_pub_decode(EVP_PKEY * pkey, X509_PUBKEY * pubkey) 191 { 192 const unsigned char *p = NULL; 193 void *pval; 194 int ptype, pklen; 195 EC_KEY *eckey = NULL; 196 X509_ALGOR *palg; 197 198 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 199 return 0; 200 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 201 202 eckey = eckey_type2param(ptype, pval); 203 204 if (!eckey) { 205 ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); 206 return 0; 207 } 208 /* We have parameters now set public key */ 209 if (!o2i_ECPublicKey(&eckey, &p, pklen)) { 210 ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); 211 goto ecerr; 212 } 213 EVP_PKEY_assign_EC_KEY(pkey, eckey); 214 return 1; 215 216 ecerr: 217 if (eckey) 218 EC_KEY_free(eckey); 219 return 0; 220 } 221 222 static int 223 eckey_pub_cmp(const EVP_PKEY * a, const EVP_PKEY * b) 224 { 225 int r; 226 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); 227 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec); 228 229 r = EC_POINT_cmp(group, pa, pb, NULL); 230 if (r == 0) 231 return 1; 232 if (r == 1) 233 return 0; 234 return -2; 235 } 236 237 static int 238 eckey_priv_decode(EVP_PKEY * pkey, PKCS8_PRIV_KEY_INFO * p8) 239 { 240 const unsigned char *p = NULL; 241 void *pval; 242 int ptype, pklen; 243 EC_KEY *eckey = NULL; 244 X509_ALGOR *palg; 245 246 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) 247 return 0; 248 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 249 250 eckey = eckey_type2param(ptype, pval); 251 252 if (!eckey) 253 goto ecliberr; 254 255 /* We have parameters now set private key */ 256 if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { 257 ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); 258 goto ecerr; 259 } 260 /* calculate public key (if necessary) */ 261 if (EC_KEY_get0_public_key(eckey) == NULL) { 262 const BIGNUM *priv_key; 263 const EC_GROUP *group; 264 EC_POINT *pub_key; 265 /* 266 * the public key was not included in the SEC1 private key => 267 * calculate the public key 268 */ 269 group = EC_KEY_get0_group(eckey); 270 pub_key = EC_POINT_new(group); 271 if (pub_key == NULL) { 272 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 273 goto ecliberr; 274 } 275 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { 276 EC_POINT_free(pub_key); 277 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 278 goto ecliberr; 279 } 280 priv_key = EC_KEY_get0_private_key(eckey); 281 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { 282 EC_POINT_free(pub_key); 283 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 284 goto ecliberr; 285 } 286 if (EC_KEY_set_public_key(eckey, pub_key) == 0) { 287 EC_POINT_free(pub_key); 288 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 289 goto ecliberr; 290 } 291 EC_POINT_free(pub_key); 292 } 293 EVP_PKEY_assign_EC_KEY(pkey, eckey); 294 return 1; 295 296 ecliberr: 297 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); 298 ecerr: 299 if (eckey) 300 EC_KEY_free(eckey); 301 return 0; 302 } 303 304 static int 305 eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey) 306 { 307 EC_KEY *ec_key; 308 unsigned char *ep, *p; 309 int eplen, ptype; 310 void *pval; 311 unsigned int tmp_flags, old_flags; 312 313 ec_key = pkey->pkey.ec; 314 315 if (!eckey_param2type(&ptype, &pval, ec_key)) { 316 ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); 317 return 0; 318 } 319 /* set the private key */ 320 321 /* 322 * do not include the parameters in the SEC1 private key see PKCS#11 323 * 12.11 324 */ 325 old_flags = EC_KEY_get_enc_flags(ec_key); 326 tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; 327 EC_KEY_set_enc_flags(ec_key, tmp_flags); 328 eplen = i2d_ECPrivateKey(ec_key, NULL); 329 if (!eplen) { 330 EC_KEY_set_enc_flags(ec_key, old_flags); 331 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); 332 return 0; 333 } 334 ep = malloc(eplen); 335 if (!ep) { 336 EC_KEY_set_enc_flags(ec_key, old_flags); 337 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 338 return 0; 339 } 340 p = ep; 341 if (!i2d_ECPrivateKey(ec_key, &p)) { 342 EC_KEY_set_enc_flags(ec_key, old_flags); 343 free(ep); 344 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); 345 return 0; 346 } 347 /* restore old encoding flags */ 348 EC_KEY_set_enc_flags(ec_key, old_flags); 349 350 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, 351 ptype, pval, ep, eplen)) 352 return 0; 353 354 return 1; 355 } 356 357 static int 358 int_ec_size(const EVP_PKEY * pkey) 359 { 360 return ECDSA_size(pkey->pkey.ec); 361 } 362 363 static int 364 ec_bits(const EVP_PKEY * pkey) 365 { 366 BIGNUM *order = BN_new(); 367 const EC_GROUP *group; 368 int ret; 369 370 if (!order) { 371 ERR_clear_error(); 372 return 0; 373 } 374 group = EC_KEY_get0_group(pkey->pkey.ec); 375 if (!EC_GROUP_get_order(group, order, NULL)) { 376 BN_free(order); 377 ERR_clear_error(); 378 return 0; 379 } 380 ret = BN_num_bits(order); 381 BN_free(order); 382 return ret; 383 } 384 385 static int 386 ec_missing_parameters(const EVP_PKEY * pkey) 387 { 388 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) 389 return 1; 390 return 0; 391 } 392 393 static int 394 ec_copy_parameters(EVP_PKEY * to, const EVP_PKEY * from) 395 { 396 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); 397 if (group == NULL) 398 return 0; 399 if (EC_KEY_set_group(to->pkey.ec, group) == 0) 400 return 0; 401 EC_GROUP_free(group); 402 return 1; 403 } 404 405 static int 406 ec_cmp_parameters(const EVP_PKEY * a, const EVP_PKEY * b) 407 { 408 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec); 409 if (EC_GROUP_cmp(group_a, group_b, NULL)) 410 return 0; 411 else 412 return 1; 413 } 414 415 static void 416 int_ec_free(EVP_PKEY * pkey) 417 { 418 EC_KEY_free(pkey->pkey.ec); 419 } 420 421 static int 422 do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype) 423 { 424 unsigned char *buffer = NULL; 425 const char *ecstr; 426 size_t buf_len = 0, i; 427 int ret = 0, reason = ERR_R_BIO_LIB; 428 BIGNUM *pub_key = NULL, *order = NULL; 429 BN_CTX *ctx = NULL; 430 const EC_GROUP *group; 431 const EC_POINT *public_key; 432 const BIGNUM *priv_key; 433 434 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { 435 reason = ERR_R_PASSED_NULL_PARAMETER; 436 goto err; 437 } 438 ctx = BN_CTX_new(); 439 if (ctx == NULL) { 440 reason = ERR_R_MALLOC_FAILURE; 441 goto err; 442 } 443 if (ktype > 0) { 444 public_key = EC_KEY_get0_public_key(x); 445 if ((pub_key = EC_POINT_point2bn(group, public_key, 446 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { 447 reason = ERR_R_EC_LIB; 448 goto err; 449 } 450 if (pub_key) 451 buf_len = (size_t) BN_num_bytes(pub_key); 452 } 453 if (ktype == 2) { 454 priv_key = EC_KEY_get0_private_key(x); 455 if (priv_key && (i = (size_t) BN_num_bytes(priv_key)) > buf_len) 456 buf_len = i; 457 } else 458 priv_key = NULL; 459 460 if (ktype > 0) { 461 buf_len += 10; 462 if ((buffer = malloc(buf_len)) == NULL) { 463 reason = ERR_R_MALLOC_FAILURE; 464 goto err; 465 } 466 } 467 if (ktype == 2) 468 ecstr = "Private-Key"; 469 else if (ktype == 1) 470 ecstr = "Public-Key"; 471 else 472 ecstr = "ECDSA-Parameters"; 473 474 if (!BIO_indent(bp, off, 128)) 475 goto err; 476 if ((order = BN_new()) == NULL) 477 goto err; 478 if (!EC_GROUP_get_order(group, order, NULL)) 479 goto err; 480 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, 481 BN_num_bits(order)) <= 0) 482 goto err; 483 484 if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 485 buffer, off)) 486 goto err; 487 if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, 488 buffer, off)) 489 goto err; 490 if (!ECPKParameters_print(bp, group, off)) 491 goto err; 492 ret = 1; 493 err: 494 if (!ret) 495 ECerr(EC_F_DO_EC_KEY_PRINT, reason); 496 BN_free(pub_key); 497 BN_free(order); 498 BN_CTX_free(ctx); 499 free(buffer); 500 return (ret); 501 } 502 503 static int 504 eckey_param_decode(EVP_PKEY * pkey, 505 const unsigned char **pder, int derlen) 506 { 507 EC_KEY *eckey; 508 if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { 509 ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); 510 return 0; 511 } 512 EVP_PKEY_assign_EC_KEY(pkey, eckey); 513 return 1; 514 } 515 516 static int 517 eckey_param_encode(const EVP_PKEY * pkey, unsigned char **pder) 518 { 519 return i2d_ECParameters(pkey->pkey.ec, pder); 520 } 521 522 static int 523 eckey_param_print(BIO * bp, const EVP_PKEY * pkey, int indent, 524 ASN1_PCTX * ctx) 525 { 526 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); 527 } 528 529 static int 530 eckey_pub_print(BIO * bp, const EVP_PKEY * pkey, int indent, 531 ASN1_PCTX * ctx) 532 { 533 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); 534 } 535 536 537 static int 538 eckey_priv_print(BIO * bp, const EVP_PKEY * pkey, int indent, 539 ASN1_PCTX * ctx) 540 { 541 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); 542 } 543 544 static int 545 old_ec_priv_decode(EVP_PKEY * pkey, 546 const unsigned char **pder, int derlen) 547 { 548 EC_KEY *ec; 549 if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { 550 ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); 551 return 0; 552 } 553 EVP_PKEY_assign_EC_KEY(pkey, ec); 554 return 1; 555 } 556 557 static int 558 old_ec_priv_encode(const EVP_PKEY * pkey, unsigned char **pder) 559 { 560 return i2d_ECPrivateKey(pkey->pkey.ec, pder); 561 } 562 563 static int 564 ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2) 565 { 566 switch (op) { 567 case ASN1_PKEY_CTRL_PKCS7_SIGN: 568 if (arg1 == 0) { 569 int snid, hnid; 570 X509_ALGOR *alg1, *alg2; 571 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 572 if (alg1 == NULL || alg1->algorithm == NULL) 573 return -1; 574 hnid = OBJ_obj2nid(alg1->algorithm); 575 if (hnid == NID_undef) 576 return -1; 577 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 578 return -1; 579 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 580 } 581 return 1; 582 #ifndef OPENSSL_NO_CMS 583 case ASN1_PKEY_CTRL_CMS_SIGN: 584 if (arg1 == 0) { 585 int snid, hnid; 586 X509_ALGOR *alg1, *alg2; 587 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, 588 &alg1, &alg2); 589 if (alg1 == NULL || alg1->algorithm == NULL) 590 return -1; 591 hnid = OBJ_obj2nid(alg1->algorithm); 592 if (hnid == NID_undef) 593 return -1; 594 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 595 return -1; 596 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 597 } 598 return 1; 599 #endif 600 601 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 602 *(int *) arg2 = NID_sha1; 603 return 2; 604 605 default: 606 return -2; 607 608 } 609 610 } 611 612 const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { 613 .pkey_id = EVP_PKEY_EC, 614 .pkey_base_id = EVP_PKEY_EC, 615 616 .pem_str = "EC", 617 .info = "OpenSSL EC algorithm", 618 619 .pub_decode = eckey_pub_decode, 620 .pub_encode = eckey_pub_encode, 621 .pub_cmp = eckey_pub_cmp, 622 .pub_print = eckey_pub_print, 623 624 .priv_decode = eckey_priv_decode, 625 .priv_encode = eckey_priv_encode, 626 .priv_print = eckey_priv_print, 627 628 .pkey_size = int_ec_size, 629 .pkey_bits = ec_bits, 630 631 .param_decode = eckey_param_decode, 632 .param_encode = eckey_param_encode, 633 .param_missing = ec_missing_parameters, 634 .param_copy = ec_copy_parameters, 635 .param_cmp = ec_cmp_parameters, 636 .param_print = eckey_param_print, 637 638 .pkey_free = int_ec_free, 639 .pkey_ctrl = ec_pkey_ctrl, 640 .old_priv_decode = old_ec_priv_decode, 641 .old_priv_encode = old_ec_priv_encode 642 }; 643