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