0d7370eef9a3faa7400bcca5292bcdb6e4181166
[openssl.git] / crypto / ec / ec_key.c
1 /*
2  * Written by Nils Larsch for the OpenSSL project.
3  */
4 /* ====================================================================
5  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    openssl-core@openssl.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com).
55  *
56  */
57 /* ====================================================================
58  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
59  * Portions originally developed by SUN MICROSYSTEMS, INC., and
60  * contributed to the OpenSSL project.
61  */
62
63 #include <internal/cryptlib.h>
64 #include <string.h>
65 #include "ec_lcl.h"
66 #include <openssl/err.h>
67 #ifndef OPENSSL_NO_ENGINE
68 # include <openssl/engine.h>
69 #endif
70
71 EC_KEY *EC_KEY_new(void)
72 {
73     return EC_KEY_new_method(NULL);
74 }
75
76 EC_KEY *EC_KEY_new_by_curve_name(int nid)
77 {
78     EC_KEY *ret = EC_KEY_new();
79     if (ret == NULL)
80         return NULL;
81     ret->group = EC_GROUP_new_by_curve_name(nid);
82     if (ret->group == NULL) {
83         EC_KEY_free(ret);
84         return NULL;
85     }
86     if (ret->meth->set_group != NULL
87         && ret->meth->set_group(ret, ret->group) == 0) {
88         EC_KEY_free(ret);
89         return NULL;
90     }
91     return ret;
92 }
93
94 void EC_KEY_free(EC_KEY *r)
95 {
96     int i;
97
98     if (r == NULL)
99         return;
100
101     CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
102     REF_PRINT_COUNT("EC_KEY", r);
103     if (i > 0)
104         return;
105     REF_ASSERT_ISNT(i < 0);
106
107     if (r->meth->finish != NULL)
108         r->meth->finish(r);
109
110 #ifndef OPENSSL_NO_ENGINE
111     ENGINE_finish(r->engine);
112 #endif
113
114     if (r->group && r->group->meth->keyfinish)
115         r->group->meth->keyfinish(r);
116
117     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
118     CRYPTO_THREAD_lock_free(r->lock);
119     EC_GROUP_free(r->group);
120     EC_POINT_free(r->pub_key);
121     BN_clear_free(r->priv_key);
122
123     OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
124 }
125
126 EC_KEY *EC_KEY_copy(EC_KEY *dest, EC_KEY *src)
127 {
128     if (dest == NULL || src == NULL) {
129         ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
130         return NULL;
131     }
132     if (src->meth != dest->meth) {
133         if (dest->meth->finish != NULL)
134             dest->meth->finish(dest);
135         if (dest->group && dest->group->meth->keyfinish)
136             dest->group->meth->keyfinish(dest);
137 #ifndef OPENSSL_NO_ENGINE
138         if (ENGINE_finish(dest->engine) == 0)
139             return 0;
140         dest->engine = NULL;
141 #endif
142     }
143     /* copy the parameters */
144     if (src->group != NULL) {
145         const EC_METHOD *meth = EC_GROUP_method_of(src->group);
146         /* clear the old group */
147         EC_GROUP_free(dest->group);
148         dest->group = EC_GROUP_new(meth);
149         if (dest->group == NULL)
150             return NULL;
151         if (!EC_GROUP_copy(dest->group, src->group))
152             return NULL;
153     }
154     /*  copy the public key */
155     if (src->pub_key != NULL && src->group != NULL) {
156         EC_POINT_free(dest->pub_key);
157         dest->pub_key = EC_POINT_new(src->group);
158         if (dest->pub_key == NULL)
159             return NULL;
160         if (!EC_POINT_copy(dest->pub_key, src->pub_key))
161             return NULL;
162     }
163     /* copy the private key */
164     if (src->priv_key != NULL) {
165         if (dest->priv_key == NULL) {
166             dest->priv_key = BN_new();
167             if (dest->priv_key == NULL)
168                 return NULL;
169         }
170         if (!BN_copy(dest->priv_key, src->priv_key))
171             return NULL;
172         if (src->group->meth->keycopy
173             && src->group->meth->keycopy(dest, src) == 0)
174             return NULL;
175     }
176
177
178     /* copy the rest */
179     dest->enc_flag = src->enc_flag;
180     dest->conv_form = src->conv_form;
181     dest->version = src->version;
182     dest->flags = src->flags;
183     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
184                             &dest->ex_data, &src->ex_data))
185         return NULL;
186
187     if (src->meth != dest->meth) {
188 #ifndef OPENSSL_NO_ENGINE
189         if (src->engine != NULL && ENGINE_init(src->engine) == 0)
190             return NULL;
191         dest->engine = src->engine;
192 #endif
193         dest->meth = src->meth;
194     }
195
196     if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
197         return NULL;
198
199     return dest;
200 }
201
202 EC_KEY *EC_KEY_dup(EC_KEY *ec_key)
203 {
204     EC_KEY *ret = EC_KEY_new_method(ec_key->engine);
205
206     if (ret == NULL)
207         return NULL;
208
209     if (EC_KEY_copy(ret, ec_key) == NULL) {
210         EC_KEY_free(ret);
211         return NULL;
212     }
213     return ret;
214 }
215
216 int EC_KEY_up_ref(EC_KEY *r)
217 {
218     int i;
219
220     if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
221         return 0;
222
223     REF_PRINT_COUNT("EC_KEY", r);
224     REF_ASSERT_ISNT(i < 2);
225     return ((i > 1) ? 1 : 0);
226 }
227
228 int EC_KEY_generate_key(EC_KEY *eckey)
229 {
230     if (eckey == NULL || eckey->group == NULL) {
231         ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
232         return 0;
233     }
234     if (eckey->meth->keygen != NULL)
235         return eckey->meth->keygen(eckey);
236     ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
237     return 0;
238 }
239
240 int ossl_ec_key_gen(EC_KEY *eckey)
241 {
242     OPENSSL_assert(eckey->group->meth->keygen != NULL);
243     return eckey->group->meth->keygen(eckey);
244 }
245
246 int ec_key_simple_generate_key(EC_KEY *eckey)
247 {
248     int ok = 0;
249     BN_CTX *ctx = NULL;
250     BIGNUM *priv_key = NULL;
251     const BIGNUM *order = NULL;
252     EC_POINT *pub_key = NULL;
253
254     if ((ctx = BN_CTX_new()) == NULL)
255         goto err;
256
257     if (eckey->priv_key == NULL) {
258         priv_key = BN_new();
259         if (priv_key == NULL)
260             goto err;
261     } else
262         priv_key = eckey->priv_key;
263
264     order = EC_GROUP_get0_order(eckey->group);
265     if (order == NULL)
266         goto err;
267
268     do
269         if (!BN_rand_range(priv_key, order))
270             goto err;
271     while (BN_is_zero(priv_key)) ;
272
273     if (eckey->pub_key == NULL) {
274         pub_key = EC_POINT_new(eckey->group);
275         if (pub_key == NULL)
276             goto err;
277     } else
278         pub_key = eckey->pub_key;
279
280     if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
281         goto err;
282
283     eckey->priv_key = priv_key;
284     eckey->pub_key = pub_key;
285
286     ok = 1;
287
288  err:
289     if (eckey->pub_key == NULL)
290         EC_POINT_free(pub_key);
291     if (eckey->priv_key != priv_key)
292         BN_free(priv_key);
293     BN_CTX_free(ctx);
294     return ok;
295 }
296
297 int ec_key_simple_generate_public_key(EC_KEY *eckey)
298 {
299     return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
300                         NULL, NULL);
301 }
302
303 int EC_KEY_check_key(const EC_KEY *eckey)
304 {
305     if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
306         ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
307         return 0;
308     }
309
310     if (eckey->group->meth->keycheck == NULL) {
311         ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
312         return 0;
313     }
314
315     return eckey->group->meth->keycheck(eckey);
316 }
317
318 int ec_key_simple_check_key(const EC_KEY *eckey)
319 {
320     int ok = 0;
321     BN_CTX *ctx = NULL;
322     const BIGNUM *order = NULL;
323     EC_POINT *point = NULL;
324
325     if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
326         ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
327         return 0;
328     }
329
330     if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
331         ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
332         goto err;
333     }
334
335     if ((ctx = BN_CTX_new()) == NULL)
336         goto err;
337     if ((point = EC_POINT_new(eckey->group)) == NULL)
338         goto err;
339
340     /* testing whether the pub_key is on the elliptic curve */
341     if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
342         ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
343         goto err;
344     }
345     /* testing whether pub_key * order is the point at infinity */
346     order = eckey->group->order;
347     if (BN_is_zero(order)) {
348         ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
349         goto err;
350     }
351     if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
352         ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
353         goto err;
354     }
355     if (!EC_POINT_is_at_infinity(eckey->group, point)) {
356         ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
357         goto err;
358     }
359     /*
360      * in case the priv_key is present : check if generator * priv_key ==
361      * pub_key
362      */
363     if (eckey->priv_key != NULL) {
364         if (BN_cmp(eckey->priv_key, order) >= 0) {
365             ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
366             goto err;
367         }
368         if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
369                           NULL, NULL, ctx)) {
370             ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
371             goto err;
372         }
373         if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
374             ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
375             goto err;
376         }
377     }
378     ok = 1;
379  err:
380     BN_CTX_free(ctx);
381     EC_POINT_free(point);
382     return ok;
383 }
384
385 int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
386                                              BIGNUM *y)
387 {
388     BN_CTX *ctx = NULL;
389     BIGNUM *tx, *ty;
390     EC_POINT *point = NULL;
391     int ok = 0;
392 #ifndef OPENSSL_NO_EC2M
393     int tmp_nid, is_char_two = 0;
394 #endif
395
396     if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
397         ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
398               ERR_R_PASSED_NULL_PARAMETER);
399         return 0;
400     }
401     ctx = BN_CTX_new();
402     if (ctx == NULL)
403         goto err;
404
405     point = EC_POINT_new(key->group);
406
407     if (point == NULL)
408         goto err;
409
410     tx = BN_CTX_get(ctx);
411     ty = BN_CTX_get(ctx);
412     if (ty == NULL)
413         goto err;
414
415 #ifndef OPENSSL_NO_EC2M
416     tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
417
418     if (tmp_nid == NID_X9_62_characteristic_two_field)
419         is_char_two = 1;
420
421     if (is_char_two) {
422         if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
423                                                   x, y, ctx))
424             goto err;
425         if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
426                                                   tx, ty, ctx))
427             goto err;
428     } else
429 #endif
430     {
431         if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
432                                                  x, y, ctx))
433             goto err;
434         if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
435                                                  tx, ty, ctx))
436             goto err;
437     }
438     /*
439      * Check if retrieved coordinates match originals and are less than field
440      * order: if not values are out of range.
441      */
442     if (BN_cmp(x, tx) || BN_cmp(y, ty)
443         || (BN_cmp(x, key->group->field) >= 0)
444         || (BN_cmp(y, key->group->field) >= 0)) {
445         ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
446               EC_R_COORDINATES_OUT_OF_RANGE);
447         goto err;
448     }
449
450     if (!EC_KEY_set_public_key(key, point))
451         goto err;
452
453     if (EC_KEY_check_key(key) == 0)
454         goto err;
455
456     ok = 1;
457
458  err:
459     BN_CTX_free(ctx);
460     EC_POINT_free(point);
461     return ok;
462
463 }
464
465 const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
466 {
467     return key->group;
468 }
469
470 int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
471 {
472     if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0)
473         return 0;
474     EC_GROUP_free(key->group);
475     key->group = EC_GROUP_dup(group);
476     return (key->group == NULL) ? 0 : 1;
477 }
478
479 const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
480 {
481     return key->priv_key;
482 }
483
484 int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
485 {
486     if (key->group == NULL || key->group->meth == NULL)
487         return 0;
488     if (key->group->meth->set_private
489         && key->meth->set_private(key, priv_key) == 0)
490         return 0;
491     if (key->meth->set_private != NULL
492         && key->meth->set_private(key, priv_key) == 0)
493         return 0;
494     BN_clear_free(key->priv_key);
495     key->priv_key = BN_dup(priv_key);
496     return (key->priv_key == NULL) ? 0 : 1;
497 }
498
499 const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
500 {
501     return key->pub_key;
502 }
503
504 int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
505 {
506     if (key->meth->set_public != NULL
507         && key->meth->set_public(key, pub_key) == 0)
508         return 0;
509     EC_POINT_free(key->pub_key);
510     key->pub_key = EC_POINT_dup(pub_key, key->group);
511     return (key->pub_key == NULL) ? 0 : 1;
512 }
513
514 unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
515 {
516     return key->enc_flag;
517 }
518
519 void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
520 {
521     key->enc_flag = flags;
522 }
523
524 point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
525 {
526     return key->conv_form;
527 }
528
529 void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
530 {
531     key->conv_form = cform;
532     if (key->group != NULL)
533         EC_GROUP_set_point_conversion_form(key->group, cform);
534 }
535
536 void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
537 {
538     if (key->group != NULL)
539         EC_GROUP_set_asn1_flag(key->group, flag);
540 }
541
542 int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
543 {
544     if (key->group == NULL)
545         return 0;
546     return EC_GROUP_precompute_mult(key->group, ctx);
547 }
548
549 int EC_KEY_get_flags(const EC_KEY *key)
550 {
551     return key->flags;
552 }
553
554 void EC_KEY_set_flags(EC_KEY *key, int flags)
555 {
556     key->flags |= flags;
557 }
558
559 void EC_KEY_clear_flags(EC_KEY *key, int flags)
560 {
561     key->flags &= ~flags;
562 }
563
564 size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
565                         unsigned char **pbuf, BN_CTX *ctx)
566 {
567     if (key == NULL || key->pub_key == NULL || key->group == NULL)
568         return 0;
569     return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
570 }
571
572 int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
573                    BN_CTX *ctx)
574 {
575     if (key == NULL || key->group == NULL)
576         return 0;
577     if (key->pub_key == NULL)
578         key->pub_key = EC_POINT_new(key->group);
579     if (key->pub_key == NULL)
580         return 0;
581     if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
582         return 0;
583     /*
584      * Save the point conversion form.
585      * For non-custom curves the first octet of the buffer (excluding
586      * the last significant bit) contains the point conversion form.
587      * EC_POINT_oct2point() has already performed sanity checking of
588      * the buffer so we know it is valid.
589      */
590     if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0)
591         key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01);
592     return 1;
593 }
594
595 size_t EC_KEY_priv2oct(const EC_KEY *eckey, unsigned char *buf, size_t len)
596 {
597     if (eckey->group == NULL || eckey->group->meth == NULL)
598         return 0;
599     if (eckey->group->meth->priv2oct == NULL) {
600         ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
601         return 0;
602     }
603
604     return eckey->group->meth->priv2oct(eckey, buf, len);
605 }
606
607 size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
608                               unsigned char *buf, size_t len)
609 {
610     size_t buf_len;
611
612     buf_len = (EC_GROUP_get_degree(eckey->group) + 7) / 8;
613     if (eckey->priv_key == NULL)
614         return 0;
615     if (buf == NULL)
616         return buf_len;
617     else if (len < buf_len)
618         return 0;
619
620     /* Octetstring may need leading zeros if BN is to short */
621
622     if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
623         ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
624         return 0;
625     }
626
627     return buf_len;
628 }
629
630 int EC_KEY_oct2priv(EC_KEY *eckey, unsigned char *buf, size_t len)
631 {
632     if (eckey->group == NULL || eckey->group->meth == NULL)
633         return 0;
634     if (eckey->group->meth->oct2priv == NULL) {
635         ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
636         return 0;
637     }
638     return eckey->group->meth->oct2priv(eckey, buf, len);
639 }
640
641 int ec_key_simple_oct2priv(EC_KEY *eckey, unsigned char *buf, size_t len)
642 {
643     if (eckey->priv_key == NULL)
644         eckey->priv_key = BN_secure_new();
645     if (eckey->priv_key == NULL) {
646         ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE);
647         return 0;
648     }
649     eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key);
650     if (eckey->priv_key == NULL) {
651         ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
652         return 0;
653     }
654     return 1;
655 }
656
657 size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
658 {
659     size_t len;
660     unsigned char *buf;
661     len = EC_KEY_priv2oct(eckey, NULL, 0);
662     if (len == 0)
663         return 0;
664     buf = OPENSSL_malloc(len);
665     if (buf == NULL)
666         return 0;
667     len = EC_KEY_priv2oct(eckey, buf, len);
668     if (len == 0) {
669         OPENSSL_free(buf);
670         return 0;
671     }
672     *pbuf = buf;
673     return len;
674 }
675
676 int EC_KEY_can_sign(const EC_KEY *eckey)
677 {
678     if (eckey->group == NULL || eckey->group->meth == NULL
679         || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
680         return 0;
681     return 1;
682 }