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