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