1 /* 2 * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved 4 * 5 * Licensed under the Apache License 2.0 (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 /* 12 * EC_GROUP low level APIs are deprecated for public use, but still ok for 13 * internal use. 14 */ 15 #include "internal/deprecated.h" 16 17 #include <string.h> 18 #include <openssl/params.h> 19 #include <openssl/core_names.h> 20 #include <openssl/err.h> 21 #include <openssl/opensslv.h> 22 #include <openssl/param_build.h> 23 #include "crypto/ec.h" 24 #include "crypto/bn.h" 25 #include "internal/nelem.h" 26 #include "ec_local.h" 27 28 /* functions for EC_GROUP objects */ 29 30 EC_GROUP *ossl_ec_group_new_ex(OSSL_LIB_CTX *libctx, const char *propq, 31 const EC_METHOD *meth) 32 { 33 EC_GROUP *ret; 34 35 if (meth == NULL) { 36 ERR_raise(ERR_LIB_EC, EC_R_SLOT_FULL); 37 return NULL; 38 } 39 if (meth->group_init == 0) { 40 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 41 return NULL; 42 } 43 44 ret = OPENSSL_zalloc(sizeof(*ret)); 45 if (ret == NULL) 46 return NULL; 47 48 ret->libctx = libctx; 49 if (propq != NULL) { 50 ret->propq = OPENSSL_strdup(propq); 51 if (ret->propq == NULL) 52 goto err; 53 } 54 ret->meth = meth; 55 if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { 56 ret->order = BN_new(); 57 if (ret->order == NULL) 58 goto err; 59 ret->cofactor = BN_new(); 60 if (ret->cofactor == NULL) 61 goto err; 62 } 63 ret->asn1_flag = OPENSSL_EC_EXPLICIT_CURVE; 64 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; 65 if (!meth->group_init(ret)) 66 goto err; 67 return ret; 68 69 err: 70 BN_free(ret->order); 71 BN_free(ret->cofactor); 72 OPENSSL_free(ret->propq); 73 OPENSSL_free(ret); 74 return NULL; 75 } 76 77 #ifndef OPENSSL_NO_DEPRECATED_3_0 78 #ifndef FIPS_MODULE 79 EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) 80 { 81 return ossl_ec_group_new_ex(NULL, NULL, meth); 82 } 83 #endif 84 #endif 85 86 void EC_pre_comp_free(EC_GROUP *group) 87 { 88 switch (group->pre_comp_type) { 89 case PCT_none: 90 break; 91 case PCT_nistz256: 92 #ifdef ECP_NISTZ256_ASM 93 EC_nistz256_pre_comp_free(group->pre_comp.nistz256); 94 #endif 95 break; 96 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 97 case PCT_nistp224: 98 EC_nistp224_pre_comp_free(group->pre_comp.nistp224); 99 break; 100 case PCT_nistp256: 101 EC_nistp256_pre_comp_free(group->pre_comp.nistp256); 102 break; 103 case PCT_nistp384: 104 ossl_ec_nistp384_pre_comp_free(group->pre_comp.nistp384); 105 break; 106 case PCT_nistp521: 107 EC_nistp521_pre_comp_free(group->pre_comp.nistp521); 108 break; 109 #else 110 case PCT_nistp224: 111 case PCT_nistp256: 112 case PCT_nistp384: 113 case PCT_nistp521: 114 break; 115 #endif 116 case PCT_ec: 117 EC_ec_pre_comp_free(group->pre_comp.ec); 118 break; 119 } 120 group->pre_comp.ec = NULL; 121 } 122 123 void EC_GROUP_free(EC_GROUP *group) 124 { 125 if (!group) 126 return; 127 128 if (group->meth->group_finish != 0) 129 group->meth->group_finish(group); 130 131 EC_pre_comp_free(group); 132 BN_MONT_CTX_free(group->mont_data); 133 EC_POINT_free(group->generator); 134 BN_free(group->order); 135 BN_free(group->cofactor); 136 OPENSSL_free(group->seed); 137 OPENSSL_free(group->propq); 138 OPENSSL_free(group); 139 } 140 141 #ifndef OPENSSL_NO_DEPRECATED_3_0 142 void EC_GROUP_clear_free(EC_GROUP *group) 143 { 144 if (!group) 145 return; 146 147 if (group->meth->group_clear_finish != 0) 148 group->meth->group_clear_finish(group); 149 else if (group->meth->group_finish != 0) 150 group->meth->group_finish(group); 151 152 EC_pre_comp_free(group); 153 BN_MONT_CTX_free(group->mont_data); 154 EC_POINT_clear_free(group->generator); 155 BN_clear_free(group->order); 156 BN_clear_free(group->cofactor); 157 OPENSSL_clear_free(group->seed, group->seed_len); 158 OPENSSL_clear_free(group, sizeof(*group)); 159 } 160 #endif 161 162 int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) 163 { 164 if (dest->meth->group_copy == 0) { 165 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 166 return 0; 167 } 168 if (dest->meth != src->meth) { 169 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 170 return 0; 171 } 172 if (dest == src) 173 return 1; 174 175 dest->libctx = src->libctx; 176 dest->curve_name = src->curve_name; 177 178 EC_pre_comp_free(dest); 179 180 /* Copy precomputed */ 181 dest->pre_comp_type = src->pre_comp_type; 182 switch (src->pre_comp_type) { 183 case PCT_none: 184 dest->pre_comp.ec = NULL; 185 break; 186 case PCT_nistz256: 187 #ifdef ECP_NISTZ256_ASM 188 dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256); 189 #endif 190 break; 191 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 192 case PCT_nistp224: 193 dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224); 194 break; 195 case PCT_nistp256: 196 dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256); 197 break; 198 case PCT_nistp384: 199 dest->pre_comp.nistp384 = ossl_ec_nistp384_pre_comp_dup(src->pre_comp.nistp384); 200 break; 201 case PCT_nistp521: 202 dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521); 203 break; 204 #else 205 case PCT_nistp224: 206 case PCT_nistp256: 207 case PCT_nistp384: 208 case PCT_nistp521: 209 break; 210 #endif 211 case PCT_ec: 212 dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec); 213 break; 214 } 215 216 if (src->mont_data != NULL) { 217 if (dest->mont_data == NULL) { 218 dest->mont_data = BN_MONT_CTX_new(); 219 if (dest->mont_data == NULL) 220 return 0; 221 } 222 if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) 223 return 0; 224 } else { 225 /* src->generator == NULL */ 226 BN_MONT_CTX_free(dest->mont_data); 227 dest->mont_data = NULL; 228 } 229 230 if (src->generator != NULL) { 231 if (dest->generator == NULL) { 232 dest->generator = EC_POINT_new(dest); 233 if (dest->generator == NULL) 234 return 0; 235 } 236 if (!EC_POINT_copy(dest->generator, src->generator)) 237 return 0; 238 } else { 239 /* src->generator == NULL */ 240 EC_POINT_clear_free(dest->generator); 241 dest->generator = NULL; 242 } 243 244 if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { 245 if (!BN_copy(dest->order, src->order)) 246 return 0; 247 if (!BN_copy(dest->cofactor, src->cofactor)) 248 return 0; 249 } 250 251 dest->asn1_flag = src->asn1_flag; 252 dest->asn1_form = src->asn1_form; 253 dest->decoded_from_explicit_params = src->decoded_from_explicit_params; 254 255 if (src->seed) { 256 OPENSSL_free(dest->seed); 257 if ((dest->seed = OPENSSL_malloc(src->seed_len)) == NULL) 258 return 0; 259 if (!memcpy(dest->seed, src->seed, src->seed_len)) 260 return 0; 261 dest->seed_len = src->seed_len; 262 } else { 263 OPENSSL_free(dest->seed); 264 dest->seed = NULL; 265 dest->seed_len = 0; 266 } 267 268 return dest->meth->group_copy(dest, src); 269 } 270 271 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) 272 { 273 EC_GROUP *t = NULL; 274 int ok = 0; 275 276 if (a == NULL) 277 return NULL; 278 279 if ((t = ossl_ec_group_new_ex(a->libctx, a->propq, a->meth)) == NULL) 280 return NULL; 281 if (!EC_GROUP_copy(t, a)) 282 goto err; 283 284 ok = 1; 285 286 err: 287 if (!ok) { 288 EC_GROUP_free(t); 289 return NULL; 290 } 291 return t; 292 } 293 294 #ifndef OPENSSL_NO_DEPRECATED_3_0 295 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) 296 { 297 return group->meth; 298 } 299 300 int EC_METHOD_get_field_type(const EC_METHOD *meth) 301 { 302 return meth->field_type; 303 } 304 #endif 305 306 static int ec_precompute_mont_data(EC_GROUP *); 307 308 /*- 309 * Try computing cofactor from the generator order (n) and field cardinality (q). 310 * This works for all curves of cryptographic interest. 311 * 312 * Hasse thm: q + 1 - 2*sqrt(q) <= n*h <= q + 1 + 2*sqrt(q) 313 * h_min = (q + 1 - 2*sqrt(q))/n 314 * h_max = (q + 1 + 2*sqrt(q))/n 315 * h_max - h_min = 4*sqrt(q)/n 316 * So if n > 4*sqrt(q) holds, there is only one possible value for h: 317 * h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil 318 * 319 * Otherwise, zero cofactor and return success. 320 */ 321 static int ec_guess_cofactor(EC_GROUP *group) 322 { 323 int ret = 0; 324 BN_CTX *ctx = NULL; 325 BIGNUM *q = NULL; 326 327 /*- 328 * If the cofactor is too large, we cannot guess it. 329 * The RHS of below is a strict overestimate of lg(4 * sqrt(q)) 330 */ 331 if (BN_num_bits(group->order) <= (BN_num_bits(group->field) + 1) / 2 + 3) { 332 /* default to 0 */ 333 BN_zero(group->cofactor); 334 /* return success */ 335 return 1; 336 } 337 338 if ((ctx = BN_CTX_new_ex(group->libctx)) == NULL) 339 return 0; 340 341 BN_CTX_start(ctx); 342 if ((q = BN_CTX_get(ctx)) == NULL) 343 goto err; 344 345 /* set q = 2**m for binary fields; q = p otherwise */ 346 if (group->meth->field_type == NID_X9_62_characteristic_two_field) { 347 BN_zero(q); 348 if (!BN_set_bit(q, BN_num_bits(group->field) - 1)) 349 goto err; 350 } else { 351 if (!BN_copy(q, group->field)) 352 goto err; 353 } 354 355 /* compute h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2)/n \rfloor */ 356 if (!BN_rshift1(group->cofactor, group->order) /* n/2 */ 357 || !BN_add(group->cofactor, group->cofactor, q) /* q + n/2 */ 358 /* q + 1 + n/2 */ 359 || !BN_add(group->cofactor, group->cofactor, BN_value_one()) 360 /* (q + 1 + n/2)/n */ 361 || !BN_div(group->cofactor, NULL, group->cofactor, group->order, ctx)) 362 goto err; 363 ret = 1; 364 err: 365 BN_CTX_end(ctx); 366 BN_CTX_free(ctx); 367 return ret; 368 } 369 370 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 371 const BIGNUM *order, const BIGNUM *cofactor) 372 { 373 if (generator == NULL) { 374 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 375 return 0; 376 } 377 378 /* require group->field >= 1 */ 379 if (group->field == NULL || BN_is_zero(group->field) 380 || BN_is_negative(group->field)) { 381 ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); 382 return 0; 383 } 384 385 /*- 386 * - require order >= 1 387 * - enforce upper bound due to Hasse thm: order can be no more than one bit 388 * longer than field cardinality 389 */ 390 if (order == NULL || BN_is_zero(order) || BN_is_negative(order) 391 || BN_num_bits(order) > BN_num_bits(group->field) + 1) { 392 ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); 393 return 0; 394 } 395 396 /*- 397 * Unfortunately the cofactor is an optional field in many standards. 398 * Internally, the lib uses 0 cofactor as a marker for "unknown cofactor". 399 * So accept cofactor == NULL or cofactor >= 0. 400 */ 401 if (cofactor != NULL && BN_is_negative(cofactor)) { 402 ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR); 403 return 0; 404 } 405 406 if (group->generator == NULL) { 407 group->generator = EC_POINT_new(group); 408 if (group->generator == NULL) 409 return 0; 410 } 411 if (!EC_POINT_copy(group->generator, generator)) 412 return 0; 413 414 if (!BN_copy(group->order, order)) 415 return 0; 416 417 /* Either take the provided positive cofactor, or try to compute it */ 418 if (cofactor != NULL && !BN_is_zero(cofactor)) { 419 if (!BN_copy(group->cofactor, cofactor)) 420 return 0; 421 } else if (!ec_guess_cofactor(group)) { 422 BN_zero(group->cofactor); 423 return 0; 424 } 425 426 /* 427 * Some groups have an order with 428 * factors of two, which makes the Montgomery setup fail. 429 * |group->mont_data| will be NULL in this case. 430 */ 431 if (BN_is_odd(group->order)) { 432 return ec_precompute_mont_data(group); 433 } 434 435 BN_MONT_CTX_free(group->mont_data); 436 group->mont_data = NULL; 437 return 1; 438 } 439 440 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) 441 { 442 return group->generator; 443 } 444 445 BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) 446 { 447 return group->mont_data; 448 } 449 450 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) 451 { 452 if (group->order == NULL) 453 return 0; 454 if (!BN_copy(order, group->order)) 455 return 0; 456 457 return !BN_is_zero(order); 458 } 459 460 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) 461 { 462 return group->order; 463 } 464 465 int EC_GROUP_order_bits(const EC_GROUP *group) 466 { 467 return group->meth->group_order_bits(group); 468 } 469 470 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, 471 BN_CTX *ctx) 472 { 473 474 if (group->cofactor == NULL) 475 return 0; 476 if (!BN_copy(cofactor, group->cofactor)) 477 return 0; 478 479 return !BN_is_zero(group->cofactor); 480 } 481 482 const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group) 483 { 484 return group->cofactor; 485 } 486 487 void EC_GROUP_set_curve_name(EC_GROUP *group, int nid) 488 { 489 group->curve_name = nid; 490 group->asn1_flag = (nid != NID_undef) 491 ? OPENSSL_EC_NAMED_CURVE 492 : OPENSSL_EC_EXPLICIT_CURVE; 493 } 494 495 int EC_GROUP_get_curve_name(const EC_GROUP *group) 496 { 497 return group->curve_name; 498 } 499 500 const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group) 501 { 502 return group->field; 503 } 504 505 int EC_GROUP_get_field_type(const EC_GROUP *group) 506 { 507 return group->meth->field_type; 508 } 509 510 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) 511 { 512 group->asn1_flag = flag; 513 } 514 515 int EC_GROUP_get_asn1_flag(const EC_GROUP *group) 516 { 517 return group->asn1_flag; 518 } 519 520 void EC_GROUP_set_point_conversion_form(EC_GROUP *group, 521 point_conversion_form_t form) 522 { 523 group->asn1_form = form; 524 } 525 526 point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP 527 *group) 528 { 529 return group->asn1_form; 530 } 531 532 size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) 533 { 534 OPENSSL_free(group->seed); 535 group->seed = NULL; 536 group->seed_len = 0; 537 538 if (!len || !p) 539 return 1; 540 541 if ((group->seed = OPENSSL_malloc(len)) == NULL) 542 return 0; 543 memcpy(group->seed, p, len); 544 group->seed_len = len; 545 546 return len; 547 } 548 549 unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group) 550 { 551 return group->seed; 552 } 553 554 size_t EC_GROUP_get_seed_len(const EC_GROUP *group) 555 { 556 return group->seed_len; 557 } 558 559 int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 560 const BIGNUM *b, BN_CTX *ctx) 561 { 562 if (group->meth->group_set_curve == 0) { 563 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 564 return 0; 565 } 566 return group->meth->group_set_curve(group, p, a, b, ctx); 567 } 568 569 int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, 570 BN_CTX *ctx) 571 { 572 if (group->meth->group_get_curve == NULL) { 573 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 574 return 0; 575 } 576 return group->meth->group_get_curve(group, p, a, b, ctx); 577 } 578 579 #ifndef OPENSSL_NO_DEPRECATED_3_0 580 int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 581 const BIGNUM *b, BN_CTX *ctx) 582 { 583 return EC_GROUP_set_curve(group, p, a, b, ctx); 584 } 585 586 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, 587 BIGNUM *b, BN_CTX *ctx) 588 { 589 return EC_GROUP_get_curve(group, p, a, b, ctx); 590 } 591 592 #ifndef OPENSSL_NO_EC2M 593 int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 594 const BIGNUM *b, BN_CTX *ctx) 595 { 596 return EC_GROUP_set_curve(group, p, a, b, ctx); 597 } 598 599 int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, 600 BIGNUM *b, BN_CTX *ctx) 601 { 602 return EC_GROUP_get_curve(group, p, a, b, ctx); 603 } 604 #endif 605 #endif 606 607 int EC_GROUP_get_degree(const EC_GROUP *group) 608 { 609 if (group->meth->group_get_degree == 0) { 610 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 611 return 0; 612 } 613 return group->meth->group_get_degree(group); 614 } 615 616 int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 617 { 618 if (group->meth->group_check_discriminant == 0) { 619 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 620 return 0; 621 } 622 return group->meth->group_check_discriminant(group, ctx); 623 } 624 625 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) 626 { 627 int r = 0; 628 BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; 629 #ifndef FIPS_MODULE 630 BN_CTX *ctx_new = NULL; 631 #endif 632 633 /* compare the field types */ 634 if (EC_GROUP_get_field_type(a) != EC_GROUP_get_field_type(b)) 635 return 1; 636 /* compare the curve name (if present in both) */ 637 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) 638 return 1; 639 if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE) 640 return 0; 641 642 #ifndef FIPS_MODULE 643 if (ctx == NULL) 644 ctx_new = ctx = BN_CTX_new(); 645 #endif 646 if (ctx == NULL) 647 return -1; 648 649 BN_CTX_start(ctx); 650 a1 = BN_CTX_get(ctx); 651 a2 = BN_CTX_get(ctx); 652 a3 = BN_CTX_get(ctx); 653 b1 = BN_CTX_get(ctx); 654 b2 = BN_CTX_get(ctx); 655 b3 = BN_CTX_get(ctx); 656 if (b3 == NULL) { 657 BN_CTX_end(ctx); 658 #ifndef FIPS_MODULE 659 BN_CTX_free(ctx_new); 660 #endif 661 return -1; 662 } 663 664 /* 665 * XXX This approach assumes that the external representation of curves 666 * over the same field type is the same. 667 */ 668 if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || !b->meth->group_get_curve(b, b1, b2, b3, ctx)) 669 r = 1; 670 671 /* return 1 if the curve parameters are different */ 672 if (r || BN_cmp(a1, b1) != 0 || BN_cmp(a2, b2) != 0 || BN_cmp(a3, b3) != 0) 673 r = 1; 674 675 /* XXX EC_POINT_cmp() assumes that the methods are equal */ 676 /* return 1 if the generators are different */ 677 if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), EC_GROUP_get0_generator(b), ctx) != 0) 678 r = 1; 679 680 if (!r) { 681 const BIGNUM *ao, *bo, *ac, *bc; 682 /* compare the orders */ 683 ao = EC_GROUP_get0_order(a); 684 bo = EC_GROUP_get0_order(b); 685 if (ao == NULL || bo == NULL) { 686 /* return an error if either order is NULL */ 687 r = -1; 688 goto end; 689 } 690 if (BN_cmp(ao, bo) != 0) { 691 /* return 1 if orders are different */ 692 r = 1; 693 goto end; 694 } 695 /* 696 * It gets here if the curve parameters and generator matched. 697 * Now check the optional cofactors (if both are present). 698 */ 699 ac = EC_GROUP_get0_cofactor(a); 700 bc = EC_GROUP_get0_cofactor(b); 701 /* Returns 1 (mismatch) if both cofactors are specified and different */ 702 if (!BN_is_zero(ac) && !BN_is_zero(bc) && BN_cmp(ac, bc) != 0) 703 r = 1; 704 /* Returns 0 if the parameters matched */ 705 } 706 end: 707 BN_CTX_end(ctx); 708 #ifndef FIPS_MODULE 709 BN_CTX_free(ctx_new); 710 #endif 711 return r; 712 } 713 714 /* functions for EC_POINT objects */ 715 716 EC_POINT *EC_POINT_new(const EC_GROUP *group) 717 { 718 EC_POINT *ret; 719 720 if (group == NULL) { 721 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 722 return NULL; 723 } 724 if (group->meth->point_init == NULL) { 725 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 726 return NULL; 727 } 728 729 ret = OPENSSL_zalloc(sizeof(*ret)); 730 if (ret == NULL) 731 return NULL; 732 733 ret->meth = group->meth; 734 ret->curve_name = group->curve_name; 735 736 if (!ret->meth->point_init(ret)) { 737 OPENSSL_free(ret); 738 return NULL; 739 } 740 741 return ret; 742 } 743 744 void EC_POINT_free(EC_POINT *point) 745 { 746 if (point == NULL) 747 return; 748 749 #ifdef OPENSSL_PEDANTIC_ZEROIZATION 750 EC_POINT_clear_free(point); 751 #else 752 if (point->meth->point_finish != 0) 753 point->meth->point_finish(point); 754 OPENSSL_free(point); 755 #endif 756 } 757 758 void EC_POINT_clear_free(EC_POINT *point) 759 { 760 if (point == NULL) 761 return; 762 763 if (point->meth->point_clear_finish != 0) 764 point->meth->point_clear_finish(point); 765 else if (point->meth->point_finish != 0) 766 point->meth->point_finish(point); 767 OPENSSL_clear_free(point, sizeof(*point)); 768 } 769 770 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) 771 { 772 if (dest->meth->point_copy == 0) { 773 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 774 return 0; 775 } 776 if (dest->meth != src->meth 777 || (dest->curve_name != src->curve_name 778 && dest->curve_name != 0 779 && src->curve_name != 0)) { 780 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 781 return 0; 782 } 783 if (dest == src) 784 return 1; 785 return dest->meth->point_copy(dest, src); 786 } 787 788 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) 789 { 790 EC_POINT *t; 791 int r; 792 793 if (a == NULL) 794 return NULL; 795 796 t = EC_POINT_new(group); 797 if (t == NULL) 798 return NULL; 799 r = EC_POINT_copy(t, a); 800 if (!r) { 801 EC_POINT_free(t); 802 return NULL; 803 } 804 return t; 805 } 806 807 #ifndef OPENSSL_NO_DEPRECATED_3_0 808 const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) 809 { 810 return point->meth; 811 } 812 #endif 813 814 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 815 { 816 if (group->meth->point_set_to_infinity == 0) { 817 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 818 return 0; 819 } 820 if (group->meth != point->meth) { 821 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 822 return 0; 823 } 824 return group->meth->point_set_to_infinity(group, point); 825 } 826 827 #ifndef OPENSSL_NO_DEPRECATED_3_0 828 int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, 829 EC_POINT *point, const BIGNUM *x, 830 const BIGNUM *y, const BIGNUM *z, 831 BN_CTX *ctx) 832 { 833 if (group->meth->field_type != NID_X9_62_prime_field) { 834 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 835 return 0; 836 } 837 if (!ec_point_is_compat(point, group)) { 838 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 839 return 0; 840 } 841 return ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, 842 x, y, z, ctx); 843 } 844 845 int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, 846 const EC_POINT *point, BIGNUM *x, 847 BIGNUM *y, BIGNUM *z, 848 BN_CTX *ctx) 849 { 850 if (group->meth->field_type != NID_X9_62_prime_field) { 851 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 852 return 0; 853 } 854 if (!ec_point_is_compat(point, group)) { 855 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 856 return 0; 857 } 858 return ossl_ec_GFp_simple_get_Jprojective_coordinates_GFp(group, point, 859 x, y, z, ctx); 860 } 861 #endif 862 863 int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 864 const BIGNUM *x, const BIGNUM *y, 865 BN_CTX *ctx) 866 { 867 if (group->meth->point_set_affine_coordinates == NULL) { 868 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 869 return 0; 870 } 871 if (!ec_point_is_compat(point, group)) { 872 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 873 return 0; 874 } 875 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx)) 876 return 0; 877 878 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 879 ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE); 880 return 0; 881 } 882 return 1; 883 } 884 885 #ifndef OPENSSL_NO_DEPRECATED_3_0 886 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, 887 EC_POINT *point, const BIGNUM *x, 888 const BIGNUM *y, BN_CTX *ctx) 889 { 890 return EC_POINT_set_affine_coordinates(group, point, x, y, ctx); 891 } 892 893 #ifndef OPENSSL_NO_EC2M 894 int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, 895 EC_POINT *point, const BIGNUM *x, 896 const BIGNUM *y, BN_CTX *ctx) 897 { 898 return EC_POINT_set_affine_coordinates(group, point, x, y, ctx); 899 } 900 #endif 901 #endif 902 903 int EC_POINT_get_affine_coordinates(const EC_GROUP *group, 904 const EC_POINT *point, BIGNUM *x, BIGNUM *y, 905 BN_CTX *ctx) 906 { 907 if (group->meth->point_get_affine_coordinates == NULL) { 908 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 909 return 0; 910 } 911 if (!ec_point_is_compat(point, group)) { 912 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 913 return 0; 914 } 915 if (EC_POINT_is_at_infinity(group, point)) { 916 ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); 917 return 0; 918 } 919 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 920 } 921 922 #ifndef OPENSSL_NO_DEPRECATED_3_0 923 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, 924 const EC_POINT *point, BIGNUM *x, 925 BIGNUM *y, BN_CTX *ctx) 926 { 927 return EC_POINT_get_affine_coordinates(group, point, x, y, ctx); 928 } 929 930 #ifndef OPENSSL_NO_EC2M 931 int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, 932 const EC_POINT *point, BIGNUM *x, 933 BIGNUM *y, BN_CTX *ctx) 934 { 935 return EC_POINT_get_affine_coordinates(group, point, x, y, ctx); 936 } 937 #endif 938 #endif 939 940 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 941 const EC_POINT *b, BN_CTX *ctx) 942 { 943 if (group->meth->add == 0) { 944 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 945 return 0; 946 } 947 if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group) 948 || !ec_point_is_compat(b, group)) { 949 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 950 return 0; 951 } 952 return group->meth->add(group, r, a, b, ctx); 953 } 954 955 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 956 BN_CTX *ctx) 957 { 958 if (group->meth->dbl == 0) { 959 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 960 return 0; 961 } 962 if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group)) { 963 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 964 return 0; 965 } 966 return group->meth->dbl(group, r, a, ctx); 967 } 968 969 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) 970 { 971 if (group->meth->invert == 0) { 972 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 973 return 0; 974 } 975 if (!ec_point_is_compat(a, group)) { 976 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 977 return 0; 978 } 979 return group->meth->invert(group, a, ctx); 980 } 981 982 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 983 { 984 if (group->meth->is_at_infinity == 0) { 985 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 986 return 0; 987 } 988 if (!ec_point_is_compat(point, group)) { 989 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 990 return 0; 991 } 992 return group->meth->is_at_infinity(group, point); 993 } 994 995 /* 996 * Check whether an EC_POINT is on the curve or not. Note that the return 997 * value for this function should NOT be treated as a boolean. Return values: 998 * 1: The point is on the curve 999 * 0: The point is not on the curve 1000 * -1: An error occurred 1001 */ 1002 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, 1003 BN_CTX *ctx) 1004 { 1005 if (group->meth->is_on_curve == 0) { 1006 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1007 return 0; 1008 } 1009 if (!ec_point_is_compat(point, group)) { 1010 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 1011 return 0; 1012 } 1013 return group->meth->is_on_curve(group, point, ctx); 1014 } 1015 1016 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 1017 BN_CTX *ctx) 1018 { 1019 if (group->meth->point_cmp == 0) { 1020 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1021 return -1; 1022 } 1023 if (!ec_point_is_compat(a, group) || !ec_point_is_compat(b, group)) { 1024 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 1025 return -1; 1026 } 1027 return group->meth->point_cmp(group, a, b, ctx); 1028 } 1029 1030 #ifndef OPENSSL_NO_DEPRECATED_3_0 1031 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 1032 { 1033 if (group->meth->make_affine == 0) { 1034 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1035 return 0; 1036 } 1037 if (!ec_point_is_compat(point, group)) { 1038 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 1039 return 0; 1040 } 1041 return group->meth->make_affine(group, point, ctx); 1042 } 1043 1044 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, 1045 EC_POINT *points[], BN_CTX *ctx) 1046 { 1047 size_t i; 1048 1049 if (group->meth->points_make_affine == 0) { 1050 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1051 return 0; 1052 } 1053 for (i = 0; i < num; i++) { 1054 if (!ec_point_is_compat(points[i], group)) { 1055 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 1056 return 0; 1057 } 1058 } 1059 return group->meth->points_make_affine(group, num, points, ctx); 1060 } 1061 #endif 1062 1063 /* 1064 * Functions for point multiplication. If group->meth->mul is 0, we use the 1065 * wNAF-based implementations in ec_mult.c; otherwise we dispatch through 1066 * methods. 1067 */ 1068 1069 #ifndef OPENSSL_NO_DEPRECATED_3_0 1070 int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 1071 size_t num, const EC_POINT *points[], 1072 const BIGNUM *scalars[], BN_CTX *ctx) 1073 { 1074 int ret = 0; 1075 size_t i = 0; 1076 #ifndef FIPS_MODULE 1077 BN_CTX *new_ctx = NULL; 1078 #endif 1079 1080 if (!ec_point_is_compat(r, group)) { 1081 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 1082 return 0; 1083 } 1084 1085 if (scalar == NULL && num == 0) 1086 return EC_POINT_set_to_infinity(group, r); 1087 1088 for (i = 0; i < num; i++) { 1089 if (!ec_point_is_compat(points[i], group)) { 1090 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 1091 return 0; 1092 } 1093 } 1094 1095 #ifndef FIPS_MODULE 1096 if (ctx == NULL) 1097 ctx = new_ctx = BN_CTX_secure_new(); 1098 #endif 1099 if (ctx == NULL) { 1100 ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); 1101 return 0; 1102 } 1103 1104 if (group->meth->mul != NULL) 1105 ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx); 1106 else 1107 /* use default */ 1108 ret = ossl_ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); 1109 1110 #ifndef FIPS_MODULE 1111 BN_CTX_free(new_ctx); 1112 #endif 1113 return ret; 1114 } 1115 #endif 1116 1117 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 1118 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) 1119 { 1120 int ret = 0; 1121 size_t num; 1122 #ifndef FIPS_MODULE 1123 BN_CTX *new_ctx = NULL; 1124 #endif 1125 1126 if (!ec_point_is_compat(r, group) 1127 || (point != NULL && !ec_point_is_compat(point, group))) { 1128 ERR_raise(ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS); 1129 return 0; 1130 } 1131 1132 if (g_scalar == NULL && p_scalar == NULL) 1133 return EC_POINT_set_to_infinity(group, r); 1134 1135 #ifndef FIPS_MODULE 1136 if (ctx == NULL) 1137 ctx = new_ctx = BN_CTX_secure_new(); 1138 #endif 1139 if (ctx == NULL) { 1140 ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); 1141 return 0; 1142 } 1143 1144 num = (point != NULL && p_scalar != NULL) ? 1 : 0; 1145 if (group->meth->mul != NULL) 1146 ret = group->meth->mul(group, r, g_scalar, num, &point, &p_scalar, ctx); 1147 else 1148 /* use default */ 1149 ret = ossl_ec_wNAF_mul(group, r, g_scalar, num, &point, &p_scalar, ctx); 1150 1151 #ifndef FIPS_MODULE 1152 BN_CTX_free(new_ctx); 1153 #endif 1154 return ret; 1155 } 1156 1157 #ifndef OPENSSL_NO_DEPRECATED_3_0 1158 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 1159 { 1160 if (group->meth->mul == 0) 1161 /* use default */ 1162 return ossl_ec_wNAF_precompute_mult(group, ctx); 1163 1164 if (group->meth->precompute_mult != 0) 1165 return group->meth->precompute_mult(group, ctx); 1166 else 1167 return 1; /* nothing to do, so report success */ 1168 } 1169 1170 int EC_GROUP_have_precompute_mult(const EC_GROUP *group) 1171 { 1172 if (group->meth->mul == 0) 1173 /* use default */ 1174 return ossl_ec_wNAF_have_precompute_mult(group); 1175 1176 if (group->meth->have_precompute_mult != 0) 1177 return group->meth->have_precompute_mult(group); 1178 else 1179 return 0; /* cannot tell whether precomputation has 1180 * been performed */ 1181 } 1182 #endif 1183 1184 /* 1185 * ec_precompute_mont_data sets |group->mont_data| from |group->order| and 1186 * returns one on success. On error it returns zero. 1187 */ 1188 static int ec_precompute_mont_data(EC_GROUP *group) 1189 { 1190 BN_CTX *ctx = BN_CTX_new_ex(group->libctx); 1191 int ret = 0; 1192 1193 BN_MONT_CTX_free(group->mont_data); 1194 group->mont_data = NULL; 1195 1196 if (ctx == NULL) 1197 goto err; 1198 1199 group->mont_data = BN_MONT_CTX_new(); 1200 if (group->mont_data == NULL) 1201 goto err; 1202 1203 if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) { 1204 BN_MONT_CTX_free(group->mont_data); 1205 group->mont_data = NULL; 1206 goto err; 1207 } 1208 1209 ret = 1; 1210 1211 err: 1212 1213 BN_CTX_free(ctx); 1214 return ret; 1215 } 1216 1217 #ifndef FIPS_MODULE 1218 int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg) 1219 { 1220 return CRYPTO_set_ex_data(&key->ex_data, idx, arg); 1221 } 1222 1223 void *EC_KEY_get_ex_data(const EC_KEY *key, int idx) 1224 { 1225 return CRYPTO_get_ex_data(&key->ex_data, idx); 1226 } 1227 #endif 1228 1229 int ossl_ec_group_simple_order_bits(const EC_GROUP *group) 1230 { 1231 if (group->order == NULL) 1232 return 0; 1233 return BN_num_bits(group->order); 1234 } 1235 1236 static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r, 1237 const BIGNUM *x, BN_CTX *ctx) 1238 { 1239 BIGNUM *e = NULL; 1240 int ret = 0; 1241 #ifndef FIPS_MODULE 1242 BN_CTX *new_ctx = NULL; 1243 #endif 1244 1245 if (group->mont_data == NULL) 1246 return 0; 1247 1248 #ifndef FIPS_MODULE 1249 if (ctx == NULL) 1250 ctx = new_ctx = BN_CTX_secure_new(); 1251 #endif 1252 if (ctx == NULL) 1253 return 0; 1254 1255 BN_CTX_start(ctx); 1256 if ((e = BN_CTX_get(ctx)) == NULL) 1257 goto err; 1258 1259 /*- 1260 * We want inverse in constant time, therefore we utilize the fact 1261 * order must be prime and use Fermats Little Theorem instead. 1262 */ 1263 if (!BN_set_word(e, 2)) 1264 goto err; 1265 if (!BN_sub(e, group->order, e)) 1266 goto err; 1267 /*- 1268 * Although the exponent is public we want the result to be 1269 * fixed top. 1270 */ 1271 if (!bn_mod_exp_mont_fixed_top(r, x, e, group->order, ctx, group->mont_data)) 1272 goto err; 1273 1274 ret = 1; 1275 1276 err: 1277 BN_CTX_end(ctx); 1278 #ifndef FIPS_MODULE 1279 BN_CTX_free(new_ctx); 1280 #endif 1281 return ret; 1282 } 1283 1284 /*- 1285 * Default behavior, if group->meth->field_inverse_mod_ord is NULL: 1286 * - When group->order is even, this function returns an error. 1287 * - When group->order is otherwise composite, the correctness 1288 * of the output is not guaranteed. 1289 * - When x is outside the range [1, group->order), the correctness 1290 * of the output is not guaranteed. 1291 * - Otherwise, this function returns the multiplicative inverse in the 1292 * range [1, group->order). 1293 * 1294 * EC_METHODs must implement their own field_inverse_mod_ord for 1295 * other functionality. 1296 */ 1297 int ossl_ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, 1298 const BIGNUM *x, BN_CTX *ctx) 1299 { 1300 if (group->meth->field_inverse_mod_ord != NULL) 1301 return group->meth->field_inverse_mod_ord(group, res, x, ctx); 1302 else 1303 return ec_field_inverse_mod_ord(group, res, x, ctx); 1304 } 1305 1306 /*- 1307 * Coordinate blinding for EC_POINT. 1308 * 1309 * The underlying EC_METHOD can optionally implement this function: 1310 * underlying implementations should return 0 on errors, or 1 on 1311 * success. 1312 * 1313 * This wrapper returns 1 in case the underlying EC_METHOD does not 1314 * support coordinate blinding. 1315 */ 1316 int ossl_ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, 1317 BN_CTX *ctx) 1318 { 1319 if (group->meth->blind_coordinates == NULL) 1320 return 1; /* ignore if not implemented */ 1321 1322 return group->meth->blind_coordinates(group, p, ctx); 1323 } 1324 1325 int EC_GROUP_get_basis_type(const EC_GROUP *group) 1326 { 1327 int i; 1328 1329 if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field) 1330 /* everything else is currently not supported */ 1331 return 0; 1332 1333 /* Find the last non-zero element of group->poly[] */ 1334 for (i = 0; 1335 i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; 1336 i++) 1337 continue; 1338 1339 if (i == 4) 1340 return NID_X9_62_ppBasis; 1341 else if (i == 2) 1342 return NID_X9_62_tpBasis; 1343 else 1344 /* everything else is currently not supported */ 1345 return 0; 1346 } 1347 1348 #ifndef OPENSSL_NO_EC2M 1349 int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) 1350 { 1351 if (group == NULL) 1352 return 0; 1353 1354 if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field 1355 || !((group->poly[0] != 0) && (group->poly[1] != 0) 1356 && (group->poly[2] == 0))) { 1357 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1358 return 0; 1359 } 1360 1361 if (k) 1362 *k = group->poly[1]; 1363 1364 return 1; 1365 } 1366 1367 int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, 1368 unsigned int *k2, unsigned int *k3) 1369 { 1370 if (group == NULL) 1371 return 0; 1372 1373 if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field 1374 || !((group->poly[0] != 0) && (group->poly[1] != 0) 1375 && (group->poly[2] != 0) && (group->poly[3] != 0) 1376 && (group->poly[4] == 0))) { 1377 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1378 return 0; 1379 } 1380 1381 if (k1) 1382 *k1 = group->poly[3]; 1383 if (k2) 1384 *k2 = group->poly[2]; 1385 if (k3) 1386 *k3 = group->poly[1]; 1387 1388 return 1; 1389 } 1390 #endif 1391 1392 #ifndef FIPS_MODULE 1393 /* 1394 * Check if the explicit parameters group matches any built-in curves. 1395 * 1396 * We create a copy of the group just built, so that we can remove optional 1397 * fields for the lookup: we do this to avoid the possibility that one of 1398 * the optional parameters is used to force the library into using a less 1399 * performant and less secure EC_METHOD instead of the specialized one. 1400 * In any case, `seed` is not really used in any computation, while a 1401 * cofactor different from the one in the built-in table is just 1402 * mathematically wrong anyway and should not be used. 1403 */ 1404 static EC_GROUP *ec_group_explicit_to_named(const EC_GROUP *group, 1405 OSSL_LIB_CTX *libctx, 1406 const char *propq, 1407 BN_CTX *ctx) 1408 { 1409 EC_GROUP *ret_group = NULL, *dup = NULL; 1410 int curve_name_nid; 1411 1412 const EC_POINT *point = EC_GROUP_get0_generator(group); 1413 const BIGNUM *order = EC_GROUP_get0_order(group); 1414 int no_seed = (EC_GROUP_get0_seed(group) == NULL); 1415 1416 if ((dup = EC_GROUP_dup(group)) == NULL 1417 || EC_GROUP_set_seed(dup, NULL, 0) != 1 1418 || !EC_GROUP_set_generator(dup, point, order, NULL)) 1419 goto err; 1420 if ((curve_name_nid = ossl_ec_curve_nid_from_params(dup, ctx)) != NID_undef) { 1421 /* 1422 * The input explicit parameters successfully matched one of the 1423 * built-in curves: often for built-in curves we have specialized 1424 * methods with better performance and hardening. 1425 * 1426 * In this case we replace the `EC_GROUP` created through explicit 1427 * parameters with one created from a named group. 1428 */ 1429 1430 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 1431 /* 1432 * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for 1433 * the same curve, we prefer the SECP nid when matching explicit 1434 * parameters as that is associated with a specialized EC_METHOD. 1435 */ 1436 if (curve_name_nid == NID_wap_wsg_idm_ecid_wtls12) 1437 curve_name_nid = NID_secp224r1; 1438 #endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */ 1439 1440 ret_group = EC_GROUP_new_by_curve_name_ex(libctx, propq, curve_name_nid); 1441 if (ret_group == NULL) 1442 goto err; 1443 1444 /* 1445 * Set the flag so that EC_GROUPs created from explicit parameters are 1446 * serialized using explicit parameters by default. 1447 */ 1448 EC_GROUP_set_asn1_flag(ret_group, OPENSSL_EC_EXPLICIT_CURVE); 1449 1450 /* 1451 * If the input params do not contain the optional seed field we make 1452 * sure it is not added to the returned group. 1453 * 1454 * The seed field is not really used inside libcrypto anyway, and 1455 * adding it to parsed explicit parameter keys would alter their DER 1456 * encoding output (because of the extra field) which could impact 1457 * applications fingerprinting keys by their DER encoding. 1458 */ 1459 if (no_seed) { 1460 if (EC_GROUP_set_seed(ret_group, NULL, 0) != 1) 1461 goto err; 1462 } 1463 } else { 1464 ret_group = (EC_GROUP *)group; 1465 } 1466 EC_GROUP_free(dup); 1467 return ret_group; 1468 err: 1469 EC_GROUP_free(dup); 1470 EC_GROUP_free(ret_group); 1471 return NULL; 1472 } 1473 #endif /* FIPS_MODULE */ 1474 1475 static EC_GROUP *group_new_from_name(const OSSL_PARAM *p, 1476 OSSL_LIB_CTX *libctx, const char *propq) 1477 { 1478 int ok = 0, nid; 1479 const char *curve_name = NULL; 1480 1481 switch (p->data_type) { 1482 case OSSL_PARAM_UTF8_STRING: 1483 /* The OSSL_PARAM functions have no support for this */ 1484 curve_name = p->data; 1485 ok = (curve_name != NULL); 1486 break; 1487 case OSSL_PARAM_UTF8_PTR: 1488 ok = OSSL_PARAM_get_utf8_ptr(p, &curve_name); 1489 break; 1490 } 1491 1492 if (ok) { 1493 nid = ossl_ec_curve_name2nid(curve_name); 1494 if (nid == NID_undef) { 1495 ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); 1496 return NULL; 1497 } else { 1498 return EC_GROUP_new_by_curve_name_ex(libctx, propq, nid); 1499 } 1500 } 1501 return NULL; 1502 } 1503 1504 /* These parameters can be set directly into an EC_GROUP */ 1505 int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]) 1506 { 1507 int encoding_flag = -1, format = -1; 1508 const OSSL_PARAM *p; 1509 1510 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT); 1511 if (p != NULL) { 1512 if (!ossl_ec_pt_format_param2id(p, &format)) { 1513 ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); 1514 return 0; 1515 } 1516 EC_GROUP_set_point_conversion_form(group, format); 1517 } 1518 1519 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); 1520 if (p != NULL) { 1521 if (!ossl_ec_encoding_param2id(p, &encoding_flag)) { 1522 ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); 1523 return 0; 1524 } 1525 EC_GROUP_set_asn1_flag(group, encoding_flag); 1526 } 1527 /* Optional seed */ 1528 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); 1529 if (p != NULL) { 1530 /* The seed is allowed to be NULL */ 1531 if (p->data_type != OSSL_PARAM_OCTET_STRING 1532 || !EC_GROUP_set_seed(group, p->data, p->data_size)) { 1533 ERR_raise(ERR_LIB_EC, EC_R_INVALID_SEED); 1534 return 0; 1535 } 1536 } 1537 return 1; 1538 } 1539 1540 EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], 1541 OSSL_LIB_CTX *libctx, const char *propq) 1542 { 1543 const OSSL_PARAM *ptmp; 1544 EC_GROUP *group = NULL; 1545 1546 #ifndef FIPS_MODULE 1547 const OSSL_PARAM *pa, *pb; 1548 int ok = 0; 1549 EC_GROUP *named_group = NULL; 1550 BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL, *cofactor = NULL; 1551 EC_POINT *point = NULL; 1552 int field_bits = 0; 1553 int is_prime_field = 1; 1554 BN_CTX *bnctx = NULL; 1555 const unsigned char *buf = NULL; 1556 int encoding_flag = -1; 1557 #endif 1558 1559 /* This is the simple named group case */ 1560 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); 1561 if (ptmp != NULL) { 1562 int decoded = 0; 1563 1564 if ((group = group_new_from_name(ptmp, libctx, propq)) == NULL) 1565 return NULL; 1566 if (!ossl_ec_group_set_params(group, params)) { 1567 EC_GROUP_free(group); 1568 return NULL; 1569 } 1570 1571 ptmp = OSSL_PARAM_locate_const(params, 1572 OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS); 1573 if (ptmp != NULL && !OSSL_PARAM_get_int(ptmp, &decoded)) { 1574 ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS); 1575 EC_GROUP_free(group); 1576 return NULL; 1577 } 1578 group->decoded_from_explicit_params = decoded > 0; 1579 return group; 1580 } 1581 #ifdef FIPS_MODULE 1582 ERR_raise(ERR_LIB_EC, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED); 1583 return NULL; 1584 #else 1585 /* If it gets here then we are trying explicit parameters */ 1586 bnctx = BN_CTX_new_ex(libctx); 1587 if (bnctx == NULL) { 1588 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 1589 return 0; 1590 } 1591 BN_CTX_start(bnctx); 1592 1593 p = BN_CTX_get(bnctx); 1594 a = BN_CTX_get(bnctx); 1595 b = BN_CTX_get(bnctx); 1596 order = BN_CTX_get(bnctx); 1597 if (order == NULL) { 1598 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 1599 goto err; 1600 } 1601 1602 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE); 1603 if (ptmp == NULL || ptmp->data_type != OSSL_PARAM_UTF8_STRING) { 1604 ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); 1605 goto err; 1606 } 1607 if (OPENSSL_strcasecmp(ptmp->data, SN_X9_62_prime_field) == 0) { 1608 is_prime_field = 1; 1609 } else if (OPENSSL_strcasecmp(ptmp->data, 1610 SN_X9_62_characteristic_two_field) 1611 == 0) { 1612 is_prime_field = 0; 1613 } else { 1614 /* Invalid field */ 1615 ERR_raise(ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD); 1616 goto err; 1617 } 1618 1619 pa = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A); 1620 if (!OSSL_PARAM_get_BN(pa, &a)) { 1621 ERR_raise(ERR_LIB_EC, EC_R_INVALID_A); 1622 goto err; 1623 } 1624 pb = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B); 1625 if (!OSSL_PARAM_get_BN(pb, &b)) { 1626 ERR_raise(ERR_LIB_EC, EC_R_INVALID_B); 1627 goto err; 1628 } 1629 1630 /* extract the prime number or irreducible polynomial */ 1631 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P); 1632 if (!OSSL_PARAM_get_BN(ptmp, &p)) { 1633 ERR_raise(ERR_LIB_EC, EC_R_INVALID_P); 1634 goto err; 1635 } 1636 1637 if (is_prime_field) { 1638 if (BN_is_negative(p) || BN_is_zero(p)) { 1639 ERR_raise(ERR_LIB_EC, EC_R_INVALID_P); 1640 goto err; 1641 } 1642 field_bits = BN_num_bits(p); 1643 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 1644 ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE); 1645 goto err; 1646 } 1647 1648 /* create the EC_GROUP structure */ 1649 group = EC_GROUP_new_curve_GFp(p, a, b, bnctx); 1650 } else { 1651 #ifdef OPENSSL_NO_EC2M 1652 ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); 1653 goto err; 1654 #else 1655 /* create the EC_GROUP structure */ 1656 group = EC_GROUP_new_curve_GF2m(p, a, b, NULL); 1657 if (group != NULL) { 1658 field_bits = EC_GROUP_get_degree(group); 1659 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { 1660 ERR_raise(ERR_LIB_EC, EC_R_FIELD_TOO_LARGE); 1661 goto err; 1662 } 1663 } 1664 #endif /* OPENSSL_NO_EC2M */ 1665 } 1666 1667 if (group == NULL) { 1668 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 1669 goto err; 1670 } 1671 1672 /* Optional seed */ 1673 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); 1674 if (ptmp != NULL) { 1675 if (ptmp->data_type != OSSL_PARAM_OCTET_STRING) { 1676 ERR_raise(ERR_LIB_EC, EC_R_INVALID_SEED); 1677 goto err; 1678 } 1679 if (!EC_GROUP_set_seed(group, ptmp->data, ptmp->data_size)) 1680 goto err; 1681 } 1682 1683 /* generator base point */ 1684 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR); 1685 if (ptmp == NULL 1686 || ptmp->data_type != OSSL_PARAM_OCTET_STRING 1687 || ptmp->data_size == 0) { 1688 ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); 1689 goto err; 1690 } 1691 buf = (const unsigned char *)(ptmp->data); 1692 if ((point = EC_POINT_new(group)) == NULL) 1693 goto err; 1694 EC_GROUP_set_point_conversion_form(group, 1695 (point_conversion_form_t)buf[0] & ~0x01); 1696 if (!EC_POINT_oct2point(group, point, buf, ptmp->data_size, bnctx)) { 1697 ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); 1698 goto err; 1699 } 1700 1701 /* order */ 1702 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER); 1703 if (!OSSL_PARAM_get_BN(ptmp, &order) 1704 || (BN_is_negative(order) || BN_is_zero(order)) 1705 || (BN_num_bits(order) > (int)field_bits + 1)) { /* Hasse bound */ 1706 ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); 1707 goto err; 1708 } 1709 1710 /* Optional cofactor */ 1711 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR); 1712 if (ptmp != NULL) { 1713 cofactor = BN_CTX_get(bnctx); 1714 if (cofactor == NULL || !OSSL_PARAM_get_BN(ptmp, &cofactor)) { 1715 ERR_raise(ERR_LIB_EC, EC_R_INVALID_COFACTOR); 1716 goto err; 1717 } 1718 } 1719 1720 /* set the generator, order and cofactor (if present) */ 1721 if (!EC_GROUP_set_generator(group, point, order, cofactor)) { 1722 ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); 1723 goto err; 1724 } 1725 1726 named_group = ec_group_explicit_to_named(group, libctx, propq, bnctx); 1727 if (named_group == NULL) { 1728 ERR_raise(ERR_LIB_EC, EC_R_INVALID_NAMED_GROUP_CONVERSION); 1729 goto err; 1730 } 1731 if (named_group == group) { 1732 /* 1733 * If we did not find a named group then the encoding should be explicit 1734 * if it was specified 1735 */ 1736 ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); 1737 if (ptmp != NULL 1738 && !ossl_ec_encoding_param2id(ptmp, &encoding_flag)) { 1739 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 1740 goto err; 1741 } 1742 if (encoding_flag == OPENSSL_EC_NAMED_CURVE) { 1743 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 1744 goto err; 1745 } 1746 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE); 1747 } else { 1748 EC_GROUP_free(group); 1749 group = named_group; 1750 } 1751 /* We've imported the group from explicit parameters, set it so. */ 1752 group->decoded_from_explicit_params = 1; 1753 ok = 1; 1754 err: 1755 if (!ok) { 1756 EC_GROUP_free(group); 1757 group = NULL; 1758 } 1759 EC_POINT_free(point); 1760 BN_CTX_end(bnctx); 1761 BN_CTX_free(bnctx); 1762 1763 return group; 1764 #endif /* FIPS_MODULE */ 1765 } 1766 1767 OSSL_PARAM *EC_GROUP_to_params(const EC_GROUP *group, OSSL_LIB_CTX *libctx, 1768 const char *propq, BN_CTX *bnctx) 1769 { 1770 OSSL_PARAM_BLD *tmpl = NULL; 1771 BN_CTX *new_bnctx = NULL; 1772 unsigned char *gen_buf = NULL; 1773 OSSL_PARAM *params = NULL; 1774 1775 if (group == NULL) 1776 goto err; 1777 1778 tmpl = OSSL_PARAM_BLD_new(); 1779 if (tmpl == NULL) 1780 goto err; 1781 1782 if (bnctx == NULL) 1783 bnctx = new_bnctx = BN_CTX_new_ex(libctx); 1784 if (bnctx == NULL) 1785 goto err; 1786 BN_CTX_start(bnctx); 1787 1788 if (!ossl_ec_group_todata( 1789 group, tmpl, NULL, libctx, propq, bnctx, &gen_buf)) 1790 goto err; 1791 1792 params = OSSL_PARAM_BLD_to_param(tmpl); 1793 1794 err: 1795 OSSL_PARAM_BLD_free(tmpl); 1796 OPENSSL_free(gen_buf); 1797 BN_CTX_end(bnctx); 1798 BN_CTX_free(new_bnctx); 1799 return params; 1800 } 1801