1/*
2 * Copyright 2002-2022 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
19EC_KEY *EC_KEY_new(void)
20{
21    return EC_KEY_new_method(NULL);
22}
23
24EC_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
42void 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
74EC_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
151EC_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
165int 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
177ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey)
178{
179    return eckey->engine;
180}
181
182int 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
194int ossl_ec_key_gen(EC_KEY *eckey)
195{
196    return eckey->group->meth->keygen(eckey);
197}
198
199int 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
250int 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
256int 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
271int 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
338int 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
399const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
400{
401    return key->group;
402}
403
404int 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
413const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
414{
415    return key->priv_key;
416}
417
418int 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     * Return `0` to comply with legacy behavior for this function, see
448     * https://github.com/openssl/openssl/issues/18744#issuecomment-1195175696
449     */
450    if (priv_key == NULL) {
451        BN_clear_free(key->priv_key);
452        key->priv_key = NULL;
453        return 0; /* intentional for legacy compatibility */
454    }
455
456    /*
457     * We should never leak the bit length of the secret scalar in the key,
458     * so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM`
459     * holding the secret scalar.
460     *
461     * This is important also because `BN_dup()` (and `BN_copy()`) do not
462     * propagate the `BN_FLG_CONSTTIME` flag from the source `BIGNUM`, and
463     * this brings an extra risk of inadvertently losing the flag, even when
464     * the caller specifically set it.
465     *
466     * The propagation has been turned on and off a few times in the past
467     * years because in some conditions has shown unintended consequences in
468     * some code paths, so at the moment we can't fix this in the BN layer.
469     *
470     * In `EC_KEY_set_private_key()` we can work around the propagation by
471     * manually setting the flag after `BN_dup()` as we know for sure that
472     * inside the EC module the `BN_FLG_CONSTTIME` is always treated
473     * correctly and should not generate unintended consequences.
474     *
475     * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
476     * to preallocate the BIGNUM internal buffer to a fixed public size big
477     * enough that operations performed during the processing never trigger
478     * a realloc which would leak the size of the scalar through memory
479     * accesses.
480     *
481     * Fixed Length
482     * ------------
483     *
484     * The order of the large prime subgroup of the curve is our choice for
485     * a fixed public size, as that is generally the upper bound for
486     * generating a private key in EC cryptosystems and should fit all valid
487     * secret scalars.
488     *
489     * For preallocating the BIGNUM storage we look at the number of "words"
490     * required for the internal representation of the order, and we
491     * preallocate 2 extra "words" in case any of the subsequent processing
492     * might temporarily overflow the order length.
493     */
494    tmp_key = BN_dup(priv_key);
495    if (tmp_key == NULL)
496        return 0;
497
498    BN_set_flags(tmp_key, BN_FLG_CONSTTIME);
499
500    fixed_top = bn_get_top(order) + 2;
501    if (bn_wexpand(tmp_key, fixed_top) == NULL) {
502        BN_clear_free(tmp_key);
503        return 0;
504    }
505
506    BN_clear_free(key->priv_key);
507    key->priv_key = tmp_key;
508
509    return 1;
510}
511
512const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
513{
514    return key->pub_key;
515}
516
517int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
518{
519    if (key->meth->set_public != NULL
520        && key->meth->set_public(key, pub_key) == 0)
521        return 0;
522    EC_POINT_free(key->pub_key);
523    key->pub_key = EC_POINT_dup(pub_key, key->group);
524    return (key->pub_key == NULL) ? 0 : 1;
525}
526
527unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
528{
529    return key->enc_flag;
530}
531
532void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
533{
534    key->enc_flag = flags;
535}
536
537point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
538{
539    return key->conv_form;
540}
541
542void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
543{
544    key->conv_form = cform;
545    if (key->group != NULL)
546        EC_GROUP_set_point_conversion_form(key->group, cform);
547}
548
549void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
550{
551    if (key->group != NULL)
552        EC_GROUP_set_asn1_flag(key->group, flag);
553}
554
555int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
556{
557    if (key->group == NULL)
558        return 0;
559    return EC_GROUP_precompute_mult(key->group, ctx);
560}
561
562int EC_KEY_get_flags(const EC_KEY *key)
563{
564    return key->flags;
565}
566
567void EC_KEY_set_flags(EC_KEY *key, int flags)
568{
569    key->flags |= flags;
570}
571
572void EC_KEY_clear_flags(EC_KEY *key, int flags)
573{
574    key->flags &= ~flags;
575}
576
577int EC_KEY_decoded_from_explicit_params(const EC_KEY *key)
578{
579    if (key == NULL || key->group == NULL)
580        return -1;
581    return key->group->decoded_from_explicit_params;
582}
583
584size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
585                        unsigned char **pbuf, BN_CTX *ctx)
586{
587    if (key == NULL || key->pub_key == NULL || key->group == NULL)
588        return 0;
589    return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
590}
591
592int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
593                   BN_CTX *ctx)
594{
595    if (key == NULL || key->group == NULL)
596        return 0;
597    if (key->pub_key == NULL)
598        key->pub_key = EC_POINT_new(key->group);
599    if (key->pub_key == NULL)
600        return 0;
601    if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
602        return 0;
603    /*
604     * Save the point conversion form.
605     * For non-custom curves the first octet of the buffer (excluding
606     * the last significant bit) contains the point conversion form.
607     * EC_POINT_oct2point() has already performed sanity checking of
608     * the buffer so we know it is valid.
609     */
610    if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0)
611        key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01);
612    return 1;
613}
614
615size_t EC_KEY_priv2oct(const EC_KEY *eckey,
616                       unsigned char *buf, size_t len)
617{
618    if (eckey->group == NULL || eckey->group->meth == NULL)
619        return 0;
620    if (eckey->group->meth->priv2oct == NULL) {
621        ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
622        return 0;
623    }
624
625    return eckey->group->meth->priv2oct(eckey, buf, len);
626}
627
628size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
629                              unsigned char *buf, size_t len)
630{
631    size_t buf_len;
632
633    buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8;
634    if (eckey->priv_key == NULL)
635        return 0;
636    if (buf == NULL)
637        return buf_len;
638    else if (len < buf_len)
639        return 0;
640
641    /* Octetstring may need leading zeros if BN is to short */
642
643    if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
644        ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
645        return 0;
646    }
647
648    return buf_len;
649}
650
651int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
652{
653    if (eckey->group == NULL || eckey->group->meth == NULL)
654        return 0;
655    if (eckey->group->meth->oct2priv == NULL) {
656        ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
657        return 0;
658    }
659    return eckey->group->meth->oct2priv(eckey, buf, len);
660}
661
662int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
663{
664    if (eckey->priv_key == NULL)
665        eckey->priv_key = BN_secure_new();
666    if (eckey->priv_key == NULL) {
667        ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE);
668        return 0;
669    }
670    if (BN_bin2bn(buf, len, eckey->priv_key) == NULL) {
671        ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
672        return 0;
673    }
674    return 1;
675}
676
677size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
678{
679    size_t len;
680    unsigned char *buf;
681
682    len = EC_KEY_priv2oct(eckey, NULL, 0);
683    if (len == 0)
684        return 0;
685    if ((buf = OPENSSL_malloc(len)) == NULL) {
686        ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE);
687        return 0;
688    }
689    len = EC_KEY_priv2oct(eckey, buf, len);
690    if (len == 0) {
691        OPENSSL_free(buf);
692        return 0;
693    }
694    *pbuf = buf;
695    return len;
696}
697
698int EC_KEY_can_sign(const EC_KEY *eckey)
699{
700    if (eckey->group == NULL || eckey->group->meth == NULL
701        || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
702        return 0;
703    return 1;
704}
705