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