1 /* $OpenBSD: ec_lib.c,v 1.41 2021/09/12 16:23:19 tb Exp $ */ 2 /* 3 * Originally written by Bodo Moeller for the OpenSSL project. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1998-2003 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 * Binary polynomial ECC support in OpenSSL originally developed by 61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 62 */ 63 64 #include <string.h> 65 66 #include <openssl/opensslconf.h> 67 68 #include <openssl/err.h> 69 #include <openssl/opensslv.h> 70 71 #include "bn_lcl.h" 72 #include "ec_lcl.h" 73 74 /* functions for EC_GROUP objects */ 75 76 EC_GROUP * 77 EC_GROUP_new(const EC_METHOD * meth) 78 { 79 EC_GROUP *ret; 80 81 if (meth == NULL) { 82 ECerror(EC_R_SLOT_FULL); 83 return NULL; 84 } 85 if (meth->group_init == 0) { 86 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 87 return NULL; 88 } 89 ret = malloc(sizeof *ret); 90 if (ret == NULL) { 91 ECerror(ERR_R_MALLOC_FAILURE); 92 return NULL; 93 } 94 ret->meth = meth; 95 96 ret->extra_data = NULL; 97 98 ret->generator = NULL; 99 BN_init(&ret->order); 100 BN_init(&ret->cofactor); 101 102 ret->curve_name = 0; 103 ret->asn1_flag = OPENSSL_EC_NAMED_CURVE; 104 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; 105 106 ret->seed = NULL; 107 ret->seed_len = 0; 108 109 if (!meth->group_init(ret)) { 110 free(ret); 111 return NULL; 112 } 113 return ret; 114 } 115 116 117 void 118 EC_GROUP_free(EC_GROUP * group) 119 { 120 if (!group) 121 return; 122 123 if (group->meth->group_finish != 0) 124 group->meth->group_finish(group); 125 126 EC_EX_DATA_free_all_data(&group->extra_data); 127 128 EC_POINT_free(group->generator); 129 BN_free(&group->order); 130 BN_free(&group->cofactor); 131 132 free(group->seed); 133 134 free(group); 135 } 136 137 138 void 139 EC_GROUP_clear_free(EC_GROUP * group) 140 { 141 if (!group) 142 return; 143 144 if (group->meth->group_clear_finish != 0) 145 group->meth->group_clear_finish(group); 146 else if (group->meth->group_finish != 0) 147 group->meth->group_finish(group); 148 149 EC_EX_DATA_clear_free_all_data(&group->extra_data); 150 151 EC_POINT_clear_free(group->generator); 152 BN_clear_free(&group->order); 153 BN_clear_free(&group->cofactor); 154 155 freezero(group->seed, group->seed_len); 156 freezero(group, sizeof *group); 157 } 158 159 160 int 161 EC_GROUP_copy(EC_GROUP * dest, const EC_GROUP * src) 162 { 163 EC_EXTRA_DATA *d; 164 165 if (dest->meth->group_copy == 0) { 166 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 167 return 0; 168 } 169 if (dest->meth != src->meth) { 170 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 171 return 0; 172 } 173 if (dest == src) 174 return 1; 175 176 EC_EX_DATA_free_all_data(&dest->extra_data); 177 178 for (d = src->extra_data; d != NULL; d = d->next) { 179 void *t = d->dup_func(d->data); 180 181 if (t == NULL) 182 return 0; 183 if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func, 184 d->free_func, d->clear_free_func)) 185 return 0; 186 } 187 188 if (src->generator != NULL) { 189 if (dest->generator == NULL) { 190 dest->generator = EC_POINT_new(dest); 191 if (dest->generator == NULL) 192 return 0; 193 } 194 if (!EC_POINT_copy(dest->generator, src->generator)) 195 return 0; 196 } else { 197 /* src->generator == NULL */ 198 EC_POINT_clear_free(dest->generator); 199 dest->generator = NULL; 200 } 201 202 if (!BN_copy(&dest->order, &src->order)) 203 return 0; 204 if (!BN_copy(&dest->cofactor, &src->cofactor)) 205 return 0; 206 207 dest->curve_name = src->curve_name; 208 dest->asn1_flag = src->asn1_flag; 209 dest->asn1_form = src->asn1_form; 210 211 if (src->seed) { 212 free(dest->seed); 213 dest->seed = malloc(src->seed_len); 214 if (dest->seed == NULL) 215 return 0; 216 memcpy(dest->seed, src->seed, src->seed_len); 217 dest->seed_len = src->seed_len; 218 } else { 219 free(dest->seed); 220 dest->seed = NULL; 221 dest->seed_len = 0; 222 } 223 224 225 return dest->meth->group_copy(dest, src); 226 } 227 228 229 EC_GROUP * 230 EC_GROUP_dup(const EC_GROUP * a) 231 { 232 EC_GROUP *t = NULL; 233 234 if ((a != NULL) && ((t = EC_GROUP_new(a->meth)) != NULL) && 235 (!EC_GROUP_copy(t, a))) { 236 EC_GROUP_free(t); 237 t = NULL; 238 } 239 return t; 240 } 241 242 243 const EC_METHOD * 244 EC_GROUP_method_of(const EC_GROUP *group) 245 { 246 return group->meth; 247 } 248 249 250 int 251 EC_METHOD_get_field_type(const EC_METHOD *meth) 252 { 253 return meth->field_type; 254 } 255 256 /* 257 * Try computing the cofactor from generator order n and field cardinality q. 258 * This works for all curves of cryptographic interest. 259 * 260 * Hasse's theorem: | h * n - (q + 1) | <= 2 * sqrt(q) 261 * 262 * So: h_min = (q + 1 - 2*sqrt(q)) / n and h_max = (q + 1 + 2*sqrt(q)) / n and 263 * therefore h_max - h_min = 4*sqrt(q) / n. So if n > 4*sqrt(q) holds, there is 264 * only one possible value for h: 265 * 266 * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil 267 * 268 * Otherwise, zero cofactor and return success. 269 */ 270 static int 271 ec_guess_cofactor(EC_GROUP *group) 272 { 273 BN_CTX *ctx = NULL; 274 BIGNUM *q = NULL; 275 int ret = 0; 276 277 /* 278 * If the cofactor is too large, we cannot guess it and default to zero. 279 * The RHS of below is a strict overestimate of log(4 * sqrt(q)). 280 */ 281 if (BN_num_bits(&group->order) <= 282 (BN_num_bits(&group->field) + 1) / 2 + 3) { 283 BN_zero(&group->cofactor); 284 return 1; 285 } 286 287 if ((ctx = BN_CTX_new()) == NULL) 288 goto err; 289 290 BN_CTX_start(ctx); 291 if ((q = BN_CTX_get(ctx)) == NULL) 292 goto err; 293 294 /* Set q = 2**m for binary fields; q = p otherwise. */ 295 if (group->meth->field_type == NID_X9_62_characteristic_two_field) { 296 BN_zero(q); 297 if (!BN_set_bit(q, BN_num_bits(&group->field) - 1)) 298 goto err; 299 } else { 300 if (!BN_copy(q, &group->field)) 301 goto err; 302 } 303 304 /* 305 * Compute 306 * h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2) / n \rfloor. 307 */ 308 309 /* h = n/2 */ 310 if (!BN_rshift1(&group->cofactor, &group->order)) 311 goto err; 312 /* h = 1 + n/2 */ 313 if (!BN_add(&group->cofactor, &group->cofactor, BN_value_one())) 314 goto err; 315 /* h = q + 1 + n/2 */ 316 if (!BN_add(&group->cofactor, &group->cofactor, q)) 317 goto err; 318 /* h = (q + 1 + n/2) / n */ 319 if (!BN_div_ct(&group->cofactor, NULL, &group->cofactor, &group->order, 320 ctx)) 321 goto err; 322 323 ret = 1; 324 err: 325 BN_CTX_end(ctx); 326 BN_CTX_free(ctx); 327 BN_zero(&group->cofactor); 328 return ret; 329 } 330 331 int 332 EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 333 const BIGNUM *order, const BIGNUM *cofactor) 334 { 335 if (generator == NULL) { 336 ECerror(ERR_R_PASSED_NULL_PARAMETER); 337 return 0; 338 } 339 340 /* Require group->field >= 1. */ 341 if (BN_is_zero(&group->field) || BN_is_negative(&group->field)) { 342 ECerror(EC_R_INVALID_FIELD); 343 return 0; 344 } 345 346 /* 347 * Require order >= 1 and enforce an upper bound of at most one bit more 348 * than the field cardinality due to Hasse's theorem. 349 */ 350 if (order == NULL || BN_is_zero(order) || BN_is_negative(order) || 351 BN_num_bits(order) > BN_num_bits(&group->field) + 1) { 352 ECerror(EC_R_INVALID_GROUP_ORDER); 353 return 0; 354 } 355 356 /* 357 * Unfortunately, the cofactor is an optional field in many standards. 358 * Internally, the library uses a 0 cofactor as a marker for "unknown 359 * cofactor". So accept cofactor == NULL or cofactor >= 0. 360 */ 361 if (cofactor != NULL && BN_is_negative(cofactor)) { 362 ECerror(EC_R_UNKNOWN_COFACTOR); 363 return 0; 364 } 365 366 if (group->generator == NULL) { 367 group->generator = EC_POINT_new(group); 368 if (group->generator == NULL) 369 return 0; 370 } 371 if (!EC_POINT_copy(group->generator, generator)) 372 return 0; 373 374 if (!BN_copy(&group->order, order)) 375 return 0; 376 377 /* Either take the provided positive cofactor, or try to compute it. */ 378 if (cofactor != NULL && !BN_is_zero(cofactor)) { 379 if (!BN_copy(&group->cofactor, cofactor)) 380 return 0; 381 } else if (!ec_guess_cofactor(group)) 382 return 0; 383 384 return 1; 385 } 386 387 388 const EC_POINT * 389 EC_GROUP_get0_generator(const EC_GROUP *group) 390 { 391 return group->generator; 392 } 393 394 395 int 396 EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) 397 { 398 if (!BN_copy(order, &group->order)) 399 return 0; 400 401 return !BN_is_zero(order); 402 } 403 404 int 405 EC_GROUP_order_bits(const EC_GROUP *group) 406 { 407 return group->meth->group_order_bits(group); 408 } 409 410 int 411 EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) 412 { 413 if (!BN_copy(cofactor, &group->cofactor)) 414 return 0; 415 416 return !BN_is_zero(&group->cofactor); 417 } 418 419 420 void 421 EC_GROUP_set_curve_name(EC_GROUP * group, int nid) 422 { 423 group->curve_name = nid; 424 } 425 426 427 int 428 EC_GROUP_get_curve_name(const EC_GROUP * group) 429 { 430 return group->curve_name; 431 } 432 433 434 void 435 EC_GROUP_set_asn1_flag(EC_GROUP * group, int flag) 436 { 437 group->asn1_flag = flag; 438 } 439 440 441 int 442 EC_GROUP_get_asn1_flag(const EC_GROUP * group) 443 { 444 return group->asn1_flag; 445 } 446 447 448 void 449 EC_GROUP_set_point_conversion_form(EC_GROUP * group, 450 point_conversion_form_t form) 451 { 452 group->asn1_form = form; 453 } 454 455 456 point_conversion_form_t 457 EC_GROUP_get_point_conversion_form(const EC_GROUP * group) 458 { 459 return group->asn1_form; 460 } 461 462 463 size_t 464 EC_GROUP_set_seed(EC_GROUP * group, const unsigned char *p, size_t len) 465 { 466 if (group->seed) { 467 free(group->seed); 468 group->seed = NULL; 469 group->seed_len = 0; 470 } 471 if (!len || !p) 472 return 1; 473 474 if ((group->seed = malloc(len)) == NULL) 475 return 0; 476 memcpy(group->seed, p, len); 477 group->seed_len = len; 478 479 return len; 480 } 481 482 483 unsigned char * 484 EC_GROUP_get0_seed(const EC_GROUP * group) 485 { 486 return group->seed; 487 } 488 489 490 size_t 491 EC_GROUP_get_seed_len(const EC_GROUP * group) 492 { 493 return group->seed_len; 494 } 495 496 int 497 EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 498 const BIGNUM *b, BN_CTX *ctx) 499 { 500 if (group->meth->group_set_curve == NULL) { 501 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 502 return 0; 503 } 504 return group->meth->group_set_curve(group, p, a, b, ctx); 505 } 506 507 int 508 EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, 509 BN_CTX *ctx) 510 { 511 if (group->meth->group_get_curve == NULL) { 512 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 513 return 0; 514 } 515 return group->meth->group_get_curve(group, p, a, b, ctx); 516 } 517 518 int 519 EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 520 const BIGNUM *b, BN_CTX *ctx) 521 { 522 return EC_GROUP_set_curve(group, p, a, b, ctx); 523 } 524 525 int 526 EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, 527 BN_CTX *ctx) 528 { 529 return EC_GROUP_get_curve(group, p, a, b, ctx); 530 } 531 532 #ifndef OPENSSL_NO_EC2M 533 int 534 EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 535 const BIGNUM *b, BN_CTX *ctx) 536 { 537 return EC_GROUP_set_curve(group, p, a, b, ctx); 538 } 539 540 int 541 EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, 542 BIGNUM *b, BN_CTX *ctx) 543 { 544 return EC_GROUP_get_curve(group, p, a, b, ctx); 545 } 546 #endif 547 548 int 549 EC_GROUP_get_degree(const EC_GROUP * group) 550 { 551 if (group->meth->group_get_degree == 0) { 552 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 553 return 0; 554 } 555 return group->meth->group_get_degree(group); 556 } 557 558 559 int 560 EC_GROUP_check_discriminant(const EC_GROUP * group, BN_CTX * ctx) 561 { 562 if (group->meth->group_check_discriminant == 0) { 563 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 564 return 0; 565 } 566 return group->meth->group_check_discriminant(group, ctx); 567 } 568 569 570 int 571 EC_GROUP_cmp(const EC_GROUP * a, const EC_GROUP * b, BN_CTX * ctx) 572 { 573 int r = 0; 574 BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; 575 BN_CTX *ctx_new = NULL; 576 577 /* compare the field types */ 578 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != 579 EC_METHOD_get_field_type(EC_GROUP_method_of(b))) 580 return 1; 581 /* compare the curve name (if present in both) */ 582 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && 583 EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) 584 return 1; 585 586 if (!ctx) 587 ctx_new = ctx = BN_CTX_new(); 588 if (!ctx) 589 return -1; 590 591 BN_CTX_start(ctx); 592 if ((a1 = BN_CTX_get(ctx)) == NULL) 593 goto err; 594 if ((a2 = BN_CTX_get(ctx)) == NULL) 595 goto err; 596 if ((a3 = BN_CTX_get(ctx)) == NULL) 597 goto err; 598 if ((b1 = BN_CTX_get(ctx)) == NULL) 599 goto err; 600 if ((b2 = BN_CTX_get(ctx)) == NULL) 601 goto err; 602 if ((b3 = BN_CTX_get(ctx)) == NULL) 603 goto err; 604 605 /* 606 * XXX This approach assumes that the external representation of 607 * curves over the same field type is the same. 608 */ 609 if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || 610 !b->meth->group_get_curve(b, b1, b2, b3, ctx)) 611 r = 1; 612 613 if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) 614 r = 1; 615 616 /* XXX EC_POINT_cmp() assumes that the methods are equal */ 617 if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), 618 EC_GROUP_get0_generator(b), ctx)) 619 r = 1; 620 621 if (!r) { 622 /* compare the order and cofactor */ 623 if (!EC_GROUP_get_order(a, a1, ctx) || 624 !EC_GROUP_get_order(b, b1, ctx) || 625 !EC_GROUP_get_cofactor(a, a2, ctx) || 626 !EC_GROUP_get_cofactor(b, b2, ctx)) 627 goto err; 628 if (BN_cmp(a1, b1) || BN_cmp(a2, b2)) 629 r = 1; 630 } 631 BN_CTX_end(ctx); 632 if (ctx_new) 633 BN_CTX_free(ctx); 634 635 return r; 636 637 err: 638 BN_CTX_end(ctx); 639 if (ctx_new) 640 BN_CTX_free(ctx); 641 return -1; 642 } 643 644 /* 645 * Coordinate blinding for EC_POINT. 646 * 647 * The underlying EC_METHOD can optionally implement this function: 648 * underlying implementations should return 0 on errors, or 1 on success. 649 * 650 * This wrapper returns 1 in case the underlying EC_METHOD does not support 651 * coordinate blinding. 652 */ 653 int 654 ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) 655 { 656 if (group->meth->blind_coordinates == NULL) 657 return 1; 658 659 return group->meth->blind_coordinates(group, p, ctx); 660 } 661 662 /* this has 'package' visibility */ 663 int 664 EC_EX_DATA_set_data(EC_EXTRA_DATA ** ex_data, void *data, 665 void *(*dup_func) (void *), 666 void (*free_func) (void *), 667 void (*clear_free_func) (void *)) 668 { 669 EC_EXTRA_DATA *d; 670 671 if (ex_data == NULL) 672 return 0; 673 674 for (d = *ex_data; d != NULL; d = d->next) { 675 if (d->dup_func == dup_func && d->free_func == free_func && 676 d->clear_free_func == clear_free_func) { 677 ECerror(EC_R_SLOT_FULL); 678 return 0; 679 } 680 } 681 682 if (data == NULL) 683 /* no explicit entry needed */ 684 return 1; 685 686 d = malloc(sizeof *d); 687 if (d == NULL) 688 return 0; 689 690 d->data = data; 691 d->dup_func = dup_func; 692 d->free_func = free_func; 693 d->clear_free_func = clear_free_func; 694 695 d->next = *ex_data; 696 *ex_data = d; 697 698 return 1; 699 } 700 701 /* this has 'package' visibility */ 702 void * 703 EC_EX_DATA_get_data(const EC_EXTRA_DATA * ex_data, 704 void *(*dup_func) (void *), 705 void (*free_func) (void *), 706 void (*clear_free_func) (void *)) 707 { 708 const EC_EXTRA_DATA *d; 709 710 for (d = ex_data; d != NULL; d = d->next) { 711 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func) 712 return d->data; 713 } 714 715 return NULL; 716 } 717 718 /* this has 'package' visibility */ 719 void 720 EC_EX_DATA_free_data(EC_EXTRA_DATA ** ex_data, 721 void *(*dup_func) (void *), 722 void (*free_func) (void *), 723 void (*clear_free_func) (void *)) 724 { 725 EC_EXTRA_DATA **p; 726 727 if (ex_data == NULL) 728 return; 729 730 for (p = ex_data; *p != NULL; p = &((*p)->next)) { 731 if ((*p)->dup_func == dup_func && 732 (*p)->free_func == free_func && 733 (*p)->clear_free_func == clear_free_func) { 734 EC_EXTRA_DATA *next = (*p)->next; 735 736 (*p)->free_func((*p)->data); 737 free(*p); 738 739 *p = next; 740 return; 741 } 742 } 743 } 744 745 /* this has 'package' visibility */ 746 void 747 EC_EX_DATA_clear_free_data(EC_EXTRA_DATA ** ex_data, 748 void *(*dup_func) (void *), 749 void (*free_func) (void *), 750 void (*clear_free_func) (void *)) 751 { 752 EC_EXTRA_DATA **p; 753 754 if (ex_data == NULL) 755 return; 756 757 for (p = ex_data; *p != NULL; p = &((*p)->next)) { 758 if ((*p)->dup_func == dup_func && 759 (*p)->free_func == free_func && 760 (*p)->clear_free_func == clear_free_func) { 761 EC_EXTRA_DATA *next = (*p)->next; 762 763 (*p)->clear_free_func((*p)->data); 764 free(*p); 765 766 *p = next; 767 return; 768 } 769 } 770 } 771 772 /* this has 'package' visibility */ 773 void 774 EC_EX_DATA_free_all_data(EC_EXTRA_DATA ** ex_data) 775 { 776 EC_EXTRA_DATA *d; 777 778 if (ex_data == NULL) 779 return; 780 781 d = *ex_data; 782 while (d) { 783 EC_EXTRA_DATA *next = d->next; 784 785 d->free_func(d->data); 786 free(d); 787 788 d = next; 789 } 790 *ex_data = NULL; 791 } 792 793 /* this has 'package' visibility */ 794 void 795 EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data) 796 { 797 EC_EXTRA_DATA *d; 798 799 if (ex_data == NULL) 800 return; 801 802 d = *ex_data; 803 while (d) { 804 EC_EXTRA_DATA *next = d->next; 805 806 d->clear_free_func(d->data); 807 free(d); 808 809 d = next; 810 } 811 *ex_data = NULL; 812 } 813 814 815 /* functions for EC_POINT objects */ 816 817 EC_POINT * 818 EC_POINT_new(const EC_GROUP * group) 819 { 820 EC_POINT *ret; 821 822 if (group == NULL) { 823 ECerror(ERR_R_PASSED_NULL_PARAMETER); 824 return NULL; 825 } 826 if (group->meth->point_init == 0) { 827 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 828 return NULL; 829 } 830 ret = malloc(sizeof *ret); 831 if (ret == NULL) { 832 ECerror(ERR_R_MALLOC_FAILURE); 833 return NULL; 834 } 835 ret->meth = group->meth; 836 837 if (!ret->meth->point_init(ret)) { 838 free(ret); 839 return NULL; 840 } 841 return ret; 842 } 843 844 845 void 846 EC_POINT_free(EC_POINT * point) 847 { 848 if (!point) 849 return; 850 851 if (point->meth->point_finish != 0) 852 point->meth->point_finish(point); 853 free(point); 854 } 855 856 857 void 858 EC_POINT_clear_free(EC_POINT * point) 859 { 860 if (!point) 861 return; 862 863 if (point->meth->point_clear_finish != 0) 864 point->meth->point_clear_finish(point); 865 else if (point->meth->point_finish != 0) 866 point->meth->point_finish(point); 867 freezero(point, sizeof *point); 868 } 869 870 871 int 872 EC_POINT_copy(EC_POINT * dest, const EC_POINT * src) 873 { 874 if (dest->meth->point_copy == 0) { 875 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 876 return 0; 877 } 878 if (dest->meth != src->meth) { 879 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 880 return 0; 881 } 882 if (dest == src) 883 return 1; 884 return dest->meth->point_copy(dest, src); 885 } 886 887 888 EC_POINT * 889 EC_POINT_dup(const EC_POINT * a, const EC_GROUP * group) 890 { 891 EC_POINT *t; 892 int r; 893 894 if (a == NULL) 895 return NULL; 896 897 t = EC_POINT_new(group); 898 if (t == NULL) 899 return (NULL); 900 r = EC_POINT_copy(t, a); 901 if (!r) { 902 EC_POINT_free(t); 903 return NULL; 904 } else 905 return t; 906 } 907 908 909 const EC_METHOD * 910 EC_POINT_method_of(const EC_POINT * point) 911 { 912 return point->meth; 913 } 914 915 916 int 917 EC_POINT_set_to_infinity(const EC_GROUP * group, EC_POINT * point) 918 { 919 if (group->meth->point_set_to_infinity == 0) { 920 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 921 return 0; 922 } 923 if (group->meth != point->meth) { 924 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 925 return 0; 926 } 927 return group->meth->point_set_to_infinity(group, point); 928 } 929 930 int 931 EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point, 932 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) 933 { 934 if (group->meth->point_set_Jprojective_coordinates == NULL) { 935 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 936 return 0; 937 } 938 if (group->meth != point->meth) { 939 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 940 return 0; 941 } 942 return group->meth->point_set_Jprojective_coordinates(group, point, 943 x, y, z, ctx); 944 } 945 946 int 947 EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, 948 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) 949 { 950 if (group->meth->point_get_Jprojective_coordinates == NULL) { 951 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 952 return 0; 953 } 954 if (group->meth != point->meth) { 955 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 956 return 0; 957 } 958 return group->meth->point_get_Jprojective_coordinates(group, point, 959 x, y, z, ctx); 960 } 961 962 int 963 EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 964 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) 965 { 966 return EC_POINT_set_Jprojective_coordinates(group, point, x, y, z, ctx); 967 } 968 969 int 970 EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, 971 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) 972 { 973 return EC_POINT_get_Jprojective_coordinates(group, point, x, y, z, ctx); 974 } 975 976 int 977 EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 978 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 979 { 980 if (group->meth->point_set_affine_coordinates == NULL) { 981 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 982 return 0; 983 } 984 if (group->meth != point->meth) { 985 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 986 return 0; 987 } 988 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx)) 989 return 0; 990 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 991 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 992 return 0; 993 } 994 return 1; 995 } 996 997 int 998 EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 999 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 1000 { 1001 return EC_POINT_set_affine_coordinates(group, point, x, y, ctx); 1002 } 1003 1004 #ifndef OPENSSL_NO_EC2M 1005 int 1006 EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point, 1007 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 1008 { 1009 return EC_POINT_set_affine_coordinates(group, point, x, y, ctx); 1010 } 1011 #endif 1012 1013 int 1014 EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, 1015 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 1016 { 1017 if (group->meth->point_get_affine_coordinates == NULL) { 1018 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1019 return 0; 1020 } 1021 if (group->meth != point->meth) { 1022 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1023 return 0; 1024 } 1025 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 1026 } 1027 1028 int 1029 EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, 1030 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 1031 { 1032 return EC_POINT_get_affine_coordinates(group, point, x, y, ctx); 1033 } 1034 1035 #ifndef OPENSSL_NO_EC2M 1036 int 1037 EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point, 1038 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 1039 { 1040 return EC_POINT_get_affine_coordinates(group, point, x, y, ctx); 1041 } 1042 #endif 1043 1044 int 1045 EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 1046 const EC_POINT *b, BN_CTX *ctx) 1047 { 1048 if (group->meth->add == 0) { 1049 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1050 return 0; 1051 } 1052 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) { 1053 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1054 return 0; 1055 } 1056 return group->meth->add(group, r, a, b, ctx); 1057 } 1058 1059 1060 int 1061 EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) 1062 { 1063 if (group->meth->dbl == 0) { 1064 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1065 return 0; 1066 } 1067 if ((group->meth != r->meth) || (r->meth != a->meth)) { 1068 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1069 return 0; 1070 } 1071 return group->meth->dbl(group, r, a, ctx); 1072 } 1073 1074 1075 int 1076 EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) 1077 { 1078 if (group->meth->invert == 0) { 1079 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1080 return 0; 1081 } 1082 if (group->meth != a->meth) { 1083 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1084 return 0; 1085 } 1086 return group->meth->invert(group, a, ctx); 1087 } 1088 1089 1090 int 1091 EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 1092 { 1093 if (group->meth->is_at_infinity == 0) { 1094 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1095 return 0; 1096 } 1097 if (group->meth != point->meth) { 1098 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1099 return 0; 1100 } 1101 return group->meth->is_at_infinity(group, point); 1102 } 1103 1104 1105 int 1106 EC_POINT_is_on_curve(const EC_GROUP * group, const EC_POINT * point, BN_CTX * ctx) 1107 { 1108 if (group->meth->is_on_curve == 0) { 1109 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1110 return 0; 1111 } 1112 if (group->meth != point->meth) { 1113 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1114 return 0; 1115 } 1116 return group->meth->is_on_curve(group, point, ctx); 1117 } 1118 1119 1120 int 1121 EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 1122 BN_CTX * ctx) 1123 { 1124 if (group->meth->point_cmp == 0) { 1125 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1126 return -1; 1127 } 1128 if ((group->meth != a->meth) || (a->meth != b->meth)) { 1129 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1130 return -1; 1131 } 1132 return group->meth->point_cmp(group, a, b, ctx); 1133 } 1134 1135 1136 int 1137 EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 1138 { 1139 if (group->meth->make_affine == 0) { 1140 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1141 return 0; 1142 } 1143 if (group->meth != point->meth) { 1144 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1145 return 0; 1146 } 1147 return group->meth->make_affine(group, point, ctx); 1148 } 1149 1150 1151 int 1152 EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], 1153 BN_CTX *ctx) 1154 { 1155 size_t i; 1156 1157 if (group->meth->points_make_affine == 0) { 1158 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1159 return 0; 1160 } 1161 for (i = 0; i < num; i++) { 1162 if (group->meth != points[i]->meth) { 1163 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1164 return 0; 1165 } 1166 } 1167 return group->meth->points_make_affine(group, num, points, ctx); 1168 } 1169 1170 1171 /* Functions for point multiplication */ 1172 int 1173 EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 1174 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) 1175 { 1176 /* 1177 * The function pointers must be set, and only support num == 0 and 1178 * num == 1. 1179 */ 1180 if (group->meth->mul_generator_ct == NULL || 1181 group->meth->mul_single_ct == NULL || 1182 group->meth->mul_double_nonct == NULL || 1183 num > 1) { 1184 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1185 return 0; 1186 } 1187 1188 /* Either bP or aG + bP, this is sane. */ 1189 if (num == 1 && points != NULL && scalars != NULL) 1190 return EC_POINT_mul(group, r, scalar, points[0], scalars[0], 1191 ctx); 1192 1193 /* aG, this is sane */ 1194 if (scalar != NULL && points == NULL && scalars == NULL) 1195 return EC_POINT_mul(group, r, scalar, NULL, NULL, ctx); 1196 1197 /* anything else is an error */ 1198 ECerror(ERR_R_EC_LIB); 1199 return 0; 1200 } 1201 1202 int 1203 EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 1204 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) 1205 { 1206 if (group->meth->mul_generator_ct == NULL || 1207 group->meth->mul_single_ct == NULL || 1208 group->meth->mul_double_nonct == NULL) { 1209 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1210 return 0; 1211 } 1212 if (g_scalar != NULL && point == NULL && p_scalar == NULL) { 1213 /* 1214 * In this case we want to compute g_scalar * GeneratorPoint: 1215 * this codepath is reached most prominently by (ephemeral) key 1216 * generation of EC cryptosystems (i.e. ECDSA keygen and sign 1217 * setup, ECDH keygen/first half), where the scalar is always 1218 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually 1219 * set and we always call the constant time version. 1220 */ 1221 return group->meth->mul_generator_ct(group, r, g_scalar, ctx); 1222 } 1223 if (g_scalar == NULL && point != NULL && p_scalar != NULL) { 1224 /* In this case we want to compute p_scalar * GenericPoint: 1225 * this codepath is reached most prominently by the second half 1226 * of ECDH, where the secret scalar is multiplied by the peer's 1227 * public point. To protect the secret scalar, we ignore if 1228 * BN_FLG_CONSTTIME is actually set and we always call the 1229 * constant time version. 1230 */ 1231 return group->meth->mul_single_ct(group, r, p_scalar, point, 1232 ctx); 1233 } 1234 if (g_scalar != NULL && point != NULL && p_scalar != NULL) { 1235 /* 1236 * In this case we want to compute 1237 * g_scalar * GeneratorPoint + p_scalar * GenericPoint: 1238 * this codepath is reached most prominently by ECDSA signature 1239 * verification. So we call the non-ct version. 1240 */ 1241 return group->meth->mul_double_nonct(group, r, g_scalar, 1242 p_scalar, point, ctx); 1243 } 1244 1245 /* Anything else is an error. */ 1246 ECerror(ERR_R_EC_LIB); 1247 return 0; 1248 } 1249 1250 int 1251 EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx) 1252 { 1253 if (group->meth->precompute_mult != 0) 1254 return group->meth->precompute_mult(group, ctx); 1255 else 1256 return 1; /* nothing to do, so report success */ 1257 } 1258 1259 int 1260 EC_GROUP_have_precompute_mult(const EC_GROUP * group) 1261 { 1262 if (group->meth->have_precompute_mult != 0) 1263 return group->meth->have_precompute_mult(group); 1264 else 1265 return 0; /* cannot tell whether precomputation has 1266 * been performed */ 1267 } 1268 1269 int 1270 ec_group_simple_order_bits(const EC_GROUP *group) 1271 { 1272 /* XXX change group->order to a pointer? */ 1273 #if 0 1274 if (group->order == NULL) 1275 return 0; 1276 #endif 1277 return BN_num_bits(&group->order); 1278 } 1279 1280 EC_KEY * 1281 ECParameters_dup(EC_KEY *key) 1282 { 1283 unsigned char *p = NULL; 1284 EC_KEY *k = NULL; 1285 int len; 1286 1287 if (key == NULL) 1288 return (NULL); 1289 1290 if ((len = i2d_ECParameters(key, &p)) > 0) 1291 k = d2i_ECParameters(NULL, (const unsigned char **)&p, len); 1292 1293 return (k); 1294 } 1295