1 /* $OpenBSD: ec_ameth.c,v 1.33 2022/06/27 12:36:05 tb 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/cms.h> 65 #include <openssl/ec.h> 66 #include <openssl/err.h> 67 #include <openssl/x509.h> 68 69 #include "asn1_locl.h" 70 #include "ec_lcl.h" 71 #include "evp_locl.h" 72 73 #ifndef OPENSSL_NO_CMS 74 static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); 75 static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); 76 #endif 77 78 static int 79 eckey_param2type(int *pptype, void **ppval, EC_KEY * ec_key) 80 { 81 const EC_GROUP *group; 82 int nid; 83 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { 84 ECerror(EC_R_MISSING_PARAMETERS); 85 return 0; 86 } 87 if (EC_GROUP_get_asn1_flag(group) && 88 (nid = EC_GROUP_get_curve_name(group))) { 89 /* we have a 'named curve' => just set the OID */ 90 *ppval = OBJ_nid2obj(nid); 91 *pptype = V_ASN1_OBJECT; 92 } else { 93 /* explicit parameters */ 94 ASN1_STRING *pstr = NULL; 95 pstr = ASN1_STRING_new(); 96 if (!pstr) 97 return 0; 98 pstr->length = i2d_ECParameters(ec_key, &pstr->data); 99 if (pstr->length <= 0) { 100 ASN1_STRING_free(pstr); 101 ECerror(ERR_R_EC_LIB); 102 return 0; 103 } 104 *ppval = pstr; 105 *pptype = V_ASN1_SEQUENCE; 106 } 107 return 1; 108 } 109 110 static int 111 eckey_pub_encode(X509_PUBKEY * pk, const EVP_PKEY * pkey) 112 { 113 EC_KEY *ec_key = pkey->pkey.ec; 114 void *pval = NULL; 115 int ptype; 116 unsigned char *penc = NULL, *p; 117 int penclen; 118 119 if (!eckey_param2type(&ptype, &pval, ec_key)) { 120 ECerror(ERR_R_EC_LIB); 121 return 0; 122 } 123 penclen = i2o_ECPublicKey(ec_key, NULL); 124 if (penclen <= 0) 125 goto err; 126 penc = malloc(penclen); 127 if (!penc) 128 goto err; 129 p = penc; 130 penclen = i2o_ECPublicKey(ec_key, &p); 131 if (penclen <= 0) 132 goto err; 133 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), 134 ptype, pval, penc, penclen)) 135 return 1; 136 err: 137 if (ptype == V_ASN1_OBJECT) 138 ASN1_OBJECT_free(pval); 139 else 140 ASN1_STRING_free(pval); 141 free(penc); 142 return 0; 143 } 144 145 static EC_KEY * 146 eckey_type2param(int ptype, const void *pval) 147 { 148 EC_GROUP *group = NULL; 149 EC_KEY *eckey = NULL; 150 151 if (ptype == V_ASN1_SEQUENCE) { 152 const ASN1_STRING *pstr = pval; 153 const unsigned char *pm = NULL; 154 int pmlen; 155 156 pm = pstr->data; 157 pmlen = pstr->length; 158 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) { 159 ECerror(EC_R_DECODE_ERROR); 160 goto ecerr; 161 } 162 } else if (ptype == V_ASN1_OBJECT) { 163 const ASN1_OBJECT *poid = pval; 164 165 /* 166 * type == V_ASN1_OBJECT => the parameters are given by an 167 * asn1 OID 168 */ 169 if ((eckey = EC_KEY_new()) == NULL) { 170 ECerror(ERR_R_MALLOC_FAILURE); 171 goto ecerr; 172 } 173 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); 174 if (group == NULL) 175 goto ecerr; 176 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); 177 if (EC_KEY_set_group(eckey, group) == 0) 178 goto ecerr; 179 } else { 180 ECerror(EC_R_DECODE_ERROR); 181 goto ecerr; 182 } 183 184 EC_GROUP_free(group); 185 return eckey; 186 187 ecerr: 188 EC_KEY_free(eckey); 189 EC_GROUP_free(group); 190 return NULL; 191 } 192 193 static int 194 eckey_pub_decode(EVP_PKEY * pkey, X509_PUBKEY * pubkey) 195 { 196 const unsigned char *p = NULL; 197 const void *pval; 198 int ptype, pklen; 199 EC_KEY *eckey = NULL; 200 X509_ALGOR *palg; 201 202 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 203 return 0; 204 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 205 206 eckey = eckey_type2param(ptype, pval); 207 208 if (!eckey) { 209 ECerror(ERR_R_EC_LIB); 210 return 0; 211 } 212 /* We have parameters now set public key */ 213 if (!o2i_ECPublicKey(&eckey, &p, pklen)) { 214 ECerror(EC_R_DECODE_ERROR); 215 goto ecerr; 216 } 217 EVP_PKEY_assign_EC_KEY(pkey, eckey); 218 return 1; 219 220 ecerr: 221 if (eckey) 222 EC_KEY_free(eckey); 223 return 0; 224 } 225 226 static int 227 eckey_pub_cmp(const EVP_PKEY * a, const EVP_PKEY * b) 228 { 229 int r; 230 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); 231 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec); 232 233 r = EC_POINT_cmp(group, pa, pb, NULL); 234 if (r == 0) 235 return 1; 236 if (r == 1) 237 return 0; 238 return -2; 239 } 240 241 static int 242 eckey_priv_decode(EVP_PKEY * pkey, const PKCS8_PRIV_KEY_INFO * p8) 243 { 244 const unsigned char *p = NULL; 245 const void *pval; 246 int ptype, pklen; 247 EC_KEY *eckey = NULL; 248 const X509_ALGOR *palg; 249 250 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) 251 return 0; 252 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 253 254 eckey = eckey_type2param(ptype, pval); 255 256 if (!eckey) 257 goto ecliberr; 258 259 /* We have parameters now set private key */ 260 if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { 261 ECerror(EC_R_DECODE_ERROR); 262 goto ecerr; 263 } 264 /* calculate public key (if necessary) */ 265 if (EC_KEY_get0_public_key(eckey) == NULL) { 266 const BIGNUM *priv_key; 267 const EC_GROUP *group; 268 EC_POINT *pub_key; 269 /* 270 * the public key was not included in the SEC1 private key => 271 * calculate the public key 272 */ 273 group = EC_KEY_get0_group(eckey); 274 pub_key = EC_POINT_new(group); 275 if (pub_key == NULL) { 276 ECerror(ERR_R_EC_LIB); 277 goto ecliberr; 278 } 279 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { 280 EC_POINT_free(pub_key); 281 ECerror(ERR_R_EC_LIB); 282 goto ecliberr; 283 } 284 priv_key = EC_KEY_get0_private_key(eckey); 285 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { 286 EC_POINT_free(pub_key); 287 ECerror(ERR_R_EC_LIB); 288 goto ecliberr; 289 } 290 if (EC_KEY_set_public_key(eckey, pub_key) == 0) { 291 EC_POINT_free(pub_key); 292 ECerror(ERR_R_EC_LIB); 293 goto ecliberr; 294 } 295 EC_POINT_free(pub_key); 296 } 297 EVP_PKEY_assign_EC_KEY(pkey, eckey); 298 return 1; 299 300 ecliberr: 301 ECerror(ERR_R_EC_LIB); 302 ecerr: 303 if (eckey) 304 EC_KEY_free(eckey); 305 return 0; 306 } 307 308 static int 309 eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey) 310 { 311 EC_KEY *ec_key; 312 unsigned char *ep, *p; 313 int eplen, ptype; 314 void *pval; 315 unsigned int tmp_flags, old_flags; 316 317 ec_key = pkey->pkey.ec; 318 319 if (!eckey_param2type(&ptype, &pval, ec_key)) { 320 ECerror(EC_R_DECODE_ERROR); 321 return 0; 322 } 323 /* set the private key */ 324 325 /* 326 * do not include the parameters in the SEC1 private key see PKCS#11 327 * 12.11 328 */ 329 old_flags = EC_KEY_get_enc_flags(ec_key); 330 tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; 331 EC_KEY_set_enc_flags(ec_key, tmp_flags); 332 eplen = i2d_ECPrivateKey(ec_key, NULL); 333 if (!eplen) { 334 EC_KEY_set_enc_flags(ec_key, old_flags); 335 ECerror(ERR_R_EC_LIB); 336 return 0; 337 } 338 ep = malloc(eplen); 339 if (!ep) { 340 EC_KEY_set_enc_flags(ec_key, old_flags); 341 ECerror(ERR_R_MALLOC_FAILURE); 342 return 0; 343 } 344 p = ep; 345 if (!i2d_ECPrivateKey(ec_key, &p)) { 346 EC_KEY_set_enc_flags(ec_key, old_flags); 347 free(ep); 348 ECerror(ERR_R_EC_LIB); 349 return 0; 350 } 351 /* restore old encoding flags */ 352 EC_KEY_set_enc_flags(ec_key, old_flags); 353 354 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, 355 ptype, pval, ep, eplen)) 356 return 0; 357 358 return 1; 359 } 360 361 static int 362 int_ec_size(const EVP_PKEY * pkey) 363 { 364 return ECDSA_size(pkey->pkey.ec); 365 } 366 367 static int 368 ec_bits(const EVP_PKEY * pkey) 369 { 370 BIGNUM *order = BN_new(); 371 const EC_GROUP *group; 372 int ret; 373 374 if (!order) { 375 ERR_clear_error(); 376 return 0; 377 } 378 group = EC_KEY_get0_group(pkey->pkey.ec); 379 if (!EC_GROUP_get_order(group, order, NULL)) { 380 BN_free(order); 381 ERR_clear_error(); 382 return 0; 383 } 384 ret = BN_num_bits(order); 385 BN_free(order); 386 return ret; 387 } 388 389 static int 390 ec_security_bits(const EVP_PKEY *pkey) 391 { 392 int ecbits = ec_bits(pkey); 393 394 if (ecbits >= 512) 395 return 256; 396 if (ecbits >= 384) 397 return 192; 398 if (ecbits >= 256) 399 return 128; 400 if (ecbits >= 224) 401 return 112; 402 if (ecbits >= 160) 403 return 80; 404 405 return ecbits / 2; 406 } 407 408 static int 409 ec_missing_parameters(const EVP_PKEY * pkey) 410 { 411 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) 412 return 1; 413 return 0; 414 } 415 416 static int 417 ec_copy_parameters(EVP_PKEY * to, const EVP_PKEY * from) 418 { 419 return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec)); 420 } 421 422 static int 423 ec_cmp_parameters(const EVP_PKEY * a, const EVP_PKEY * b) 424 { 425 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec); 426 if (EC_GROUP_cmp(group_a, group_b, NULL)) 427 return 0; 428 else 429 return 1; 430 } 431 432 static void 433 int_ec_free(EVP_PKEY * pkey) 434 { 435 EC_KEY_free(pkey->pkey.ec); 436 } 437 438 static int 439 do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype) 440 { 441 unsigned char *buffer = NULL; 442 const char *ecstr; 443 size_t buf_len = 0, i; 444 int ret = 0, reason = ERR_R_BIO_LIB; 445 BIGNUM *pub_key = NULL, *order = NULL; 446 BN_CTX *ctx = NULL; 447 const EC_GROUP *group; 448 const EC_POINT *public_key; 449 const BIGNUM *priv_key; 450 451 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { 452 reason = ERR_R_PASSED_NULL_PARAMETER; 453 goto err; 454 } 455 ctx = BN_CTX_new(); 456 if (ctx == NULL) { 457 reason = ERR_R_MALLOC_FAILURE; 458 goto err; 459 } 460 if (ktype > 0) { 461 public_key = EC_KEY_get0_public_key(x); 462 if (public_key != NULL) { 463 if ((pub_key = EC_POINT_point2bn(group, public_key, 464 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { 465 reason = ERR_R_EC_LIB; 466 goto err; 467 } 468 if (pub_key) 469 buf_len = (size_t) BN_num_bytes(pub_key); 470 } 471 } 472 if (ktype == 2) { 473 priv_key = EC_KEY_get0_private_key(x); 474 if (priv_key && (i = (size_t) BN_num_bytes(priv_key)) > buf_len) 475 buf_len = i; 476 } else 477 priv_key = NULL; 478 479 if (ktype > 0) { 480 buf_len += 10; 481 if ((buffer = malloc(buf_len)) == NULL) { 482 reason = ERR_R_MALLOC_FAILURE; 483 goto err; 484 } 485 } 486 if (ktype == 2) 487 ecstr = "Private-Key"; 488 else if (ktype == 1) 489 ecstr = "Public-Key"; 490 else 491 ecstr = "ECDSA-Parameters"; 492 493 if (!BIO_indent(bp, off, 128)) 494 goto err; 495 if ((order = BN_new()) == NULL) 496 goto err; 497 if (!EC_GROUP_get_order(group, order, NULL)) 498 goto err; 499 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, 500 BN_num_bits(order)) <= 0) 501 goto err; 502 503 if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 504 buffer, off)) 505 goto err; 506 if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, 507 buffer, off)) 508 goto err; 509 if (!ECPKParameters_print(bp, group, off)) 510 goto err; 511 ret = 1; 512 err: 513 if (!ret) 514 ECerror(reason); 515 BN_free(pub_key); 516 BN_free(order); 517 BN_CTX_free(ctx); 518 free(buffer); 519 return (ret); 520 } 521 522 static int 523 eckey_param_decode(EVP_PKEY * pkey, 524 const unsigned char **pder, int derlen) 525 { 526 EC_KEY *eckey; 527 if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { 528 ECerror(ERR_R_EC_LIB); 529 return 0; 530 } 531 EVP_PKEY_assign_EC_KEY(pkey, eckey); 532 return 1; 533 } 534 535 static int 536 eckey_param_encode(const EVP_PKEY * pkey, unsigned char **pder) 537 { 538 return i2d_ECParameters(pkey->pkey.ec, pder); 539 } 540 541 static int 542 eckey_param_print(BIO * bp, const EVP_PKEY * pkey, int indent, 543 ASN1_PCTX * ctx) 544 { 545 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); 546 } 547 548 static int 549 eckey_pub_print(BIO * bp, const EVP_PKEY * pkey, int indent, 550 ASN1_PCTX * ctx) 551 { 552 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); 553 } 554 555 556 static int 557 eckey_priv_print(BIO * bp, const EVP_PKEY * pkey, int indent, 558 ASN1_PCTX * ctx) 559 { 560 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); 561 } 562 563 static int 564 old_ec_priv_decode(EVP_PKEY * pkey, 565 const unsigned char **pder, int derlen) 566 { 567 EC_KEY *ec; 568 if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { 569 ECerror(EC_R_DECODE_ERROR); 570 return 0; 571 } 572 EVP_PKEY_assign_EC_KEY(pkey, ec); 573 return 1; 574 } 575 576 static int 577 old_ec_priv_encode(const EVP_PKEY * pkey, unsigned char **pder) 578 { 579 return i2d_ECPrivateKey(pkey->pkey.ec, pder); 580 } 581 582 static int 583 ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2) 584 { 585 switch (op) { 586 case ASN1_PKEY_CTRL_PKCS7_SIGN: 587 if (arg1 == 0) { 588 int snid, hnid; 589 X509_ALGOR *alg1, *alg2; 590 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 591 if (alg1 == NULL || alg1->algorithm == NULL) 592 return -1; 593 hnid = OBJ_obj2nid(alg1->algorithm); 594 if (hnid == NID_undef) 595 return -1; 596 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 597 return -1; 598 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 599 } 600 return 1; 601 602 #ifndef OPENSSL_NO_CMS 603 case ASN1_PKEY_CTRL_CMS_SIGN: 604 if (arg1 == 0) { 605 X509_ALGOR *alg1, *alg2; 606 int snid, hnid; 607 608 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); 609 if (alg1 == NULL || alg1->algorithm == NULL) 610 return -1; 611 hnid = OBJ_obj2nid(alg1->algorithm); 612 if (hnid == NID_undef) 613 return -1; 614 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) 615 return -1; 616 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); 617 } 618 return 1; 619 620 case ASN1_PKEY_CTRL_CMS_ENVELOPE: 621 if (arg1 == 0) 622 return ecdh_cms_encrypt(arg2); 623 else if (arg1 == 1) 624 return ecdh_cms_decrypt(arg2); 625 return -2; 626 627 case ASN1_PKEY_CTRL_CMS_RI_TYPE: 628 *(int *)arg2 = CMS_RECIPINFO_AGREE; 629 return 1; 630 #endif 631 632 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 633 *(int *) arg2 = NID_sha1; 634 return 2; 635 636 default: 637 return -2; 638 639 } 640 641 } 642 643 static int 644 ec_pkey_check(const EVP_PKEY *pkey) 645 { 646 EC_KEY *eckey = pkey->pkey.ec; 647 648 if (eckey->priv_key == NULL) { 649 ECerror(EC_R_MISSING_PRIVATE_KEY); 650 return 0; 651 } 652 653 return EC_KEY_check_key(eckey); 654 } 655 656 static int 657 ec_pkey_public_check(const EVP_PKEY *pkey) 658 { 659 EC_KEY *eckey = pkey->pkey.ec; 660 661 /* This also checks the private key, but oh, well... */ 662 return EC_KEY_check_key(eckey); 663 } 664 665 static int 666 ec_pkey_param_check(const EVP_PKEY *pkey) 667 { 668 EC_KEY *eckey = pkey->pkey.ec; 669 670 if (eckey->group == NULL) { 671 ECerror(EC_R_MISSING_PARAMETERS); 672 return 0; 673 } 674 675 return EC_GROUP_check(eckey->group, NULL); 676 } 677 678 #ifndef OPENSSL_NO_CMS 679 680 static int 681 ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg, 682 ASN1_BIT_STRING *pubkey) 683 { 684 const ASN1_OBJECT *aoid; 685 int atype; 686 const void *aval; 687 int rv = 0; 688 EVP_PKEY *pkpeer = NULL; 689 EC_KEY *ecpeer = NULL; 690 const unsigned char *p; 691 int plen; 692 693 X509_ALGOR_get0(&aoid, &atype, &aval, alg); 694 if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) 695 goto err; 696 697 /* If absent parameters get group from main key */ 698 if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { 699 const EC_GROUP *grp; 700 EVP_PKEY *pk; 701 702 pk = EVP_PKEY_CTX_get0_pkey(pctx); 703 if (!pk) 704 goto err; 705 grp = EC_KEY_get0_group(pk->pkey.ec); 706 ecpeer = EC_KEY_new(); 707 if (ecpeer == NULL) 708 goto err; 709 if (!EC_KEY_set_group(ecpeer, grp)) 710 goto err; 711 } else { 712 ecpeer = eckey_type2param(atype, aval); 713 if (!ecpeer) 714 goto err; 715 } 716 717 /* We have parameters now set public key */ 718 plen = ASN1_STRING_length(pubkey); 719 p = ASN1_STRING_get0_data(pubkey); 720 if (!p || !plen) 721 goto err; 722 if (!o2i_ECPublicKey(&ecpeer, &p, plen)) 723 goto err; 724 pkpeer = EVP_PKEY_new(); 725 if (pkpeer == NULL) 726 goto err; 727 EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer); 728 if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) 729 rv = 1; 730 err: 731 EC_KEY_free(ecpeer); 732 EVP_PKEY_free(pkpeer); 733 return rv; 734 } 735 736 /* Set KDF parameters based on KDF NID */ 737 static int 738 ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) 739 { 740 int kdf_nid, kdfmd_nid, cofactor; 741 const EVP_MD *kdf_md; 742 743 if (eckdf_nid == NID_undef) 744 return 0; 745 746 /* Lookup KDF type, cofactor mode and digest */ 747 if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid)) 748 return 0; 749 750 if (kdf_nid == NID_dh_std_kdf) 751 cofactor = 0; 752 else if (kdf_nid == NID_dh_cofactor_kdf) 753 cofactor = 1; 754 else 755 return 0; 756 757 if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) 758 return 0; 759 760 if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0) 761 return 0; 762 763 kdf_md = EVP_get_digestbynid(kdfmd_nid); 764 if (!kdf_md) 765 return 0; 766 767 if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) 768 return 0; 769 770 return 1; 771 } 772 773 static int 774 ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) 775 { 776 X509_ALGOR *alg, *kekalg = NULL; 777 ASN1_OCTET_STRING *ukm; 778 const unsigned char *p; 779 unsigned char *der = NULL; 780 int plen, keylen; 781 const EVP_CIPHER *kekcipher; 782 EVP_CIPHER_CTX *kekctx; 783 int rv = 0; 784 785 if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) 786 return 0; 787 788 if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { 789 ECerror(EC_R_KDF_PARAMETER_ERROR); 790 return 0; 791 } 792 793 if (alg->parameter->type != V_ASN1_SEQUENCE) 794 return 0; 795 796 p = alg->parameter->value.sequence->data; 797 plen = alg->parameter->value.sequence->length; 798 kekalg = d2i_X509_ALGOR(NULL, &p, plen); 799 if (!kekalg) 800 goto err; 801 kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); 802 if (!kekctx) 803 goto err; 804 kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); 805 if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) 806 goto err; 807 if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) 808 goto err; 809 if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) 810 goto err; 811 812 keylen = EVP_CIPHER_CTX_key_length(kekctx); 813 if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) 814 goto err; 815 816 plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); 817 if (!plen) 818 goto err; 819 820 if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) 821 goto err; 822 der = NULL; 823 824 rv = 1; 825 err: 826 X509_ALGOR_free(kekalg); 827 free(der); 828 return rv; 829 } 830 831 static int 832 ecdh_cms_decrypt(CMS_RecipientInfo *ri) 833 { 834 EVP_PKEY_CTX *pctx; 835 836 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 837 if (!pctx) 838 return 0; 839 840 /* See if we need to set peer key */ 841 if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { 842 X509_ALGOR *alg; 843 ASN1_BIT_STRING *pubkey; 844 845 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, 846 NULL, NULL, NULL)) 847 return 0; 848 if (!alg || !pubkey) 849 return 0; 850 if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { 851 ECerror(EC_R_PEER_KEY_ERROR); 852 return 0; 853 } 854 } 855 856 /* Set ECDH derivation parameters and initialise unwrap context */ 857 if (!ecdh_cms_set_shared_info(pctx, ri)) { 858 ECerror(EC_R_SHARED_INFO_ERROR); 859 return 0; 860 } 861 862 return 1; 863 } 864 865 static int 866 ecdh_cms_encrypt(CMS_RecipientInfo *ri) 867 { 868 EVP_PKEY_CTX *pctx; 869 EVP_PKEY *pkey; 870 EVP_CIPHER_CTX *ctx; 871 int keylen; 872 X509_ALGOR *talg, *wrap_alg = NULL; 873 const ASN1_OBJECT *aoid; 874 ASN1_BIT_STRING *pubkey; 875 ASN1_STRING *wrap_str; 876 ASN1_OCTET_STRING *ukm; 877 unsigned char *penc = NULL; 878 int penclen; 879 int ecdh_nid, kdf_type, kdf_nid, wrap_nid; 880 const EVP_MD *kdf_md; 881 int rv = 0; 882 883 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 884 if (!pctx) 885 return 0; 886 /* Get ephemeral key */ 887 pkey = EVP_PKEY_CTX_get0_pkey(pctx); 888 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, 889 NULL, NULL, NULL)) 890 goto err; 891 X509_ALGOR_get0(&aoid, NULL, NULL, talg); 892 893 /* Is everything uninitialised? */ 894 if (aoid == OBJ_nid2obj(NID_undef)) { 895 EC_KEY *eckey = pkey->pkey.ec; 896 unsigned char *p; 897 898 /* Set the key */ 899 penclen = i2o_ECPublicKey(eckey, NULL); 900 if (penclen <= 0) 901 goto err; 902 penc = malloc(penclen); 903 if (penc == NULL) 904 goto err; 905 p = penc; 906 penclen = i2o_ECPublicKey(eckey, &p); 907 if (penclen <= 0) 908 goto err; 909 ASN1_STRING_set0(pubkey, penc, penclen); 910 if (!asn1_abs_set_unused_bits(pubkey, 0)) 911 goto err; 912 penc = NULL; 913 914 X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 915 V_ASN1_UNDEF, NULL); 916 } 917 918 /* See if custom parameters set */ 919 kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); 920 if (kdf_type <= 0) 921 goto err; 922 if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md)) 923 goto err; 924 ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); 925 if (ecdh_nid < 0) 926 goto err; 927 else if (ecdh_nid == 0) 928 ecdh_nid = NID_dh_std_kdf; 929 else if (ecdh_nid == 1) 930 ecdh_nid = NID_dh_cofactor_kdf; 931 932 if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { 933 kdf_type = EVP_PKEY_ECDH_KDF_X9_63; 934 if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) 935 goto err; 936 } else { 937 /* Unknown KDF */ 938 goto err; 939 } 940 if (kdf_md == NULL) { 941 /* Fixme later for better MD */ 942 kdf_md = EVP_sha1(); 943 if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) 944 goto err; 945 } 946 947 if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) 948 goto err; 949 950 /* Lookup NID for KDF+cofactor+digest */ 951 if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid)) 952 goto err; 953 954 /* Get wrap NID */ 955 ctx = CMS_RecipientInfo_kari_get0_ctx(ri); 956 wrap_nid = EVP_CIPHER_CTX_type(ctx); 957 keylen = EVP_CIPHER_CTX_key_length(ctx); 958 959 /* Package wrap algorithm in an AlgorithmIdentifier */ 960 961 wrap_alg = X509_ALGOR_new(); 962 if (wrap_alg == NULL) 963 goto err; 964 wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); 965 wrap_alg->parameter = ASN1_TYPE_new(); 966 if (wrap_alg->parameter == NULL) 967 goto err; 968 if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) 969 goto err; 970 if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { 971 ASN1_TYPE_free(wrap_alg->parameter); 972 wrap_alg->parameter = NULL; 973 } 974 975 if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) 976 goto err; 977 978 penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); 979 if (!penclen) 980 goto err; 981 982 if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) 983 goto err; 984 penc = NULL; 985 986 /* 987 * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter 988 * of another AlgorithmIdentifier. 989 */ 990 penclen = i2d_X509_ALGOR(wrap_alg, &penc); 991 if (!penc || !penclen) 992 goto err; 993 wrap_str = ASN1_STRING_new(); 994 if (wrap_str == NULL) 995 goto err; 996 ASN1_STRING_set0(wrap_str, penc, penclen); 997 penc = NULL; 998 X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); 999 1000 rv = 1; 1001 1002 err: 1003 free(penc); 1004 X509_ALGOR_free(wrap_alg); 1005 return rv; 1006 } 1007 1008 #endif 1009 1010 const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { 1011 .pkey_id = EVP_PKEY_EC, 1012 .pkey_base_id = EVP_PKEY_EC, 1013 1014 .pem_str = "EC", 1015 .info = "OpenSSL EC algorithm", 1016 1017 .pub_decode = eckey_pub_decode, 1018 .pub_encode = eckey_pub_encode, 1019 .pub_cmp = eckey_pub_cmp, 1020 .pub_print = eckey_pub_print, 1021 1022 .priv_decode = eckey_priv_decode, 1023 .priv_encode = eckey_priv_encode, 1024 .priv_print = eckey_priv_print, 1025 1026 .pkey_size = int_ec_size, 1027 .pkey_bits = ec_bits, 1028 .pkey_security_bits = ec_security_bits, 1029 1030 .param_decode = eckey_param_decode, 1031 .param_encode = eckey_param_encode, 1032 .param_missing = ec_missing_parameters, 1033 .param_copy = ec_copy_parameters, 1034 .param_cmp = ec_cmp_parameters, 1035 .param_print = eckey_param_print, 1036 1037 .pkey_free = int_ec_free, 1038 .pkey_ctrl = ec_pkey_ctrl, 1039 .old_priv_decode = old_ec_priv_decode, 1040 .old_priv_encode = old_ec_priv_encode, 1041 1042 .pkey_check = ec_pkey_check, 1043 .pkey_public_check = ec_pkey_public_check, 1044 .pkey_param_check = ec_pkey_param_check, 1045 }; 1046