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