1 /* 2 * Copyright 2002-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 "internal/cryptlib.h" 12 #include <string.h> 13 #include "ec_local.h" 14 #include "internal/refcount.h" 15 #include <openssl/err.h> 16 #include <openssl/engine.h> 17 #include "crypto/bn.h" 18 19 EC_KEY *EC_KEY_new(void) 20 { 21 return EC_KEY_new_method(NULL); 22 } 23 24 EC_KEY *EC_KEY_new_by_curve_name(int nid) 25 { 26 EC_KEY *ret = EC_KEY_new(); 27 if (ret == NULL) 28 return NULL; 29 ret->group = EC_GROUP_new_by_curve_name(nid); 30 if (ret->group == NULL) { 31 EC_KEY_free(ret); 32 return NULL; 33 } 34 if (ret->meth->set_group != NULL 35 && ret->meth->set_group(ret, ret->group) == 0) { 36 EC_KEY_free(ret); 37 return NULL; 38 } 39 return ret; 40 } 41 42 void EC_KEY_free(EC_KEY *r) 43 { 44 int i; 45 46 if (r == NULL) 47 return; 48 49 CRYPTO_DOWN_REF(&r->references, &i, r->lock); 50 REF_PRINT_COUNT("EC_KEY", r); 51 if (i > 0) 52 return; 53 REF_ASSERT_ISNT(i < 0); 54 55 if (r->meth != NULL && r->meth->finish != NULL) 56 r->meth->finish(r); 57 58 #ifndef OPENSSL_NO_ENGINE 59 ENGINE_finish(r->engine); 60 #endif 61 62 if (r->group && r->group->meth->keyfinish) 63 r->group->meth->keyfinish(r); 64 65 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); 66 CRYPTO_THREAD_lock_free(r->lock); 67 EC_GROUP_free(r->group); 68 EC_POINT_free(r->pub_key); 69 BN_clear_free(r->priv_key); 70 71 OPENSSL_clear_free((void *)r, sizeof(EC_KEY)); 72 } 73 74 EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) 75 { 76 if (dest == NULL || src == NULL) { 77 ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); 78 return NULL; 79 } 80 if (src->meth != dest->meth) { 81 if (dest->meth->finish != NULL) 82 dest->meth->finish(dest); 83 if (dest->group && dest->group->meth->keyfinish) 84 dest->group->meth->keyfinish(dest); 85 #ifndef OPENSSL_NO_ENGINE 86 if (ENGINE_finish(dest->engine) == 0) 87 return 0; 88 dest->engine = NULL; 89 #endif 90 } 91 /* copy the parameters */ 92 if (src->group != NULL) { 93 const EC_METHOD *meth = EC_GROUP_method_of(src->group); 94 /* clear the old group */ 95 EC_GROUP_free(dest->group); 96 dest->group = EC_GROUP_new(meth); 97 if (dest->group == NULL) 98 return NULL; 99 if (!EC_GROUP_copy(dest->group, src->group)) 100 return NULL; 101 102 /* copy the public key */ 103 if (src->pub_key != NULL) { 104 EC_POINT_free(dest->pub_key); 105 dest->pub_key = EC_POINT_new(src->group); 106 if (dest->pub_key == NULL) 107 return NULL; 108 if (!EC_POINT_copy(dest->pub_key, src->pub_key)) 109 return NULL; 110 } 111 /* copy the private key */ 112 if (src->priv_key != NULL) { 113 if (dest->priv_key == NULL) { 114 dest->priv_key = BN_new(); 115 if (dest->priv_key == NULL) 116 return NULL; 117 } 118 if (!BN_copy(dest->priv_key, src->priv_key)) 119 return NULL; 120 if (src->group->meth->keycopy 121 && src->group->meth->keycopy(dest, src) == 0) 122 return NULL; 123 } 124 } 125 126 127 /* copy the rest */ 128 dest->enc_flag = src->enc_flag; 129 dest->conv_form = src->conv_form; 130 dest->version = src->version; 131 dest->flags = src->flags; 132 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, 133 &dest->ex_data, &src->ex_data)) 134 return NULL; 135 136 if (src->meth != dest->meth) { 137 #ifndef OPENSSL_NO_ENGINE 138 if (src->engine != NULL && ENGINE_init(src->engine) == 0) 139 return NULL; 140 dest->engine = src->engine; 141 #endif 142 dest->meth = src->meth; 143 } 144 145 if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0) 146 return NULL; 147 148 return dest; 149 } 150 151 EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) 152 { 153 EC_KEY *ret = EC_KEY_new_method(ec_key->engine); 154 155 if (ret == NULL) 156 return NULL; 157 158 if (EC_KEY_copy(ret, ec_key) == NULL) { 159 EC_KEY_free(ret); 160 return NULL; 161 } 162 return ret; 163 } 164 165 int EC_KEY_up_ref(EC_KEY *r) 166 { 167 int i; 168 169 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) 170 return 0; 171 172 REF_PRINT_COUNT("EC_KEY", r); 173 REF_ASSERT_ISNT(i < 2); 174 return ((i > 1) ? 1 : 0); 175 } 176 177 ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey) 178 { 179 return eckey->engine; 180 } 181 182 int EC_KEY_generate_key(EC_KEY *eckey) 183 { 184 if (eckey == NULL || eckey->group == NULL) { 185 ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); 186 return 0; 187 } 188 if (eckey->meth->keygen != NULL) 189 return eckey->meth->keygen(eckey); 190 ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED); 191 return 0; 192 } 193 194 int ossl_ec_key_gen(EC_KEY *eckey) 195 { 196 return eckey->group->meth->keygen(eckey); 197 } 198 199 int ec_key_simple_generate_key(EC_KEY *eckey) 200 { 201 int ok = 0; 202 BN_CTX *ctx = NULL; 203 BIGNUM *priv_key = NULL; 204 const BIGNUM *order = NULL; 205 EC_POINT *pub_key = NULL; 206 207 if ((ctx = BN_CTX_new()) == NULL) 208 goto err; 209 210 if (eckey->priv_key == NULL) { 211 priv_key = BN_new(); 212 if (priv_key == NULL) 213 goto err; 214 } else 215 priv_key = eckey->priv_key; 216 217 order = EC_GROUP_get0_order(eckey->group); 218 if (order == NULL) 219 goto err; 220 221 do 222 if (!BN_priv_rand_range(priv_key, order)) 223 goto err; 224 while (BN_is_zero(priv_key)) ; 225 226 if (eckey->pub_key == NULL) { 227 pub_key = EC_POINT_new(eckey->group); 228 if (pub_key == NULL) 229 goto err; 230 } else 231 pub_key = eckey->pub_key; 232 233 if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) 234 goto err; 235 236 eckey->priv_key = priv_key; 237 eckey->pub_key = pub_key; 238 239 ok = 1; 240 241 err: 242 if (eckey->pub_key == NULL) 243 EC_POINT_free(pub_key); 244 if (eckey->priv_key != priv_key) 245 BN_free(priv_key); 246 BN_CTX_free(ctx); 247 return ok; 248 } 249 250 int ec_key_simple_generate_public_key(EC_KEY *eckey) 251 { 252 return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL, 253 NULL, NULL); 254 } 255 256 int EC_KEY_check_key(const EC_KEY *eckey) 257 { 258 if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { 259 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); 260 return 0; 261 } 262 263 if (eckey->group->meth->keycheck == NULL) { 264 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 265 return 0; 266 } 267 268 return eckey->group->meth->keycheck(eckey); 269 } 270 271 int ec_key_simple_check_key(const EC_KEY *eckey) 272 { 273 int ok = 0; 274 BN_CTX *ctx = NULL; 275 const BIGNUM *order = NULL; 276 EC_POINT *point = NULL; 277 278 if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { 279 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); 280 return 0; 281 } 282 283 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { 284 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY); 285 goto err; 286 } 287 288 if ((ctx = BN_CTX_new()) == NULL) 289 goto err; 290 if ((point = EC_POINT_new(eckey->group)) == NULL) 291 goto err; 292 293 /* testing whether the pub_key is on the elliptic curve */ 294 if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { 295 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); 296 goto err; 297 } 298 /* testing whether pub_key * order is the point at infinity */ 299 order = eckey->group->order; 300 if (BN_is_zero(order)) { 301 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); 302 goto err; 303 } 304 if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { 305 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB); 306 goto err; 307 } 308 if (!EC_POINT_is_at_infinity(eckey->group, point)) { 309 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER); 310 goto err; 311 } 312 /* 313 * in case the priv_key is present : check if generator * priv_key == 314 * pub_key 315 */ 316 if (eckey->priv_key != NULL) { 317 if (BN_cmp(eckey->priv_key, order) >= 0) { 318 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER); 319 goto err; 320 } 321 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, 322 NULL, NULL, ctx)) { 323 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB); 324 goto err; 325 } 326 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { 327 ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); 328 goto err; 329 } 330 } 331 ok = 1; 332 err: 333 BN_CTX_free(ctx); 334 EC_POINT_free(point); 335 return ok; 336 } 337 338 int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, 339 BIGNUM *y) 340 { 341 BN_CTX *ctx = NULL; 342 BIGNUM *tx, *ty; 343 EC_POINT *point = NULL; 344 int ok = 0; 345 346 if (key == NULL || key->group == NULL || x == NULL || y == NULL) { 347 ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 348 ERR_R_PASSED_NULL_PARAMETER); 349 return 0; 350 } 351 ctx = BN_CTX_new(); 352 if (ctx == NULL) 353 return 0; 354 355 BN_CTX_start(ctx); 356 point = EC_POINT_new(key->group); 357 358 if (point == NULL) 359 goto err; 360 361 tx = BN_CTX_get(ctx); 362 ty = BN_CTX_get(ctx); 363 if (ty == NULL) 364 goto err; 365 366 if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx)) 367 goto err; 368 if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx)) 369 goto err; 370 371 /* 372 * Check if retrieved coordinates match originals and are less than field 373 * order: if not values are out of range. 374 */ 375 if (BN_cmp(x, tx) || BN_cmp(y, ty) 376 || (BN_cmp(x, key->group->field) >= 0) 377 || (BN_cmp(y, key->group->field) >= 0)) { 378 ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 379 EC_R_COORDINATES_OUT_OF_RANGE); 380 goto err; 381 } 382 383 if (!EC_KEY_set_public_key(key, point)) 384 goto err; 385 386 if (EC_KEY_check_key(key) == 0) 387 goto err; 388 389 ok = 1; 390 391 err: 392 BN_CTX_end(ctx); 393 BN_CTX_free(ctx); 394 EC_POINT_free(point); 395 return ok; 396 397 } 398 399 const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) 400 { 401 return key->group; 402 } 403 404 int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) 405 { 406 if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0) 407 return 0; 408 EC_GROUP_free(key->group); 409 key->group = EC_GROUP_dup(group); 410 return (key->group == NULL) ? 0 : 1; 411 } 412 413 const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) 414 { 415 return key->priv_key; 416 } 417 418 int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) 419 { 420 int fixed_top; 421 const BIGNUM *order = NULL; 422 BIGNUM *tmp_key = NULL; 423 424 if (key->group == NULL || key->group->meth == NULL) 425 return 0; 426 427 /* 428 * Not only should key->group be set, but it should also be in a valid 429 * fully initialized state. 430 * 431 * Specifically, to operate in constant time, we need that the group order 432 * is set, as we use its length as the fixed public size of any scalar used 433 * as an EC private key. 434 */ 435 order = EC_GROUP_get0_order(key->group); 436 if (order == NULL || BN_is_zero(order)) 437 return 0; /* This should never happen */ 438 439 if (key->group->meth->set_private != NULL 440 && key->group->meth->set_private(key, priv_key) == 0) 441 return 0; 442 if (key->meth->set_private != NULL 443 && key->meth->set_private(key, priv_key) == 0) 444 return 0; 445 446 /* 447 * We should never leak the bit length of the secret scalar in the key, 448 * so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM` 449 * holding the secret scalar. 450 * 451 * This is important also because `BN_dup()` (and `BN_copy()`) do not 452 * propagate the `BN_FLG_CONSTTIME` flag from the source `BIGNUM`, and 453 * this brings an extra risk of inadvertently losing the flag, even when 454 * the caller specifically set it. 455 * 456 * The propagation has been turned on and off a few times in the past 457 * years because in some conditions has shown unintended consequences in 458 * some code paths, so at the moment we can't fix this in the BN layer. 459 * 460 * In `EC_KEY_set_private_key()` we can work around the propagation by 461 * manually setting the flag after `BN_dup()` as we know for sure that 462 * inside the EC module the `BN_FLG_CONSTTIME` is always treated 463 * correctly and should not generate unintended consequences. 464 * 465 * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have 466 * to preallocate the BIGNUM internal buffer to a fixed public size big 467 * enough that operations performed during the processing never trigger 468 * a realloc which would leak the size of the scalar through memory 469 * accesses. 470 * 471 * Fixed Length 472 * ------------ 473 * 474 * The order of the large prime subgroup of the curve is our choice for 475 * a fixed public size, as that is generally the upper bound for 476 * generating a private key in EC cryptosystems and should fit all valid 477 * secret scalars. 478 * 479 * For preallocating the BIGNUM storage we look at the number of "words" 480 * required for the internal representation of the order, and we 481 * preallocate 2 extra "words" in case any of the subsequent processing 482 * might temporarily overflow the order length. 483 */ 484 tmp_key = BN_dup(priv_key); 485 if (tmp_key == NULL) 486 return 0; 487 488 BN_set_flags(tmp_key, BN_FLG_CONSTTIME); 489 490 fixed_top = bn_get_top(order) + 2; 491 if (bn_wexpand(tmp_key, fixed_top) == NULL) { 492 BN_clear_free(tmp_key); 493 return 0; 494 } 495 496 BN_clear_free(key->priv_key); 497 key->priv_key = tmp_key; 498 499 return 1; 500 } 501 502 const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) 503 { 504 return key->pub_key; 505 } 506 507 int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) 508 { 509 if (key->meth->set_public != NULL 510 && key->meth->set_public(key, pub_key) == 0) 511 return 0; 512 EC_POINT_free(key->pub_key); 513 key->pub_key = EC_POINT_dup(pub_key, key->group); 514 return (key->pub_key == NULL) ? 0 : 1; 515 } 516 517 unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) 518 { 519 return key->enc_flag; 520 } 521 522 void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) 523 { 524 key->enc_flag = flags; 525 } 526 527 point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) 528 { 529 return key->conv_form; 530 } 531 532 void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) 533 { 534 key->conv_form = cform; 535 if (key->group != NULL) 536 EC_GROUP_set_point_conversion_form(key->group, cform); 537 } 538 539 void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) 540 { 541 if (key->group != NULL) 542 EC_GROUP_set_asn1_flag(key->group, flag); 543 } 544 545 int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) 546 { 547 if (key->group == NULL) 548 return 0; 549 return EC_GROUP_precompute_mult(key->group, ctx); 550 } 551 552 int EC_KEY_get_flags(const EC_KEY *key) 553 { 554 return key->flags; 555 } 556 557 void EC_KEY_set_flags(EC_KEY *key, int flags) 558 { 559 key->flags |= flags; 560 } 561 562 void EC_KEY_clear_flags(EC_KEY *key, int flags) 563 { 564 key->flags &= ~flags; 565 } 566 567 int EC_KEY_decoded_from_explicit_params(const EC_KEY *key) 568 { 569 if (key == NULL || key->group == NULL) 570 return -1; 571 return key->group->decoded_from_explicit_params; 572 } 573 574 size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, 575 unsigned char **pbuf, BN_CTX *ctx) 576 { 577 if (key == NULL || key->pub_key == NULL || key->group == NULL) 578 return 0; 579 return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx); 580 } 581 582 int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, 583 BN_CTX *ctx) 584 { 585 if (key == NULL || key->group == NULL) 586 return 0; 587 if (key->pub_key == NULL) 588 key->pub_key = EC_POINT_new(key->group); 589 if (key->pub_key == NULL) 590 return 0; 591 if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0) 592 return 0; 593 /* 594 * Save the point conversion form. 595 * For non-custom curves the first octet of the buffer (excluding 596 * the last significant bit) contains the point conversion form. 597 * EC_POINT_oct2point() has already performed sanity checking of 598 * the buffer so we know it is valid. 599 */ 600 if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) 601 key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01); 602 return 1; 603 } 604 605 size_t EC_KEY_priv2oct(const EC_KEY *eckey, 606 unsigned char *buf, size_t len) 607 { 608 if (eckey->group == NULL || eckey->group->meth == NULL) 609 return 0; 610 if (eckey->group->meth->priv2oct == NULL) { 611 ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 612 return 0; 613 } 614 615 return eckey->group->meth->priv2oct(eckey, buf, len); 616 } 617 618 size_t ec_key_simple_priv2oct(const EC_KEY *eckey, 619 unsigned char *buf, size_t len) 620 { 621 size_t buf_len; 622 623 buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8; 624 if (eckey->priv_key == NULL) 625 return 0; 626 if (buf == NULL) 627 return buf_len; 628 else if (len < buf_len) 629 return 0; 630 631 /* Octetstring may need leading zeros if BN is to short */ 632 633 if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) { 634 ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL); 635 return 0; 636 } 637 638 return buf_len; 639 } 640 641 int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len) 642 { 643 if (eckey->group == NULL || eckey->group->meth == NULL) 644 return 0; 645 if (eckey->group->meth->oct2priv == NULL) { 646 ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 647 return 0; 648 } 649 return eckey->group->meth->oct2priv(eckey, buf, len); 650 } 651 652 int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len) 653 { 654 if (eckey->priv_key == NULL) 655 eckey->priv_key = BN_secure_new(); 656 if (eckey->priv_key == NULL) { 657 ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE); 658 return 0; 659 } 660 eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key); 661 if (eckey->priv_key == NULL) { 662 ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB); 663 return 0; 664 } 665 return 1; 666 } 667 668 size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf) 669 { 670 size_t len; 671 unsigned char *buf; 672 673 len = EC_KEY_priv2oct(eckey, NULL, 0); 674 if (len == 0) 675 return 0; 676 if ((buf = OPENSSL_malloc(len)) == NULL) { 677 ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE); 678 return 0; 679 } 680 len = EC_KEY_priv2oct(eckey, buf, len); 681 if (len == 0) { 682 OPENSSL_free(buf); 683 return 0; 684 } 685 *pbuf = buf; 686 return len; 687 } 688 689 int EC_KEY_can_sign(const EC_KEY *eckey) 690 { 691 if (eckey->group == NULL || eckey->group->meth == NULL 692 || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN)) 693 return 0; 694 return 1; 695 } 696