1/* 2 * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved 4 * 5 * Licensed under the OpenSSL license (the "License"). You may not use 6 * this file except in compliance with the License. You can obtain a copy 7 * in the file LICENSE in the source distribution or at 8 * https://www.openssl.org/source/license.html 9 */ 10 11#include <string.h> 12 13#include <openssl/err.h> 14#include <openssl/opensslv.h> 15 16#include "ec_local.h" 17 18/* functions for EC_GROUP objects */ 19 20EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) 21{ 22 EC_GROUP *ret; 23 24 if (meth == NULL) { 25 ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL); 26 return NULL; 27 } 28 if (meth->group_init == 0) { 29 ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 30 return NULL; 31 } 32 33 ret = OPENSSL_zalloc(sizeof(*ret)); 34 if (ret == NULL) { 35 ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); 36 return NULL; 37 } 38 39 ret->meth = meth; 40 if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { 41 ret->order = BN_new(); 42 if (ret->order == NULL) 43 goto err; 44 ret->cofactor = BN_new(); 45 if (ret->cofactor == NULL) 46 goto err; 47 } 48 ret->asn1_flag = OPENSSL_EC_NAMED_CURVE; 49 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; 50 if (!meth->group_init(ret)) 51 goto err; 52 return ret; 53 54 err: 55 BN_free(ret->order); 56 BN_free(ret->cofactor); 57 OPENSSL_free(ret); 58 return NULL; 59} 60 61void EC_pre_comp_free(EC_GROUP *group) 62{ 63 switch (group->pre_comp_type) { 64 case PCT_none: 65 break; 66 case PCT_nistz256: 67#ifdef ECP_NISTZ256_ASM 68 EC_nistz256_pre_comp_free(group->pre_comp.nistz256); 69#endif 70 break; 71#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 72 case PCT_nistp224: 73 EC_nistp224_pre_comp_free(group->pre_comp.nistp224); 74 break; 75 case PCT_nistp256: 76 EC_nistp256_pre_comp_free(group->pre_comp.nistp256); 77 break; 78 case PCT_nistp521: 79 EC_nistp521_pre_comp_free(group->pre_comp.nistp521); 80 break; 81#else 82 case PCT_nistp224: 83 case PCT_nistp256: 84 case PCT_nistp521: 85 break; 86#endif 87 case PCT_ec: 88 EC_ec_pre_comp_free(group->pre_comp.ec); 89 break; 90 } 91 group->pre_comp.ec = NULL; 92} 93 94void EC_GROUP_free(EC_GROUP *group) 95{ 96 if (!group) 97 return; 98 99 if (group->meth->group_finish != 0) 100 group->meth->group_finish(group); 101 102 EC_pre_comp_free(group); 103 BN_MONT_CTX_free(group->mont_data); 104 EC_POINT_free(group->generator); 105 BN_free(group->order); 106 BN_free(group->cofactor); 107 OPENSSL_free(group->seed); 108 OPENSSL_free(group); 109} 110 111void EC_GROUP_clear_free(EC_GROUP *group) 112{ 113 if (!group) 114 return; 115 116 if (group->meth->group_clear_finish != 0) 117 group->meth->group_clear_finish(group); 118 else if (group->meth->group_finish != 0) 119 group->meth->group_finish(group); 120 121 EC_pre_comp_free(group); 122 BN_MONT_CTX_free(group->mont_data); 123 EC_POINT_clear_free(group->generator); 124 BN_clear_free(group->order); 125 BN_clear_free(group->cofactor); 126 OPENSSL_clear_free(group->seed, group->seed_len); 127 OPENSSL_clear_free(group, sizeof(*group)); 128} 129 130int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) 131{ 132 if (dest->meth->group_copy == 0) { 133 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 134 return 0; 135 } 136 if (dest->meth != src->meth) { 137 ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); 138 return 0; 139 } 140 if (dest == src) 141 return 1; 142 143 dest->curve_name = src->curve_name; 144 145 /* Copy precomputed */ 146 dest->pre_comp_type = src->pre_comp_type; 147 switch (src->pre_comp_type) { 148 case PCT_none: 149 dest->pre_comp.ec = NULL; 150 break; 151 case PCT_nistz256: 152#ifdef ECP_NISTZ256_ASM 153 dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256); 154#endif 155 break; 156#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 157 case PCT_nistp224: 158 dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224); 159 break; 160 case PCT_nistp256: 161 dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256); 162 break; 163 case PCT_nistp521: 164 dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521); 165 break; 166#else 167 case PCT_nistp224: 168 case PCT_nistp256: 169 case PCT_nistp521: 170 break; 171#endif 172 case PCT_ec: 173 dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec); 174 break; 175 } 176 177 if (src->mont_data != NULL) { 178 if (dest->mont_data == NULL) { 179 dest->mont_data = BN_MONT_CTX_new(); 180 if (dest->mont_data == NULL) 181 return 0; 182 } 183 if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) 184 return 0; 185 } else { 186 /* src->generator == NULL */ 187 BN_MONT_CTX_free(dest->mont_data); 188 dest->mont_data = NULL; 189 } 190 191 if (src->generator != NULL) { 192 if (dest->generator == NULL) { 193 dest->generator = EC_POINT_new(dest); 194 if (dest->generator == NULL) 195 return 0; 196 } 197 if (!EC_POINT_copy(dest->generator, src->generator)) 198 return 0; 199 } else { 200 /* src->generator == NULL */ 201 EC_POINT_clear_free(dest->generator); 202 dest->generator = NULL; 203 } 204 205 if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { 206 if (!BN_copy(dest->order, src->order)) 207 return 0; 208 if (!BN_copy(dest->cofactor, src->cofactor)) 209 return 0; 210 } 211 212 dest->asn1_flag = src->asn1_flag; 213 dest->asn1_form = src->asn1_form; 214 dest->decoded_from_explicit_params = src->decoded_from_explicit_params; 215 216 if (src->seed) { 217 OPENSSL_free(dest->seed); 218 if ((dest->seed = OPENSSL_malloc(src->seed_len)) == NULL) { 219 ECerr(EC_F_EC_GROUP_COPY, ERR_R_MALLOC_FAILURE); 220 return 0; 221 } 222 if (!memcpy(dest->seed, src->seed, src->seed_len)) 223 return 0; 224 dest->seed_len = src->seed_len; 225 } else { 226 OPENSSL_free(dest->seed); 227 dest->seed = NULL; 228 dest->seed_len = 0; 229 } 230 231 return dest->meth->group_copy(dest, src); 232} 233 234EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) 235{ 236 EC_GROUP *t = NULL; 237 int ok = 0; 238 239 if (a == NULL) 240 return NULL; 241 242 if ((t = EC_GROUP_new(a->meth)) == NULL) 243 return NULL; 244 if (!EC_GROUP_copy(t, a)) 245 goto err; 246 247 ok = 1; 248 249 err: 250 if (!ok) { 251 EC_GROUP_free(t); 252 return NULL; 253 } 254 return t; 255} 256 257const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) 258{ 259 return group->meth; 260} 261 262int EC_METHOD_get_field_type(const EC_METHOD *meth) 263{ 264 return meth->field_type; 265} 266 267static int ec_precompute_mont_data(EC_GROUP *); 268 269/*- 270 * Try computing cofactor from the generator order (n) and field cardinality (q). 271 * This works for all curves of cryptographic interest. 272 * 273 * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q) 274 * h_min = (q + 1 - 2*sqrt(q))/n 275 * h_max = (q + 1 + 2*sqrt(q))/n 276 * h_max - h_min = 4*sqrt(q)/n 277 * So if n > 4*sqrt(q) holds, there is only one possible value for h: 278 * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil 279 * 280 * Otherwise, zero cofactor and return success. 281 */ 282static int ec_guess_cofactor(EC_GROUP *group) { 283 int ret = 0; 284 BN_CTX *ctx = NULL; 285 BIGNUM *q = NULL; 286 287 /*- 288 * If the cofactor is too large, we cannot guess it. 289 * The RHS of below is a strict overestimate of lg(4 * sqrt(q)) 290 */ 291 if (BN_num_bits(group->order) <= (BN_num_bits(group->field) + 1) / 2 + 3) { 292 /* default to 0 */ 293 BN_zero(group->cofactor); 294 /* return success */ 295 return 1; 296 } 297 298 if ((ctx = BN_CTX_new()) == NULL) 299 return 0; 300 301 BN_CTX_start(ctx); 302 if ((q = BN_CTX_get(ctx)) == NULL) 303 goto err; 304 305 /* set q = 2**m for binary fields; q = p otherwise */ 306 if (group->meth->field_type == NID_X9_62_characteristic_two_field) { 307 BN_zero(q); 308 if (!BN_set_bit(q, BN_num_bits(group->field) - 1)) 309 goto err; 310 } else { 311 if (!BN_copy(q, group->field)) 312 goto err; 313 } 314 315 /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */ 316 if (!BN_rshift1(group->cofactor, group->order) /* n/2 */ 317 || !BN_add(group->cofactor, group->cofactor, q) /* q + n/2 */ 318 /* q + 1 + n/2 */ 319 || !BN_add(group->cofactor, group->cofactor, BN_value_one()) 320 /* (q + 1 + n/2)/n */ 321 || !BN_div(group->cofactor, NULL, group->cofactor, group->order, ctx)) 322 goto err; 323 ret = 1; 324 err: 325 BN_CTX_end(ctx); 326 BN_CTX_free(ctx); 327 return ret; 328} 329 330int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 331 const BIGNUM *order, const BIGNUM *cofactor) 332{ 333 if (generator == NULL) { 334 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); 335 return 0; 336 } 337 338 /* require group->field >= 1 */ 339 if (group->field == NULL || BN_is_zero(group->field) 340 || BN_is_negative(group->field)) { 341 ECerr(EC_F_EC_GROUP_SET_GENERATOR, EC_R_INVALID_FIELD); 342 return 0; 343 } 344 345 /*- 346 * - require order >= 1 347 * - enforce upper bound due to Hasse thm: order can be no more than one bit 348 * longer than field cardinality 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 ECerr(EC_F_EC_GROUP_SET_GENERATOR, 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 lib uses 0 cofactor as a marker for "unknown cofactor". 359 * So accept cofactor == NULL or cofactor >= 0. 360 */ 361 if (cofactor != NULL && BN_is_negative(cofactor)) { 362 ECerr(EC_F_EC_GROUP_SET_GENERATOR, 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 BN_zero(group->cofactor); 383 return 0; 384 } 385 386 /* 387 * Some groups have an order with 388 * factors of two, which makes the Montgomery setup fail. 389 * |group->mont_data| will be NULL in this case. 390 */ 391 if (BN_is_odd(group->order)) { 392 return ec_precompute_mont_data(group); 393 } 394 395 BN_MONT_CTX_free(group->mont_data); 396 group->mont_data = NULL; 397 return 1; 398} 399 400const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) 401{ 402 return group->generator; 403} 404 405BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) 406{ 407 return group->mont_data; 408} 409 410int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) 411{ 412 if (group->order == NULL) 413 return 0; 414 if (!BN_copy(order, group->order)) 415 return 0; 416 417 return !BN_is_zero(order); 418} 419 420const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) 421{ 422 return group->order; 423} 424 425int EC_GROUP_order_bits(const EC_GROUP *group) 426{ 427 return group->meth->group_order_bits(group); 428} 429 430int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, 431 BN_CTX *ctx) 432{ 433 434 if (group->cofactor == NULL) 435 return 0; 436 if (!BN_copy(cofactor, group->cofactor)) 437 return 0; 438 439 return !BN_is_zero(group->cofactor); 440} 441 442const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group) 443{ 444 return group->cofactor; 445} 446 447void EC_GROUP_set_curve_name(EC_GROUP *group, int nid) 448{ 449 group->curve_name = nid; 450} 451 452int EC_GROUP_get_curve_name(const EC_GROUP *group) 453{ 454 return group->curve_name; 455} 456 457void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) 458{ 459 group->asn1_flag = flag; 460} 461 462int EC_GROUP_get_asn1_flag(const EC_GROUP *group) 463{ 464 return group->asn1_flag; 465} 466 467void EC_GROUP_set_point_conversion_form(EC_GROUP *group, 468 point_conversion_form_t form) 469{ 470 group->asn1_form = form; 471} 472 473point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP 474 *group) 475{ 476 return group->asn1_form; 477} 478 479size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) 480{ 481 OPENSSL_free(group->seed); 482 group->seed = NULL; 483 group->seed_len = 0; 484 485 if (!len || !p) 486 return 1; 487 488 if ((group->seed = OPENSSL_malloc(len)) == NULL) { 489 ECerr(EC_F_EC_GROUP_SET_SEED, ERR_R_MALLOC_FAILURE); 490 return 0; 491 } 492 memcpy(group->seed, p, len); 493 group->seed_len = len; 494 495 return len; 496} 497 498unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group) 499{ 500 return group->seed; 501} 502 503size_t EC_GROUP_get_seed_len(const EC_GROUP *group) 504{ 505 return group->seed_len; 506} 507 508int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 509 const BIGNUM *b, BN_CTX *ctx) 510{ 511 if (group->meth->group_set_curve == 0) { 512 ECerr(EC_F_EC_GROUP_SET_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 513 return 0; 514 } 515 return group->meth->group_set_curve(group, p, a, b, ctx); 516} 517 518int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, 519 BN_CTX *ctx) 520{ 521 if (group->meth->group_get_curve == NULL) { 522 ECerr(EC_F_EC_GROUP_GET_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 523 return 0; 524 } 525 return group->meth->group_get_curve(group, p, a, b, ctx); 526} 527 528#if OPENSSL_API_COMPAT < 0x10200000L 529int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 530 const BIGNUM *b, BN_CTX *ctx) 531{ 532 return EC_GROUP_set_curve(group, p, a, b, ctx); 533} 534 535int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, 536 BIGNUM *b, BN_CTX *ctx) 537{ 538 return EC_GROUP_get_curve(group, p, a, b, ctx); 539} 540 541# ifndef OPENSSL_NO_EC2M 542int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 543 const BIGNUM *b, BN_CTX *ctx) 544{ 545 return EC_GROUP_set_curve(group, p, a, b, ctx); 546} 547 548int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, 549 BIGNUM *b, BN_CTX *ctx) 550{ 551 return EC_GROUP_get_curve(group, p, a, b, ctx); 552} 553# endif 554#endif 555 556int EC_GROUP_get_degree(const EC_GROUP *group) 557{ 558 if (group->meth->group_get_degree == 0) { 559 ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 560 return 0; 561 } 562 return group->meth->group_get_degree(group); 563} 564 565int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 566{ 567 if (group->meth->group_check_discriminant == 0) { 568 ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, 569 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 570 return 0; 571 } 572 return group->meth->group_check_discriminant(group, ctx); 573} 574 575int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) 576{ 577 int r = 0; 578 BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; 579 BN_CTX *ctx_new = NULL; 580 581 /* compare the field types */ 582 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != 583 EC_METHOD_get_field_type(EC_GROUP_method_of(b))) 584 return 1; 585 /* compare the curve name (if present in both) */ 586 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && 587 EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) 588 return 1; 589 if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE) 590 return 0; 591 592 if (ctx == NULL) 593 ctx_new = ctx = BN_CTX_new(); 594 if (ctx == NULL) 595 return -1; 596 597 BN_CTX_start(ctx); 598 a1 = BN_CTX_get(ctx); 599 a2 = BN_CTX_get(ctx); 600 a3 = BN_CTX_get(ctx); 601 b1 = BN_CTX_get(ctx); 602 b2 = BN_CTX_get(ctx); 603 b3 = BN_CTX_get(ctx); 604 if (b3 == NULL) { 605 BN_CTX_end(ctx); 606 BN_CTX_free(ctx_new); 607 return -1; 608 } 609 610 /* 611 * XXX This approach assumes that the external representation of curves 612 * over the same field type is the same. 613 */ 614 if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || 615 !b->meth->group_get_curve(b, b1, b2, b3, ctx)) 616 r = 1; 617 618 if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) 619 r = 1; 620 621 /* XXX EC_POINT_cmp() assumes that the methods are equal */ 622 if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), 623 EC_GROUP_get0_generator(b), ctx)) 624 r = 1; 625 626 if (!r) { 627 const BIGNUM *ao, *bo, *ac, *bc; 628 /* compare the order and cofactor */ 629 ao = EC_GROUP_get0_order(a); 630 bo = EC_GROUP_get0_order(b); 631 ac = EC_GROUP_get0_cofactor(a); 632 bc = EC_GROUP_get0_cofactor(b); 633 if (ao == NULL || bo == NULL) { 634 BN_CTX_end(ctx); 635 BN_CTX_free(ctx_new); 636 return -1; 637 } 638 if (BN_cmp(ao, bo) || BN_cmp(ac, bc)) 639 r = 1; 640 } 641 642 BN_CTX_end(ctx); 643 BN_CTX_free(ctx_new); 644 645 return r; 646} 647 648/* functions for EC_POINT objects */ 649 650EC_POINT *EC_POINT_new(const EC_GROUP *group) 651{ 652 EC_POINT *ret; 653 654 if (group == NULL) { 655 ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); 656 return NULL; 657 } 658 if (group->meth->point_init == NULL) { 659 ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 660 return NULL; 661 } 662 663 ret = OPENSSL_zalloc(sizeof(*ret)); 664 if (ret == NULL) { 665 ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); 666 return NULL; 667 } 668 669 ret->meth = group->meth; 670 ret->curve_name = group->curve_name; 671 672 if (!ret->meth->point_init(ret)) { 673 OPENSSL_free(ret); 674 return NULL; 675 } 676 677 return ret; 678} 679 680void EC_POINT_free(EC_POINT *point) 681{ 682 if (!point) 683 return; 684 685 if (point->meth->point_finish != 0) 686 point->meth->point_finish(point); 687 OPENSSL_free(point); 688} 689 690void EC_POINT_clear_free(EC_POINT *point) 691{ 692 if (!point) 693 return; 694 695 if (point->meth->point_clear_finish != 0) 696 point->meth->point_clear_finish(point); 697 else if (point->meth->point_finish != 0) 698 point->meth->point_finish(point); 699 OPENSSL_clear_free(point, sizeof(*point)); 700} 701 702int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) 703{ 704 if (dest->meth->point_copy == 0) { 705 ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 706 return 0; 707 } 708 if (dest->meth != src->meth 709 || (dest->curve_name != src->curve_name 710 && dest->curve_name != 0 711 && src->curve_name != 0)) { 712 ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); 713 return 0; 714 } 715 if (dest == src) 716 return 1; 717 return dest->meth->point_copy(dest, src); 718} 719 720EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) 721{ 722 EC_POINT *t; 723 int r; 724 725 if (a == NULL) 726 return NULL; 727 728 t = EC_POINT_new(group); 729 if (t == NULL) 730 return NULL; 731 r = EC_POINT_copy(t, a); 732 if (!r) { 733 EC_POINT_free(t); 734 return NULL; 735 } 736 return t; 737} 738 739const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) 740{ 741 return point->meth; 742} 743 744int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 745{ 746 if (group->meth->point_set_to_infinity == 0) { 747 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, 748 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 749 return 0; 750 } 751 if (group->meth != point->meth) { 752 ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); 753 return 0; 754 } 755 return group->meth->point_set_to_infinity(group, point); 756} 757 758int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, 759 EC_POINT *point, const BIGNUM *x, 760 const BIGNUM *y, const BIGNUM *z, 761 BN_CTX *ctx) 762{ 763 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { 764 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 765 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 766 return 0; 767 } 768 if (!ec_point_is_compat(point, group)) { 769 ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 770 EC_R_INCOMPATIBLE_OBJECTS); 771 return 0; 772 } 773 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, 774 y, z, ctx); 775} 776 777int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, 778 const EC_POINT *point, BIGNUM *x, 779 BIGNUM *y, BIGNUM *z, 780 BN_CTX *ctx) 781{ 782 if (group->meth->point_get_Jprojective_coordinates_GFp == 0) { 783 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 784 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 785 return 0; 786 } 787 if (!ec_point_is_compat(point, group)) { 788 ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 789 EC_R_INCOMPATIBLE_OBJECTS); 790 return 0; 791 } 792 return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, 793 y, z, ctx); 794} 795 796int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 797 const BIGNUM *x, const BIGNUM *y, 798 BN_CTX *ctx) 799{ 800 if (group->meth->point_set_affine_coordinates == NULL) { 801 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES, 802 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 803 return 0; 804 } 805 if (!ec_point_is_compat(point, group)) { 806 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES, EC_R_INCOMPATIBLE_OBJECTS); 807 return 0; 808 } 809 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx)) 810 return 0; 811 812 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 813 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES, EC_R_POINT_IS_NOT_ON_CURVE); 814 return 0; 815 } 816 return 1; 817} 818 819#if OPENSSL_API_COMPAT < 0x10200000L 820int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, 821 EC_POINT *point, const BIGNUM *x, 822 const BIGNUM *y, BN_CTX *ctx) 823{ 824 return EC_POINT_set_affine_coordinates(group, point, x, y, ctx); 825} 826 827# ifndef OPENSSL_NO_EC2M 828int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, 829 EC_POINT *point, const BIGNUM *x, 830 const BIGNUM *y, BN_CTX *ctx) 831{ 832 return EC_POINT_set_affine_coordinates(group, point, x, y, ctx); 833} 834# endif 835#endif 836 837int EC_POINT_get_affine_coordinates(const EC_GROUP *group, 838 const EC_POINT *point, BIGNUM *x, BIGNUM *y, 839 BN_CTX *ctx) 840{ 841 if (group->meth->point_get_affine_coordinates == NULL) { 842 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES, 843 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 844 return 0; 845 } 846 if (!ec_point_is_compat(point, group)) { 847 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES, EC_R_INCOMPATIBLE_OBJECTS); 848 return 0; 849 } 850 if (EC_POINT_is_at_infinity(group, point)) { 851 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY); 852 return 0; 853 } 854 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 855} 856 857#if OPENSSL_API_COMPAT < 0x10200000L 858int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, 859 const EC_POINT *point, BIGNUM *x, 860 BIGNUM *y, BN_CTX *ctx) 861{ 862 return EC_POINT_get_affine_coordinates(group, point, x, y, ctx); 863} 864 865# ifndef OPENSSL_NO_EC2M 866int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, 867 const EC_POINT *point, BIGNUM *x, 868 BIGNUM *y, BN_CTX *ctx) 869{ 870 return EC_POINT_get_affine_coordinates(group, point, x, y, ctx); 871} 872# endif 873#endif 874 875int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 876 const EC_POINT *b, BN_CTX *ctx) 877{ 878 if (group->meth->add == 0) { 879 ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 880 return 0; 881 } 882 if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group) 883 || !ec_point_is_compat(b, group)) { 884 ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); 885 return 0; 886 } 887 return group->meth->add(group, r, a, b, ctx); 888} 889 890int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 891 BN_CTX *ctx) 892{ 893 if (group->meth->dbl == 0) { 894 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 895 return 0; 896 } 897 if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group)) { 898 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); 899 return 0; 900 } 901 return group->meth->dbl(group, r, a, ctx); 902} 903 904int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) 905{ 906 if (group->meth->invert == 0) { 907 ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 908 return 0; 909 } 910 if (!ec_point_is_compat(a, group)) { 911 ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); 912 return 0; 913 } 914 return group->meth->invert(group, a, ctx); 915} 916 917int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 918{ 919 if (group->meth->is_at_infinity == 0) { 920 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, 921 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 922 return 0; 923 } 924 if (!ec_point_is_compat(point, group)) { 925 ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); 926 return 0; 927 } 928 return group->meth->is_at_infinity(group, point); 929} 930 931/* 932 * Check whether an EC_POINT is on the curve or not. Note that the return 933 * value for this function should NOT be treated as a boolean. Return values: 934 * 1: The point is on the curve 935 * 0: The point is not on the curve 936 * -1: An error occurred 937 */ 938int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, 939 BN_CTX *ctx) 940{ 941 if (group->meth->is_on_curve == 0) { 942 ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 943 return 0; 944 } 945 if (!ec_point_is_compat(point, group)) { 946 ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); 947 return 0; 948 } 949 return group->meth->is_on_curve(group, point, ctx); 950} 951 952int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 953 BN_CTX *ctx) 954{ 955 if (group->meth->point_cmp == 0) { 956 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 957 return -1; 958 } 959 if (!ec_point_is_compat(a, group) || !ec_point_is_compat(b, group)) { 960 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); 961 return -1; 962 } 963 return group->meth->point_cmp(group, a, b, ctx); 964} 965 966int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 967{ 968 if (group->meth->make_affine == 0) { 969 ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 970 return 0; 971 } 972 if (!ec_point_is_compat(point, group)) { 973 ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); 974 return 0; 975 } 976 return group->meth->make_affine(group, point, ctx); 977} 978 979int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, 980 EC_POINT *points[], BN_CTX *ctx) 981{ 982 size_t i; 983 984 if (group->meth->points_make_affine == 0) { 985 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 986 return 0; 987 } 988 for (i = 0; i < num; i++) { 989 if (!ec_point_is_compat(points[i], group)) { 990 ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); 991 return 0; 992 } 993 } 994 return group->meth->points_make_affine(group, num, points, ctx); 995} 996 997/* 998 * Functions for point multiplication. If group->meth->mul is 0, we use the 999 * wNAF-based implementations in ec_mult.c; otherwise we dispatch through 1000 * methods. 1001 */ 1002 1003int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 1004 size_t num, const EC_POINT *points[], 1005 const BIGNUM *scalars[], BN_CTX *ctx) 1006{ 1007 int ret = 0; 1008 size_t i = 0; 1009 BN_CTX *new_ctx = NULL; 1010 1011 if (!ec_point_is_compat(r, group)) { 1012 ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); 1013 return 0; 1014 } 1015 1016 if (scalar == NULL && num == 0) 1017 return EC_POINT_set_to_infinity(group, r); 1018 1019 for (i = 0; i < num; i++) { 1020 if (!ec_point_is_compat(points[i], group)) { 1021 ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); 1022 return 0; 1023 } 1024 } 1025 1026 if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) { 1027 ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR); 1028 return 0; 1029 } 1030 1031 if (group->meth->mul != NULL) 1032 ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx); 1033 else 1034 /* use default */ 1035 ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); 1036 1037 BN_CTX_free(new_ctx); 1038 return ret; 1039} 1040 1041int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 1042 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) 1043{ 1044 /* just a convenient interface to EC_POINTs_mul() */ 1045 1046 const EC_POINT *points[1]; 1047 const BIGNUM *scalars[1]; 1048 1049 points[0] = point; 1050 scalars[0] = p_scalar; 1051 1052 return EC_POINTs_mul(group, r, g_scalar, 1053 (point != NULL 1054 && p_scalar != NULL), points, scalars, ctx); 1055} 1056 1057int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 1058{ 1059 if (group->meth->mul == 0) 1060 /* use default */ 1061 return ec_wNAF_precompute_mult(group, ctx); 1062 1063 if (group->meth->precompute_mult != 0) 1064 return group->meth->precompute_mult(group, ctx); 1065 else 1066 return 1; /* nothing to do, so report success */ 1067} 1068 1069int EC_GROUP_have_precompute_mult(const EC_GROUP *group) 1070{ 1071 if (group->meth->mul == 0) 1072 /* use default */ 1073 return ec_wNAF_have_precompute_mult(group); 1074 1075 if (group->meth->have_precompute_mult != 0) 1076 return group->meth->have_precompute_mult(group); 1077 else 1078 return 0; /* cannot tell whether precomputation has 1079 * been performed */ 1080} 1081 1082/* 1083 * ec_precompute_mont_data sets |group->mont_data| from |group->order| and 1084 * returns one on success. On error it returns zero. 1085 */ 1086static int ec_precompute_mont_data(EC_GROUP *group) 1087{ 1088 BN_CTX *ctx = BN_CTX_new(); 1089 int ret = 0; 1090 1091 BN_MONT_CTX_free(group->mont_data); 1092 group->mont_data = NULL; 1093 1094 if (ctx == NULL) 1095 goto err; 1096 1097 group->mont_data = BN_MONT_CTX_new(); 1098 if (group->mont_data == NULL) 1099 goto err; 1100 1101 if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) { 1102 BN_MONT_CTX_free(group->mont_data); 1103 group->mont_data = NULL; 1104 goto err; 1105 } 1106 1107 ret = 1; 1108 1109 err: 1110 1111 BN_CTX_free(ctx); 1112 return ret; 1113} 1114 1115int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg) 1116{ 1117 return CRYPTO_set_ex_data(&key->ex_data, idx, arg); 1118} 1119 1120void *EC_KEY_get_ex_data(const EC_KEY *key, int idx) 1121{ 1122 return CRYPTO_get_ex_data(&key->ex_data, idx); 1123} 1124 1125int ec_group_simple_order_bits(const EC_GROUP *group) 1126{ 1127 if (group->order == NULL) 1128 return 0; 1129 return BN_num_bits(group->order); 1130} 1131 1132static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r, 1133 const BIGNUM *x, BN_CTX *ctx) 1134{ 1135 BIGNUM *e = NULL; 1136 BN_CTX *new_ctx = NULL; 1137 int ret = 0; 1138 1139 if (group->mont_data == NULL) 1140 return 0; 1141 1142 if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) 1143 return 0; 1144 1145 BN_CTX_start(ctx); 1146 if ((e = BN_CTX_get(ctx)) == NULL) 1147 goto err; 1148 1149 /*- 1150 * We want inverse in constant time, therefore we utilize the fact 1151 * order must be prime and use Fermats Little Theorem instead. 1152 */ 1153 if (!BN_set_word(e, 2)) 1154 goto err; 1155 if (!BN_sub(e, group->order, e)) 1156 goto err; 1157 /*- 1158 * Exponent e is public. 1159 * No need for scatter-gather or BN_FLG_CONSTTIME. 1160 */ 1161 if (!BN_mod_exp_mont(r, x, e, group->order, ctx, group->mont_data)) 1162 goto err; 1163 1164 ret = 1; 1165 1166 err: 1167 BN_CTX_end(ctx); 1168 BN_CTX_free(new_ctx); 1169 return ret; 1170} 1171 1172/*- 1173 * Default behavior, if group->meth->field_inverse_mod_ord is NULL: 1174 * - When group->order is even, this function returns an error. 1175 * - When group->order is otherwise composite, the correctness 1176 * of the output is not guaranteed. 1177 * - When x is outside the range [1, group->order), the correctness 1178 * of the output is not guaranteed. 1179 * - Otherwise, this function returns the multiplicative inverse in the 1180 * range [1, group->order). 1181 * 1182 * EC_METHODs must implement their own field_inverse_mod_ord for 1183 * other functionality. 1184 */ 1185int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, 1186 const BIGNUM *x, BN_CTX *ctx) 1187{ 1188 if (group->meth->field_inverse_mod_ord != NULL) 1189 return group->meth->field_inverse_mod_ord(group, res, x, ctx); 1190 else 1191 return ec_field_inverse_mod_ord(group, res, x, ctx); 1192} 1193 1194/*- 1195 * Coordinate blinding for EC_POINT. 1196 * 1197 * The underlying EC_METHOD can optionally implement this function: 1198 * underlying implementations should return 0 on errors, or 1 on 1199 * success. 1200 * 1201 * This wrapper returns 1 in case the underlying EC_METHOD does not 1202 * support coordinate blinding. 1203 */ 1204int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) 1205{ 1206 if (group->meth->blind_coordinates == NULL) 1207 return 1; /* ignore if not implemented */ 1208 1209 return group->meth->blind_coordinates(group, p, ctx); 1210} 1211