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