ec_asn1.c revision 325335
1/* crypto/ec/ec_asn1.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 *    software must display the following acknowledgment:
22 *    "This product includes software developed by the OpenSSL Project
23 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 *    endorse or promote products derived from this software without
27 *    prior written permission. For written permission, please contact
28 *    licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 *    nor may "OpenSSL" appear in their names without prior written
32 *    permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 *    acknowledgment:
36 *    "This product includes software developed by the OpenSSL Project
37 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com).  This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <string.h>
60#include "ec_lcl.h"
61#include <openssl/err.h>
62#include <openssl/asn1t.h>
63#include <openssl/objects.h>
64
65#define OSSL_NELEM(x)    (sizeof(x)/sizeof(x[0]))
66
67int EC_GROUP_get_basis_type(const EC_GROUP *group)
68{
69    int i;
70
71    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
72        NID_X9_62_characteristic_two_field)
73        /* everything else is currently not supported */
74        return 0;
75
76    /* Find the last non-zero element of group->poly[] */
77    for (i = 0;
78         i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0;
79         i++)
80        continue;
81
82    if (i == 4)
83        return NID_X9_62_ppBasis;
84    else if (i == 2)
85        return NID_X9_62_tpBasis;
86    else
87        /* everything else is currently not supported */
88        return 0;
89}
90
91#ifndef OPENSSL_NO_EC2M
92int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
93{
94    if (group == NULL)
95        return 0;
96
97    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
98        NID_X9_62_characteristic_two_field
99        || !((group->poly[0] != 0) && (group->poly[1] != 0)
100             && (group->poly[2] == 0))) {
101        ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
102              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
103        return 0;
104    }
105
106    if (k)
107        *k = group->poly[1];
108
109    return 1;
110}
111
112int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
113                                   unsigned int *k2, unsigned int *k3)
114{
115    if (group == NULL)
116        return 0;
117
118    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
119        NID_X9_62_characteristic_two_field
120        || !((group->poly[0] != 0) && (group->poly[1] != 0)
121             && (group->poly[2] != 0) && (group->poly[3] != 0)
122             && (group->poly[4] == 0))) {
123        ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
124              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
125        return 0;
126    }
127
128    if (k1)
129        *k1 = group->poly[3];
130    if (k2)
131        *k2 = group->poly[2];
132    if (k3)
133        *k3 = group->poly[1];
134
135    return 1;
136}
137#endif
138
139/* some structures needed for the asn1 encoding */
140typedef struct x9_62_pentanomial_st {
141    long k1;
142    long k2;
143    long k3;
144} X9_62_PENTANOMIAL;
145
146typedef struct x9_62_characteristic_two_st {
147    long m;
148    ASN1_OBJECT *type;
149    union {
150        char *ptr;
151        /* NID_X9_62_onBasis */
152        ASN1_NULL *onBasis;
153        /* NID_X9_62_tpBasis */
154        ASN1_INTEGER *tpBasis;
155        /* NID_X9_62_ppBasis */
156        X9_62_PENTANOMIAL *ppBasis;
157        /* anything else */
158        ASN1_TYPE *other;
159    } p;
160} X9_62_CHARACTERISTIC_TWO;
161
162typedef struct x9_62_fieldid_st {
163    ASN1_OBJECT *fieldType;
164    union {
165        char *ptr;
166        /* NID_X9_62_prime_field */
167        ASN1_INTEGER *prime;
168        /* NID_X9_62_characteristic_two_field */
169        X9_62_CHARACTERISTIC_TWO *char_two;
170        /* anything else */
171        ASN1_TYPE *other;
172    } p;
173} X9_62_FIELDID;
174
175typedef struct x9_62_curve_st {
176    ASN1_OCTET_STRING *a;
177    ASN1_OCTET_STRING *b;
178    ASN1_BIT_STRING *seed;
179} X9_62_CURVE;
180
181typedef struct ec_parameters_st {
182    long version;
183    X9_62_FIELDID *fieldID;
184    X9_62_CURVE *curve;
185    ASN1_OCTET_STRING *base;
186    ASN1_INTEGER *order;
187    ASN1_INTEGER *cofactor;
188} ECPARAMETERS;
189
190struct ecpk_parameters_st {
191    int type;
192    union {
193        ASN1_OBJECT *named_curve;
194        ECPARAMETERS *parameters;
195        ASN1_NULL *implicitlyCA;
196    } value;
197} /* ECPKPARAMETERS */ ;
198
199/* SEC1 ECPrivateKey */
200typedef struct ec_privatekey_st {
201    long version;
202    ASN1_OCTET_STRING *privateKey;
203    ECPKPARAMETERS *parameters;
204    ASN1_BIT_STRING *publicKey;
205} EC_PRIVATEKEY;
206
207/* the OpenSSL ASN.1 definitions */
208ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
209        ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
210        ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
211        ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
212} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
213
214DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
215IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
216
217ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
218
219ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
220        ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
221        ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
222        ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
223} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
224
225ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
226        ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
227        ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
228        ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
229} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
230
231DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
232IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
233
234ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
235
236ASN1_ADB(X9_62_FIELDID) = {
237        ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
238        ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
239} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
240
241ASN1_SEQUENCE(X9_62_FIELDID) = {
242        ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
243        ASN1_ADB_OBJECT(X9_62_FIELDID)
244} ASN1_SEQUENCE_END(X9_62_FIELDID)
245
246ASN1_SEQUENCE(X9_62_CURVE) = {
247        ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
248        ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
249        ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
250} ASN1_SEQUENCE_END(X9_62_CURVE)
251
252ASN1_SEQUENCE(ECPARAMETERS) = {
253        ASN1_SIMPLE(ECPARAMETERS, version, LONG),
254        ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
255        ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
256        ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
257        ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
258        ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
259} ASN1_SEQUENCE_END(ECPARAMETERS)
260
261DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
262IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
263
264ASN1_CHOICE(ECPKPARAMETERS) = {
265        ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
266        ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
267        ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
268} ASN1_CHOICE_END(ECPKPARAMETERS)
269
270DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
271DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
272IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
273
274ASN1_SEQUENCE(EC_PRIVATEKEY) = {
275        ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
276        ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
277        ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
278        ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
279} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
280
281DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
282DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
283IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
284
285/* some declarations of internal function */
286
287/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
288static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
289/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
290static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
291/*
292 * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS
293 * object
294 */
295static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
296/*
297 * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP
298 * object
299 */
300static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,
301                                              ECPARAMETERS *);
302/*
303 * ec_asn1_pkparameters2group() creates a EC_GROUP object from a
304 * ECPKPARAMETERS object
305 */
306static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
307/*
308 * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
309 * EC_GROUP object
310 */
311static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
312                                                  ECPKPARAMETERS *);
313
314/* the function definitions */
315
316static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
317{
318    int ok = 0, nid;
319    BIGNUM *tmp = NULL;
320
321    if (group == NULL || field == NULL)
322        return 0;
323
324    /* clear the old values (if necessary) */
325    if (field->fieldType != NULL)
326        ASN1_OBJECT_free(field->fieldType);
327    if (field->p.other != NULL)
328        ASN1_TYPE_free(field->p.other);
329
330    nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
331    /* set OID for the field */
332    if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
333        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
334        goto err;
335    }
336
337    if (nid == NID_X9_62_prime_field) {
338        if ((tmp = BN_new()) == NULL) {
339            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
340            goto err;
341        }
342        /* the parameters are specified by the prime number p */
343        if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
344            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
345            goto err;
346        }
347        /* set the prime number */
348        field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
349        if (field->p.prime == NULL) {
350            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
351            goto err;
352        }
353    } else                      /* nid == NID_X9_62_characteristic_two_field */
354#ifdef OPENSSL_NO_EC2M
355    {
356        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
357        goto err;
358    }
359#else
360    {
361        int field_type;
362        X9_62_CHARACTERISTIC_TWO *char_two;
363
364        field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
365        char_two = field->p.char_two;
366
367        if (char_two == NULL) {
368            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
369            goto err;
370        }
371
372        char_two->m = (long)EC_GROUP_get_degree(group);
373
374        field_type = EC_GROUP_get_basis_type(group);
375
376        if (field_type == 0) {
377            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
378            goto err;
379        }
380        /* set base type OID */
381        if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
382            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
383            goto err;
384        }
385
386        if (field_type == NID_X9_62_tpBasis) {
387            unsigned int k;
388
389            if (!EC_GROUP_get_trinomial_basis(group, &k))
390                goto err;
391
392            char_two->p.tpBasis = ASN1_INTEGER_new();
393            if (!char_two->p.tpBasis) {
394                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
395                goto err;
396            }
397            if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) {
398                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
399                goto err;
400            }
401        } else if (field_type == NID_X9_62_ppBasis) {
402            unsigned int k1, k2, k3;
403
404            if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
405                goto err;
406
407            char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
408            if (!char_two->p.ppBasis) {
409                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
410                goto err;
411            }
412
413            /* set k? values */
414            char_two->p.ppBasis->k1 = (long)k1;
415            char_two->p.ppBasis->k2 = (long)k2;
416            char_two->p.ppBasis->k3 = (long)k3;
417        } else {                /* field_type == NID_X9_62_onBasis */
418
419            /* for ONB the parameters are (asn1) NULL */
420            char_two->p.onBasis = ASN1_NULL_new();
421            if (!char_two->p.onBasis) {
422                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
423                goto err;
424            }
425        }
426    }
427#endif
428
429    ok = 1;
430
431 err:if (tmp)
432        BN_free(tmp);
433    return (ok);
434}
435
436static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
437{
438    int ok = 0, nid;
439    BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
440    unsigned char *buffer_1 = NULL, *buffer_2 = NULL,
441        *a_buf = NULL, *b_buf = NULL;
442    size_t len_1, len_2;
443    unsigned char char_zero = 0;
444
445    if (!group || !curve || !curve->a || !curve->b)
446        return 0;
447
448    if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
449        ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
450        goto err;
451    }
452
453    nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
454
455    /* get a and b */
456    if (nid == NID_X9_62_prime_field) {
457        if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
458            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
459            goto err;
460        }
461    }
462#ifndef OPENSSL_NO_EC2M
463    else {                      /* nid == NID_X9_62_characteristic_two_field */
464
465        if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
466            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
467            goto err;
468        }
469    }
470#endif
471    len_1 = (size_t)BN_num_bytes(tmp_1);
472    len_2 = (size_t)BN_num_bytes(tmp_2);
473
474    if (len_1 == 0) {
475        /* len_1 == 0 => a == 0 */
476        a_buf = &char_zero;
477        len_1 = 1;
478    } else {
479        if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) {
480            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
481            goto err;
482        }
483        if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
484            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
485            goto err;
486        }
487        a_buf = buffer_1;
488    }
489
490    if (len_2 == 0) {
491        /* len_2 == 0 => b == 0 */
492        b_buf = &char_zero;
493        len_2 = 1;
494    } else {
495        if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) {
496            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
497            goto err;
498        }
499        if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
500            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
501            goto err;
502        }
503        b_buf = buffer_2;
504    }
505
506    /* set a and b */
507    if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
508        !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) {
509        ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
510        goto err;
511    }
512
513    /* set the seed (optional) */
514    if (group->seed) {
515        if (!curve->seed)
516            if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
517                ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
518                goto err;
519            }
520        curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
521        curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
522        if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
523                                 (int)group->seed_len)) {
524            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
525            goto err;
526        }
527    } else {
528        if (curve->seed) {
529            ASN1_BIT_STRING_free(curve->seed);
530            curve->seed = NULL;
531        }
532    }
533
534    ok = 1;
535
536 err:if (buffer_1)
537        OPENSSL_free(buffer_1);
538    if (buffer_2)
539        OPENSSL_free(buffer_2);
540    if (tmp_1)
541        BN_free(tmp_1);
542    if (tmp_2)
543        BN_free(tmp_2);
544    return (ok);
545}
546
547static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
548                                              ECPARAMETERS *param)
549{
550    int ok = 0;
551    size_t len = 0;
552    ECPARAMETERS *ret = NULL;
553    BIGNUM *tmp = NULL;
554    unsigned char *buffer = NULL;
555    const EC_POINT *point = NULL;
556    point_conversion_form_t form;
557
558    if ((tmp = BN_new()) == NULL) {
559        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
560        goto err;
561    }
562
563    if (param == NULL) {
564        if ((ret = ECPARAMETERS_new()) == NULL) {
565            ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
566            goto err;
567        }
568    } else
569        ret = param;
570
571    /* set the version (always one) */
572    ret->version = (long)0x1;
573
574    /* set the fieldID */
575    if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
576        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
577        goto err;
578    }
579
580    /* set the curve */
581    if (!ec_asn1_group2curve(group, ret->curve)) {
582        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
583        goto err;
584    }
585
586    /* set the base point */
587    if ((point = EC_GROUP_get0_generator(group)) == NULL) {
588        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
589        goto err;
590    }
591
592    form = EC_GROUP_get_point_conversion_form(group);
593
594    len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
595    if (len == 0) {
596        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
597        goto err;
598    }
599    if ((buffer = OPENSSL_malloc(len)) == NULL) {
600        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
601        goto err;
602    }
603    if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) {
604        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
605        goto err;
606    }
607    if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
608        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
609        goto err;
610    }
611    if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) {
612        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
613        goto err;
614    }
615
616    /* set the order */
617    if (!EC_GROUP_get_order(group, tmp, NULL)) {
618        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
619        goto err;
620    }
621    ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
622    if (ret->order == NULL) {
623        ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
624        goto err;
625    }
626
627    /* set the cofactor (optional) */
628    if (EC_GROUP_get_cofactor(group, tmp, NULL)) {
629        ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
630        if (ret->cofactor == NULL) {
631            ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
632            goto err;
633        }
634    }
635
636    ok = 1;
637
638 err:if (!ok) {
639        if (ret && !param)
640            ECPARAMETERS_free(ret);
641        ret = NULL;
642    }
643    if (tmp)
644        BN_free(tmp);
645    if (buffer)
646        OPENSSL_free(buffer);
647    return (ret);
648}
649
650ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
651                                           ECPKPARAMETERS *params)
652{
653    int ok = 1, tmp;
654    ECPKPARAMETERS *ret = params;
655
656    if (ret == NULL) {
657        if ((ret = ECPKPARAMETERS_new()) == NULL) {
658            ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE);
659            return NULL;
660        }
661    } else {
662        if (ret->type == 0 && ret->value.named_curve)
663            ASN1_OBJECT_free(ret->value.named_curve);
664        else if (ret->type == 1 && ret->value.parameters)
665            ECPARAMETERS_free(ret->value.parameters);
666    }
667
668    if (EC_GROUP_get_asn1_flag(group)) {
669        /*
670         * use the asn1 OID to describe the the elliptic curve parameters
671         */
672        tmp = EC_GROUP_get_curve_name(group);
673        if (tmp) {
674            ret->type = 0;
675            if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
676                ok = 0;
677        } else
678            /* we don't kmow the nid => ERROR */
679            ok = 0;
680    } else {
681        /* use the ECPARAMETERS structure */
682        ret->type = 1;
683        if ((ret->value.parameters =
684             ec_asn1_group2parameters(group, NULL)) == NULL)
685            ok = 0;
686    }
687
688    if (!ok) {
689        ECPKPARAMETERS_free(ret);
690        return NULL;
691    }
692    return ret;
693}
694
695static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
696{
697    int ok = 0, tmp;
698    EC_GROUP *ret = NULL;
699    BIGNUM *p = NULL, *a = NULL, *b = NULL;
700    EC_POINT *point = NULL;
701    long field_bits;
702
703    if (!params->fieldID || !params->fieldID->fieldType ||
704        !params->fieldID->p.ptr) {
705        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
706        goto err;
707    }
708
709    /* now extract the curve parameters a and b */
710    if (!params->curve || !params->curve->a ||
711        !params->curve->a->data || !params->curve->b ||
712        !params->curve->b->data) {
713        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
714        goto err;
715    }
716    a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
717    if (a == NULL) {
718        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
719        goto err;
720    }
721    b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
722    if (b == NULL) {
723        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
724        goto err;
725    }
726
727    /* get the field parameters */
728    tmp = OBJ_obj2nid(params->fieldID->fieldType);
729    if (tmp == NID_X9_62_characteristic_two_field)
730#ifdef OPENSSL_NO_EC2M
731    {
732        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
733        goto err;
734    }
735#else
736    {
737        X9_62_CHARACTERISTIC_TWO *char_two;
738
739        char_two = params->fieldID->p.char_two;
740
741        field_bits = char_two->m;
742        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
743            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
744            goto err;
745        }
746
747        if ((p = BN_new()) == NULL) {
748            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
749            goto err;
750        }
751
752        /* get the base type */
753        tmp = OBJ_obj2nid(char_two->type);
754
755        if (tmp == NID_X9_62_tpBasis) {
756            long tmp_long;
757
758            if (!char_two->p.tpBasis) {
759                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
760                goto err;
761            }
762
763            tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
764
765            if (!(char_two->m > tmp_long && tmp_long > 0)) {
766                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
767                      EC_R_INVALID_TRINOMIAL_BASIS);
768                goto err;
769            }
770
771            /* create the polynomial */
772            if (!BN_set_bit(p, (int)char_two->m))
773                goto err;
774            if (!BN_set_bit(p, (int)tmp_long))
775                goto err;
776            if (!BN_set_bit(p, 0))
777                goto err;
778        } else if (tmp == NID_X9_62_ppBasis) {
779            X9_62_PENTANOMIAL *penta;
780
781            penta = char_two->p.ppBasis;
782            if (!penta) {
783                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
784                goto err;
785            }
786
787            if (!
788                (char_two->m > penta->k3 && penta->k3 > penta->k2
789                 && penta->k2 > penta->k1 && penta->k1 > 0)) {
790                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
791                      EC_R_INVALID_PENTANOMIAL_BASIS);
792                goto err;
793            }
794
795            /* create the polynomial */
796            if (!BN_set_bit(p, (int)char_two->m))
797                goto err;
798            if (!BN_set_bit(p, (int)penta->k1))
799                goto err;
800            if (!BN_set_bit(p, (int)penta->k2))
801                goto err;
802            if (!BN_set_bit(p, (int)penta->k3))
803                goto err;
804            if (!BN_set_bit(p, 0))
805                goto err;
806        } else if (tmp == NID_X9_62_onBasis) {
807            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
808            goto err;
809        } else {                /* error */
810
811            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
812            goto err;
813        }
814
815        /* create the EC_GROUP structure */
816        ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
817    }
818#endif
819    else if (tmp == NID_X9_62_prime_field) {
820        /* we have a curve over a prime field */
821        /* extract the prime number */
822        if (!params->fieldID->p.prime) {
823            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
824            goto err;
825        }
826        p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
827        if (p == NULL) {
828            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
829            goto err;
830        }
831
832        if (BN_is_negative(p) || BN_is_zero(p)) {
833            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
834            goto err;
835        }
836
837        field_bits = BN_num_bits(p);
838        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
839            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
840            goto err;
841        }
842
843        /* create the EC_GROUP structure */
844        ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
845    } else {
846        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
847        goto err;
848    }
849
850    if (ret == NULL) {
851        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
852        goto err;
853    }
854
855    /* extract seed (optional) */
856    if (params->curve->seed != NULL) {
857        if (ret->seed != NULL)
858            OPENSSL_free(ret->seed);
859        if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) {
860            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
861            goto err;
862        }
863        memcpy(ret->seed, params->curve->seed->data,
864               params->curve->seed->length);
865        ret->seed_len = params->curve->seed->length;
866    }
867
868    if (!params->order || !params->base || !params->base->data) {
869        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
870        goto err;
871    }
872
873    if ((point = EC_POINT_new(ret)) == NULL)
874        goto err;
875
876    /* set the point conversion form */
877    EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
878                                       (params->base->data[0] & ~0x01));
879
880    /* extract the ec point */
881    if (!EC_POINT_oct2point(ret, point, params->base->data,
882                            params->base->length, NULL)) {
883        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
884        goto err;
885    }
886
887    /* extract the order */
888    if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
889        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
890        goto err;
891    }
892    if (BN_is_negative(a) || BN_is_zero(a)) {
893        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
894        goto err;
895    }
896    if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */
897        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
898        goto err;
899    }
900
901    /* extract the cofactor (optional) */
902    if (params->cofactor == NULL) {
903        if (b) {
904            BN_free(b);
905            b = NULL;
906        }
907    } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
908        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
909        goto err;
910    }
911    /* set the generator, order and cofactor (if present) */
912    if (!EC_GROUP_set_generator(ret, point, a, b)) {
913        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
914        goto err;
915    }
916
917    ok = 1;
918
919 err:if (!ok) {
920        if (ret)
921            EC_GROUP_clear_free(ret);
922        ret = NULL;
923    }
924
925    if (p)
926        BN_free(p);
927    if (a)
928        BN_free(a);
929    if (b)
930        BN_free(b);
931    if (point)
932        EC_POINT_free(point);
933    return (ret);
934}
935
936EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
937{
938    EC_GROUP *ret = NULL;
939    int tmp = 0;
940
941    if (params == NULL) {
942        ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS);
943        return NULL;
944    }
945
946    if (params->type == 0) {    /* the curve is given by an OID */
947        tmp = OBJ_obj2nid(params->value.named_curve);
948        if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
949            ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
950                  EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
951            return NULL;
952        }
953        EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
954    } else if (params->type == 1) { /* the parameters are given by a
955                                     * ECPARAMETERS structure */
956        ret = ec_asn1_parameters2group(params->value.parameters);
957        if (!ret) {
958            ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
959            return NULL;
960        }
961        EC_GROUP_set_asn1_flag(ret, 0x0);
962    } else if (params->type == 2) { /* implicitlyCA */
963        return NULL;
964    } else {
965        ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
966        return NULL;
967    }
968
969    return ret;
970}
971
972/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
973
974EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
975{
976    EC_GROUP *group = NULL;
977    ECPKPARAMETERS *params = NULL;
978    const unsigned char *p = *in;
979
980    if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) {
981        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
982        ECPKPARAMETERS_free(params);
983        return NULL;
984    }
985
986    if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
987        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
988        ECPKPARAMETERS_free(params);
989        return NULL;
990    }
991
992    if (a && *a)
993        EC_GROUP_clear_free(*a);
994    if (a)
995        *a = group;
996
997    ECPKPARAMETERS_free(params);
998    *in = p;
999    return (group);
1000}
1001
1002int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1003{
1004    int ret = 0;
1005    ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
1006    if (tmp == NULL) {
1007        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1008        return 0;
1009    }
1010    if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
1011        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1012        ECPKPARAMETERS_free(tmp);
1013        return 0;
1014    }
1015    ECPKPARAMETERS_free(tmp);
1016    return (ret);
1017}
1018
1019/* some EC_KEY functions */
1020
1021EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1022{
1023    int ok = 0;
1024    EC_KEY *ret = NULL;
1025    EC_PRIVATEKEY *priv_key = NULL;
1026    const unsigned char *p = *in;
1027
1028    if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) {
1029        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1030        return NULL;
1031    }
1032
1033    if (a == NULL || *a == NULL) {
1034        if ((ret = EC_KEY_new()) == NULL) {
1035            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1036            goto err;
1037        }
1038    } else
1039        ret = *a;
1040
1041    if (priv_key->parameters) {
1042        if (ret->group)
1043            EC_GROUP_clear_free(ret->group);
1044        ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1045    }
1046
1047    if (ret->group == NULL) {
1048        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1049        goto err;
1050    }
1051
1052    ret->version = priv_key->version;
1053
1054    if (priv_key->privateKey) {
1055        ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
1056                                  M_ASN1_STRING_length(priv_key->privateKey),
1057                                  ret->priv_key);
1058        if (ret->priv_key == NULL) {
1059            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB);
1060            goto err;
1061        }
1062    } else {
1063        ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY);
1064        goto err;
1065    }
1066
1067    if (ret->pub_key)
1068        EC_POINT_clear_free(ret->pub_key);
1069    ret->pub_key = EC_POINT_new(ret->group);
1070    if (ret->pub_key == NULL) {
1071        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1072        goto err;
1073    }
1074
1075    if (priv_key->publicKey) {
1076        const unsigned char *pub_oct;
1077        int pub_oct_len;
1078
1079        pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
1080        pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1081        /*
1082         * The first byte - point conversion form - must be present.
1083         */
1084        if (pub_oct_len <= 0) {
1085            ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
1086            goto err;
1087        }
1088        /* Save the point conversion form. */
1089        ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01);
1090        if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1091                                pub_oct, (size_t)(pub_oct_len), NULL)) {
1092            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1093            goto err;
1094        }
1095    } else {
1096        if (!EC_POINT_mul
1097            (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) {
1098            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1099            goto err;
1100        }
1101        /* Remember the original private-key-only encoding. */
1102        ret->enc_flag |= EC_PKEY_NO_PUBKEY;
1103    }
1104
1105    if (a)
1106        *a = ret;
1107    *in = p;
1108    ok = 1;
1109 err:
1110    if (!ok) {
1111        if (ret && (a == NULL || *a != ret))
1112            EC_KEY_free(ret);
1113        ret = NULL;
1114    }
1115
1116    if (priv_key)
1117        EC_PRIVATEKEY_free(priv_key);
1118
1119    return (ret);
1120}
1121
1122int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1123{
1124    int ret = 0, ok = 0;
1125    unsigned char *buffer = NULL;
1126    size_t buf_len = 0, tmp_len, bn_len;
1127    EC_PRIVATEKEY *priv_key = NULL;
1128
1129    if (a == NULL || a->group == NULL || a->priv_key == NULL ||
1130        (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) {
1131        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
1132        goto err;
1133    }
1134
1135    if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1136        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1137        goto err;
1138    }
1139
1140    priv_key->version = a->version;
1141
1142    bn_len = (size_t)BN_num_bytes(a->priv_key);
1143
1144    /* Octetstring may need leading zeros if BN is to short */
1145
1146    buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8;
1147
1148    if (bn_len > buf_len) {
1149        ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
1150        goto err;
1151    }
1152
1153    buffer = OPENSSL_malloc(buf_len);
1154    if (buffer == NULL) {
1155        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1156        goto err;
1157    }
1158
1159    if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) {
1160        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1161        goto err;
1162    }
1163
1164    if (buf_len - bn_len > 0) {
1165        memset(buffer, 0, buf_len - bn_len);
1166    }
1167
1168    if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
1169        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1170        goto err;
1171    }
1172
1173    if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
1174        if ((priv_key->parameters =
1175             ec_asn1_group2pkparameters(a->group,
1176                                        priv_key->parameters)) == NULL) {
1177            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1178            goto err;
1179        }
1180    }
1181
1182    if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) {
1183        priv_key->publicKey = M_ASN1_BIT_STRING_new();
1184        if (priv_key->publicKey == NULL) {
1185            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1186            goto err;
1187        }
1188
1189        tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1190                                     a->conv_form, NULL, 0, NULL);
1191
1192        if (tmp_len > buf_len) {
1193            unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1194            if (!tmp_buffer) {
1195                ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1196                goto err;
1197            }
1198            buffer = tmp_buffer;
1199            buf_len = tmp_len;
1200        }
1201
1202        if (!EC_POINT_point2oct(a->group, a->pub_key,
1203                                a->conv_form, buffer, buf_len, NULL)) {
1204            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1205            goto err;
1206        }
1207
1208        priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
1209        priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1210        if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
1211            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1212            goto err;
1213        }
1214    }
1215
1216    if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
1217        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1218        goto err;
1219    }
1220    ok = 1;
1221 err:
1222    if (buffer)
1223        OPENSSL_free(buffer);
1224    if (priv_key)
1225        EC_PRIVATEKEY_free(priv_key);
1226    return (ok ? ret : 0);
1227}
1228
1229int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1230{
1231    if (a == NULL) {
1232        ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1233        return 0;
1234    }
1235    return i2d_ECPKParameters(a->group, out);
1236}
1237
1238EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1239{
1240    EC_KEY *ret;
1241
1242    if (in == NULL || *in == NULL) {
1243        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1244        return NULL;
1245    }
1246
1247    if (a == NULL || *a == NULL) {
1248        if ((ret = EC_KEY_new()) == NULL) {
1249            ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1250            return NULL;
1251        }
1252    } else
1253        ret = *a;
1254
1255    if (!d2i_ECPKParameters(&ret->group, in, len)) {
1256        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1257        if (a == NULL || *a != ret)
1258             EC_KEY_free(ret);
1259        return NULL;
1260    }
1261
1262    if (a)
1263        *a = ret;
1264
1265    return ret;
1266}
1267
1268EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1269{
1270    EC_KEY *ret = NULL;
1271
1272    if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
1273        /*
1274         * sorry, but a EC_GROUP-structur is necessary to set the public key
1275         */
1276        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1277        return 0;
1278    }
1279    ret = *a;
1280    if (ret->pub_key == NULL &&
1281        (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
1282        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1283        return 0;
1284    }
1285    if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) {
1286        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1287        return 0;
1288    }
1289    /* save the point conversion form */
1290    ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01);
1291    *in += len;
1292    return ret;
1293}
1294
1295int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1296{
1297    size_t buf_len = 0;
1298    int new_buffer = 0;
1299
1300    if (a == NULL) {
1301        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1302        return 0;
1303    }
1304
1305    buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1306                                 a->conv_form, NULL, 0, NULL);
1307
1308    if (out == NULL || buf_len == 0)
1309        /* out == NULL => just return the length of the octet string */
1310        return buf_len;
1311
1312    if (*out == NULL) {
1313        if ((*out = OPENSSL_malloc(buf_len)) == NULL) {
1314            ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1315            return 0;
1316        }
1317        new_buffer = 1;
1318    }
1319    if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1320                            *out, buf_len, NULL)) {
1321        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1322        if (new_buffer) {
1323            OPENSSL_free(*out);
1324            *out = NULL;
1325        }
1326        return 0;
1327    }
1328    if (!new_buffer)
1329        *out += buf_len;
1330    return buf_len;
1331}
1332