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