1 /* $OpenBSD: ec_key.c,v 1.51 2025/01/25 10:34:36 tb Exp $ */ 2 /* 3 * Written by Nils Larsch for the OpenSSL project. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1998-2005 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 * openssl-core@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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60 * Portions originally developed by SUN MICROSYSTEMS, INC., and 61 * contributed to the OpenSSL project. 62 */ 63 64 #include <string.h> 65 66 #include <openssl/opensslconf.h> 67 68 #include <openssl/ec.h> 69 #include <openssl/err.h> 70 71 #include "bn_local.h" 72 #include "ec_local.h" 73 #include "ecdsa_local.h" 74 75 EC_KEY * 76 EC_KEY_new(void) 77 { 78 return EC_KEY_new_method(NULL); 79 } 80 LCRYPTO_ALIAS(EC_KEY_new); 81 82 EC_KEY * 83 EC_KEY_new_by_curve_name(int nid) 84 { 85 EC_KEY *ec_key; 86 87 if ((ec_key = EC_KEY_new()) == NULL) 88 goto err; 89 90 if ((ec_key->group = EC_GROUP_new_by_curve_name(nid)) == NULL) 91 goto err; 92 93 /* XXX - do we want an ec_key_set0_group()? */ 94 if (ec_key->meth->set_group != NULL) { 95 if (!ec_key->meth->set_group(ec_key, ec_key->group)) 96 goto err; 97 } 98 99 return ec_key; 100 101 err: 102 EC_KEY_free(ec_key); 103 104 return NULL; 105 } 106 LCRYPTO_ALIAS(EC_KEY_new_by_curve_name); 107 108 void 109 EC_KEY_free(EC_KEY *ec_key) 110 { 111 if (ec_key == NULL) 112 return; 113 114 if (CRYPTO_add(&ec_key->references, -1, CRYPTO_LOCK_EC) > 0) 115 return; 116 117 if (ec_key->meth != NULL && ec_key->meth->finish != NULL) 118 ec_key->meth->finish(ec_key); 119 120 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, ec_key, &ec_key->ex_data); 121 122 EC_GROUP_free(ec_key->group); 123 EC_POINT_free(ec_key->pub_key); 124 BN_free(ec_key->priv_key); 125 126 freezero(ec_key, sizeof(*ec_key)); 127 } 128 LCRYPTO_ALIAS(EC_KEY_free); 129 130 EC_KEY * 131 EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) 132 { 133 if (dest == NULL || src == NULL) { 134 ECerror(ERR_R_PASSED_NULL_PARAMETER); 135 return NULL; 136 } 137 138 if (src->meth != dest->meth) { 139 if (dest->meth != NULL && dest->meth->finish != NULL) 140 dest->meth->finish(dest); 141 } 142 143 if (src->group != NULL) { 144 EC_GROUP_free(dest->group); 145 if ((dest->group = EC_GROUP_dup(src->group)) == NULL) 146 return NULL; 147 if (src->pub_key != NULL) { 148 EC_POINT_free(dest->pub_key); 149 if ((dest->pub_key = EC_POINT_dup(src->pub_key, 150 src->group)) == NULL) 151 return NULL; 152 } 153 } 154 155 BN_free(dest->priv_key); 156 dest->priv_key = NULL; 157 if (src->priv_key != NULL) { 158 if ((dest->priv_key = BN_dup(src->priv_key)) == NULL) 159 return NULL; 160 } 161 162 dest->enc_flag = src->enc_flag; 163 dest->conv_form = src->conv_form; 164 dest->version = src->version; 165 dest->flags = src->flags; 166 167 /* 168 * The fun part about being a toolkit implementer is that the rest of 169 * the world gets to live with your terrible API design choices for 170 * eternity. (To be fair: the signature was changed in OpenSSL 3). 171 */ 172 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, &dest->ex_data, 173 &((EC_KEY *)src)->ex_data)) /* XXX const */ 174 return NULL; 175 176 dest->meth = src->meth; 177 178 if (src->meth != NULL && src->meth->copy != NULL) { 179 if (!src->meth->copy(dest, src)) 180 return NULL; 181 } 182 183 return dest; 184 } 185 LCRYPTO_ALIAS(EC_KEY_copy); 186 187 EC_KEY * 188 EC_KEY_dup(const EC_KEY *in_ec_key) 189 { 190 EC_KEY *ec_key; 191 192 /* XXX - Pass NULL - so we're perhaps not running the right init()? */ 193 if ((ec_key = EC_KEY_new_method(NULL)) == NULL) 194 goto err; 195 if (EC_KEY_copy(ec_key, in_ec_key) == NULL) 196 goto err; 197 198 return ec_key; 199 200 err: 201 EC_KEY_free(ec_key); 202 203 return NULL; 204 } 205 LCRYPTO_ALIAS(EC_KEY_dup); 206 207 int 208 EC_KEY_up_ref(EC_KEY *r) 209 { 210 return CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC) > 1; 211 } 212 LCRYPTO_ALIAS(EC_KEY_up_ref); 213 214 int 215 EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg) 216 { 217 return CRYPTO_set_ex_data(&r->ex_data, idx, arg); 218 } 219 LCRYPTO_ALIAS(EC_KEY_set_ex_data); 220 221 void * 222 EC_KEY_get_ex_data(const EC_KEY *r, int idx) 223 { 224 return CRYPTO_get_ex_data(&r->ex_data, idx); 225 } 226 LCRYPTO_ALIAS(EC_KEY_get_ex_data); 227 228 int 229 EC_KEY_generate_key(EC_KEY *eckey) 230 { 231 if (eckey->meth->keygen != NULL) 232 return eckey->meth->keygen(eckey); 233 ECerror(EC_R_NOT_IMPLEMENTED); 234 return 0; 235 } 236 LCRYPTO_ALIAS(EC_KEY_generate_key); 237 238 static int 239 ec_key_gen(EC_KEY *eckey) 240 { 241 BIGNUM *priv_key = NULL; 242 EC_POINT *pub_key = NULL; 243 const BIGNUM *order; 244 int ret = 0; 245 246 if (eckey == NULL || eckey->group == NULL) { 247 ECerror(ERR_R_PASSED_NULL_PARAMETER); 248 goto err; 249 } 250 251 if ((priv_key = BN_new()) == NULL) 252 goto err; 253 if ((pub_key = EC_POINT_new(eckey->group)) == NULL) 254 goto err; 255 256 if ((order = EC_GROUP_get0_order(eckey->group)) == NULL) 257 goto err; 258 if (!bn_rand_interval(priv_key, 1, order)) 259 goto err; 260 if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, NULL)) 261 goto err; 262 263 BN_free(eckey->priv_key); 264 eckey->priv_key = priv_key; 265 priv_key = NULL; 266 267 EC_POINT_free(eckey->pub_key); 268 eckey->pub_key = pub_key; 269 pub_key = NULL; 270 271 ret = 1; 272 273 err: 274 EC_POINT_free(pub_key); 275 BN_free(priv_key); 276 277 return ret; 278 } 279 280 int 281 EC_KEY_check_key(const EC_KEY *eckey) 282 { 283 BN_CTX *ctx = NULL; 284 EC_POINT *point = NULL; 285 const BIGNUM *order; 286 int ret = 0; 287 288 if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { 289 ECerror(ERR_R_PASSED_NULL_PARAMETER); 290 goto err; 291 } 292 293 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { 294 ECerror(EC_R_POINT_AT_INFINITY); 295 goto err; 296 } 297 298 if ((ctx = BN_CTX_new()) == NULL) 299 goto err; 300 301 if ((point = EC_POINT_new(eckey->group)) == NULL) 302 goto err; 303 304 /* Ensure public key is on the elliptic curve. */ 305 if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { 306 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 307 goto err; 308 } 309 310 /* Ensure public key multiplied by the order is the point at infinity. */ 311 if ((order = EC_GROUP_get0_order(eckey->group)) == NULL) { 312 ECerror(EC_R_INVALID_GROUP_ORDER); 313 goto err; 314 } 315 if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { 316 ECerror(ERR_R_EC_LIB); 317 goto err; 318 } 319 if (!EC_POINT_is_at_infinity(eckey->group, point)) { 320 ECerror(EC_R_WRONG_ORDER); 321 goto err; 322 } 323 324 /* 325 * If the private key is present, ensure that the private key multiplied 326 * by the generator matches the public key. 327 */ 328 if (eckey->priv_key != NULL) { 329 if (BN_cmp(eckey->priv_key, order) >= 0) { 330 ECerror(EC_R_WRONG_ORDER); 331 goto err; 332 } 333 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, 334 NULL, ctx)) { 335 ECerror(ERR_R_EC_LIB); 336 goto err; 337 } 338 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, 339 ctx) != 0) { 340 ECerror(EC_R_INVALID_PRIVATE_KEY); 341 goto err; 342 } 343 } 344 345 ret = 1; 346 347 err: 348 BN_CTX_free(ctx); 349 EC_POINT_free(point); 350 351 return ret; 352 } 353 LCRYPTO_ALIAS(EC_KEY_check_key); 354 355 int 356 EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y) 357 { 358 BN_CTX *ctx = NULL; 359 EC_POINT *point = NULL; 360 BIGNUM *tx, *ty; 361 int ret = 0; 362 363 if (key == NULL || key->group == NULL || x == NULL || y == NULL) { 364 ECerror(ERR_R_PASSED_NULL_PARAMETER); 365 goto err; 366 } 367 368 if ((ctx = BN_CTX_new()) == NULL) 369 goto err; 370 371 BN_CTX_start(ctx); 372 373 if ((tx = BN_CTX_get(ctx)) == NULL) 374 goto err; 375 if ((ty = BN_CTX_get(ctx)) == NULL) 376 goto err; 377 378 if ((point = EC_POINT_new(key->group)) == NULL) 379 goto err; 380 381 if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx)) 382 goto err; 383 if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx)) 384 goto err; 385 386 /* 387 * Check if retrieved coordinates match originals: if not values are 388 * out of range. 389 */ 390 if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) { 391 ECerror(EC_R_COORDINATES_OUT_OF_RANGE); 392 goto err; 393 } 394 if (!EC_KEY_set_public_key(key, point)) 395 goto err; 396 if (EC_KEY_check_key(key) == 0) 397 goto err; 398 399 ret = 1; 400 401 err: 402 BN_CTX_end(ctx); 403 BN_CTX_free(ctx); 404 EC_POINT_free(point); 405 406 return ret; 407 } 408 LCRYPTO_ALIAS(EC_KEY_set_public_key_affine_coordinates); 409 410 const EC_GROUP * 411 EC_KEY_get0_group(const EC_KEY *key) 412 { 413 return key->group; 414 } 415 LCRYPTO_ALIAS(EC_KEY_get0_group); 416 417 int 418 EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) 419 { 420 if (key->meth->set_group != NULL && 421 key->meth->set_group(key, group) == 0) 422 return 0; 423 EC_GROUP_free(key->group); 424 key->group = EC_GROUP_dup(group); 425 return (key->group == NULL) ? 0 : 1; 426 } 427 LCRYPTO_ALIAS(EC_KEY_set_group); 428 429 const BIGNUM * 430 EC_KEY_get0_private_key(const EC_KEY *key) 431 { 432 return key->priv_key; 433 } 434 LCRYPTO_ALIAS(EC_KEY_get0_private_key); 435 436 int 437 EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) 438 { 439 if (key->meth->set_private != NULL && 440 key->meth->set_private(key, priv_key) == 0) 441 return 0; 442 443 BN_free(key->priv_key); 444 if ((key->priv_key = BN_dup(priv_key)) == NULL) 445 return 0; 446 447 return 1; 448 } 449 LCRYPTO_ALIAS(EC_KEY_set_private_key); 450 451 const EC_POINT * 452 EC_KEY_get0_public_key(const EC_KEY *key) 453 { 454 return key->pub_key; 455 } 456 LCRYPTO_ALIAS(EC_KEY_get0_public_key); 457 458 int 459 EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) 460 { 461 if (key->meth->set_public != NULL && 462 key->meth->set_public(key, pub_key) == 0) 463 return 0; 464 465 EC_POINT_free(key->pub_key); 466 if ((key->pub_key = EC_POINT_dup(pub_key, key->group)) == NULL) 467 return 0; 468 469 return 1; 470 } 471 LCRYPTO_ALIAS(EC_KEY_set_public_key); 472 473 unsigned int 474 EC_KEY_get_enc_flags(const EC_KEY *key) 475 { 476 return key->enc_flag; 477 } 478 LCRYPTO_ALIAS(EC_KEY_get_enc_flags); 479 480 void 481 EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) 482 { 483 key->enc_flag = flags; 484 } 485 LCRYPTO_ALIAS(EC_KEY_set_enc_flags); 486 487 point_conversion_form_t 488 EC_KEY_get_conv_form(const EC_KEY *key) 489 { 490 return key->conv_form; 491 } 492 LCRYPTO_ALIAS(EC_KEY_get_conv_form); 493 494 void 495 EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) 496 { 497 key->conv_form = cform; 498 if (key->group != NULL) 499 EC_GROUP_set_point_conversion_form(key->group, cform); 500 } 501 LCRYPTO_ALIAS(EC_KEY_set_conv_form); 502 503 void 504 EC_KEY_set_asn1_flag(EC_KEY *key, int flag) 505 { 506 if (key->group != NULL) 507 EC_GROUP_set_asn1_flag(key->group, flag); 508 } 509 LCRYPTO_ALIAS(EC_KEY_set_asn1_flag); 510 511 int 512 EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) 513 { 514 if (key->group == NULL) 515 return 0; 516 return 1; 517 } 518 LCRYPTO_ALIAS(EC_KEY_precompute_mult); 519 520 int 521 EC_KEY_get_flags(const EC_KEY *key) 522 { 523 return key->flags; 524 } 525 LCRYPTO_ALIAS(EC_KEY_get_flags); 526 527 void 528 EC_KEY_set_flags(EC_KEY *key, int flags) 529 { 530 key->flags |= flags; 531 } 532 LCRYPTO_ALIAS(EC_KEY_set_flags); 533 534 void 535 EC_KEY_clear_flags(EC_KEY *key, int flags) 536 { 537 key->flags &= ~flags; 538 } 539 LCRYPTO_ALIAS(EC_KEY_clear_flags); 540 541 const EC_KEY_METHOD * 542 EC_KEY_get_method(const EC_KEY *key) 543 { 544 return key->meth; 545 } 546 LCRYPTO_ALIAS(EC_KEY_get_method); 547 548 int 549 EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) 550 { 551 void (*finish)(EC_KEY *key) = key->meth->finish; 552 553 if (finish != NULL) 554 finish(key); 555 556 key->meth = meth; 557 if (meth->init != NULL) 558 return meth->init(key); 559 return 1; 560 } 561 LCRYPTO_ALIAS(EC_KEY_set_method); 562 563 EC_KEY * 564 EC_KEY_new_method(ENGINE *engine) 565 { 566 EC_KEY *ret; 567 568 if ((ret = calloc(1, sizeof(EC_KEY))) == NULL) { 569 ECerror(ERR_R_MALLOC_FAILURE); 570 return NULL; 571 } 572 ret->meth = EC_KEY_get_default_method(); 573 ret->version = 1; 574 ret->flags = 0; 575 ret->group = NULL; 576 ret->pub_key = NULL; 577 ret->priv_key = NULL; 578 ret->enc_flag = 0; 579 ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; 580 ret->references = 1; 581 582 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) 583 goto err; 584 if (ret->meth->init != NULL && ret->meth->init(ret) == 0) 585 goto err; 586 587 return ret; 588 589 err: 590 EC_KEY_free(ret); 591 return NULL; 592 } 593 LCRYPTO_ALIAS(EC_KEY_new_method); 594 595 #define EC_KEY_METHOD_DYNAMIC 1 596 597 EC_KEY_METHOD * 598 EC_KEY_METHOD_new(const EC_KEY_METHOD *meth) 599 { 600 EC_KEY_METHOD *ret; 601 602 if ((ret = calloc(1, sizeof(*meth))) == NULL) 603 return NULL; 604 if (meth != NULL) 605 *ret = *meth; 606 ret->flags |= EC_KEY_METHOD_DYNAMIC; 607 return ret; 608 } 609 LCRYPTO_ALIAS(EC_KEY_METHOD_new); 610 611 void 612 EC_KEY_METHOD_free(EC_KEY_METHOD *meth) 613 { 614 if (meth == NULL) 615 return; 616 if (meth->flags & EC_KEY_METHOD_DYNAMIC) 617 free(meth); 618 } 619 LCRYPTO_ALIAS(EC_KEY_METHOD_free); 620 621 void 622 EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, 623 int (*init)(EC_KEY *key), 624 void (*finish)(EC_KEY *key), 625 int (*copy)(EC_KEY *dest, const EC_KEY *src), 626 int (*set_group)(EC_KEY *key, const EC_GROUP *grp), 627 int (*set_private)(EC_KEY *key, const BIGNUM *priv_key), 628 int (*set_public)(EC_KEY *key, const EC_POINT *pub_key)) 629 { 630 meth->init = init; 631 meth->finish = finish; 632 meth->copy = copy; 633 meth->set_group = set_group; 634 meth->set_private = set_private; 635 meth->set_public = set_public; 636 } 637 LCRYPTO_ALIAS(EC_KEY_METHOD_set_init); 638 639 void 640 EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, int (*keygen)(EC_KEY *key)) 641 { 642 meth->keygen = keygen; 643 } 644 LCRYPTO_ALIAS(EC_KEY_METHOD_set_keygen); 645 646 void 647 EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, 648 int (*ckey)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, 649 const EC_KEY *ecdh)) 650 { 651 meth->compute_key = ckey; 652 } 653 LCRYPTO_ALIAS(EC_KEY_METHOD_set_compute_key); 654 655 void 656 EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, 657 int (*sign)(int type, const unsigned char *dgst, 658 int dlen, unsigned char *sig, unsigned int *siglen, 659 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey), 660 int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, 661 BIGNUM **kinvp, BIGNUM **rp), 662 ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, 663 int dgst_len, const BIGNUM *in_kinv, 664 const BIGNUM *in_r, EC_KEY *eckey)) 665 { 666 meth->sign = sign; 667 meth->sign_setup = sign_setup; 668 meth->sign_sig = sign_sig; 669 } 670 LCRYPTO_ALIAS(EC_KEY_METHOD_set_sign); 671 672 void 673 EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, 674 int (*verify)(int type, const unsigned char *dgst, int dgst_len, 675 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), 676 int (*verify_sig)(const unsigned char *dgst, int dgst_len, 677 const ECDSA_SIG *sig, EC_KEY *eckey)) 678 { 679 meth->verify = verify; 680 meth->verify_sig = verify_sig; 681 } 682 LCRYPTO_ALIAS(EC_KEY_METHOD_set_verify); 683 684 685 void 686 EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, 687 int (**pinit)(EC_KEY *key), 688 void (**pfinish)(EC_KEY *key), 689 int (**pcopy)(EC_KEY *dest, const EC_KEY *src), 690 int (**pset_group)(EC_KEY *key, const EC_GROUP *grp), 691 int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key), 692 int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key)) 693 { 694 if (pinit != NULL) 695 *pinit = meth->init; 696 if (pfinish != NULL) 697 *pfinish = meth->finish; 698 if (pcopy != NULL) 699 *pcopy = meth->copy; 700 if (pset_group != NULL) 701 *pset_group = meth->set_group; 702 if (pset_private != NULL) 703 *pset_private = meth->set_private; 704 if (pset_public != NULL) 705 *pset_public = meth->set_public; 706 } 707 LCRYPTO_ALIAS(EC_KEY_METHOD_get_init); 708 709 void 710 EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, 711 int (**pkeygen)(EC_KEY *key)) 712 { 713 if (pkeygen != NULL) 714 *pkeygen = meth->keygen; 715 } 716 LCRYPTO_ALIAS(EC_KEY_METHOD_get_keygen); 717 718 void 719 EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, 720 int (**pck)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, 721 const EC_KEY *ecdh)) 722 { 723 if (pck != NULL) 724 *pck = meth->compute_key; 725 } 726 LCRYPTO_ALIAS(EC_KEY_METHOD_get_compute_key); 727 728 void 729 EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, 730 int (**psign)(int type, const unsigned char *dgst, 731 int dlen, unsigned char *sig, unsigned int *siglen, 732 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey), 733 int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, 734 BIGNUM **kinvp, BIGNUM **rp), 735 ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, 736 int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, 737 EC_KEY *eckey)) 738 { 739 if (psign != NULL) 740 *psign = meth->sign; 741 if (psign_setup != NULL) 742 *psign_setup = meth->sign_setup; 743 if (psign_sig != NULL) 744 *psign_sig = meth->sign_sig; 745 } 746 LCRYPTO_ALIAS(EC_KEY_METHOD_get_sign); 747 748 void 749 EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, 750 int (**pverify)(int type, const unsigned char *dgst, int dgst_len, 751 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), 752 int (**pverify_sig)(const unsigned char *dgst, int dgst_len, 753 const ECDSA_SIG *sig, EC_KEY *eckey)) 754 { 755 if (pverify != NULL) 756 *pverify = meth->verify; 757 if (pverify_sig != NULL) 758 *pverify_sig = meth->verify_sig; 759 } 760 LCRYPTO_ALIAS(EC_KEY_METHOD_get_verify); 761 762 static const EC_KEY_METHOD openssl_ec_key_method = { 763 .name = "OpenSSL EC_KEY method", 764 .flags = 0, 765 766 .init = NULL, 767 .finish = NULL, 768 .copy = NULL, 769 770 .set_group = NULL, 771 .set_private = NULL, 772 .set_public = NULL, 773 774 .keygen = ec_key_gen, 775 .compute_key = ecdh_compute_key, 776 777 .sign = ecdsa_sign, 778 .sign_setup = ecdsa_sign_setup, 779 .sign_sig = ecdsa_sign_sig, 780 781 .verify = ecdsa_verify, 782 .verify_sig = ecdsa_verify_sig, 783 }; 784 785 const EC_KEY_METHOD * 786 EC_KEY_OpenSSL(void) 787 { 788 return &openssl_ec_key_method; 789 } 790 LCRYPTO_ALIAS(EC_KEY_OpenSSL); 791 792 const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method; 793 794 const EC_KEY_METHOD * 795 EC_KEY_get_default_method(void) 796 { 797 return default_ec_key_meth; 798 } 799 LCRYPTO_ALIAS(EC_KEY_get_default_method); 800 801 void 802 EC_KEY_set_default_method(const EC_KEY_METHOD *meth) 803 { 804 if (meth == NULL) 805 default_ec_key_meth = &openssl_ec_key_method; 806 else 807 default_ec_key_meth = meth; 808 } 809 LCRYPTO_ALIAS(EC_KEY_set_default_method); 810