ec_asn1.c revision 352193
1/* crypto/ec/ec_asn1.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2019 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, *dup = NULL;
699    BIGNUM *p = NULL, *a = NULL, *b = NULL;
700    EC_POINT *point = NULL;
701    long field_bits;
702    int curve_name = NID_undef;
703    BN_CTX *ctx = NULL;
704
705    if (!params->fieldID || !params->fieldID->fieldType ||
706        !params->fieldID->p.ptr) {
707        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
708        goto err;
709    }
710
711    /* now extract the curve parameters a and b */
712    if (!params->curve || !params->curve->a ||
713        !params->curve->a->data || !params->curve->b ||
714        !params->curve->b->data) {
715        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
716        goto err;
717    }
718    a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
719    if (a == NULL) {
720        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
721        goto err;
722    }
723    b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
724    if (b == NULL) {
725        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
726        goto err;
727    }
728
729    /* get the field parameters */
730    tmp = OBJ_obj2nid(params->fieldID->fieldType);
731    if (tmp == NID_X9_62_characteristic_two_field)
732#ifdef OPENSSL_NO_EC2M
733    {
734        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
735        goto err;
736    }
737#else
738    {
739        X9_62_CHARACTERISTIC_TWO *char_two;
740
741        char_two = params->fieldID->p.char_two;
742
743        field_bits = char_two->m;
744        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
745            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
746            goto err;
747        }
748
749        if ((p = BN_new()) == NULL) {
750            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
751            goto err;
752        }
753
754        /* get the base type */
755        tmp = OBJ_obj2nid(char_two->type);
756
757        if (tmp == NID_X9_62_tpBasis) {
758            long tmp_long;
759
760            if (!char_two->p.tpBasis) {
761                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
762                goto err;
763            }
764
765            tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
766
767            if (!(char_two->m > tmp_long && tmp_long > 0)) {
768                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
769                      EC_R_INVALID_TRINOMIAL_BASIS);
770                goto err;
771            }
772
773            /* create the polynomial */
774            if (!BN_set_bit(p, (int)char_two->m))
775                goto err;
776            if (!BN_set_bit(p, (int)tmp_long))
777                goto err;
778            if (!BN_set_bit(p, 0))
779                goto err;
780        } else if (tmp == NID_X9_62_ppBasis) {
781            X9_62_PENTANOMIAL *penta;
782
783            penta = char_two->p.ppBasis;
784            if (!penta) {
785                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
786                goto err;
787            }
788
789            if (!
790                (char_two->m > penta->k3 && penta->k3 > penta->k2
791                 && penta->k2 > penta->k1 && penta->k1 > 0)) {
792                ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
793                      EC_R_INVALID_PENTANOMIAL_BASIS);
794                goto err;
795            }
796
797            /* create the polynomial */
798            if (!BN_set_bit(p, (int)char_two->m))
799                goto err;
800            if (!BN_set_bit(p, (int)penta->k1))
801                goto err;
802            if (!BN_set_bit(p, (int)penta->k2))
803                goto err;
804            if (!BN_set_bit(p, (int)penta->k3))
805                goto err;
806            if (!BN_set_bit(p, 0))
807                goto err;
808        } else if (tmp == NID_X9_62_onBasis) {
809            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
810            goto err;
811        } else {                /* error */
812
813            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
814            goto err;
815        }
816
817        /* create the EC_GROUP structure */
818        ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
819    }
820#endif
821    else if (tmp == NID_X9_62_prime_field) {
822        /* we have a curve over a prime field */
823        /* extract the prime number */
824        if (!params->fieldID->p.prime) {
825            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
826            goto err;
827        }
828        p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
829        if (p == NULL) {
830            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
831            goto err;
832        }
833
834        if (BN_is_negative(p) || BN_is_zero(p)) {
835            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
836            goto err;
837        }
838
839        field_bits = BN_num_bits(p);
840        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
841            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
842            goto err;
843        }
844
845        /* create the EC_GROUP structure */
846        ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
847    } else {
848        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
849        goto err;
850    }
851
852    if (ret == NULL) {
853        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
854        goto err;
855    }
856
857    /* extract seed (optional) */
858    if (params->curve->seed != NULL) {
859        if (ret->seed != NULL)
860            OPENSSL_free(ret->seed);
861        if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) {
862            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
863            goto err;
864        }
865        memcpy(ret->seed, params->curve->seed->data,
866               params->curve->seed->length);
867        ret->seed_len = params->curve->seed->length;
868    }
869
870    if (!params->order || !params->base || !params->base->data) {
871        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
872        goto err;
873    }
874
875    if ((point = EC_POINT_new(ret)) == NULL)
876        goto err;
877
878    /* set the point conversion form */
879    EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
880                                       (params->base->data[0] & ~0x01));
881
882    /* extract the ec point */
883    if (!EC_POINT_oct2point(ret, point, params->base->data,
884                            params->base->length, NULL)) {
885        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
886        goto err;
887    }
888
889    /* extract the order */
890    if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
891        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
892        goto err;
893    }
894    if (BN_is_negative(a) || BN_is_zero(a)) {
895        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
896        goto err;
897    }
898    if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */
899        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
900        goto err;
901    }
902
903    /* extract the cofactor (optional) */
904    if (params->cofactor == NULL) {
905        if (b) {
906            BN_free(b);
907            b = NULL;
908        }
909    } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
910        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
911        goto err;
912    }
913    /* set the generator, order and cofactor (if present) */
914    if (!EC_GROUP_set_generator(ret, point, a, b)) {
915        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
916        goto err;
917    }
918
919    /*
920     * Check if the explicit parameters group just created matches one of the
921     * built-in curves.
922     *
923     * We create a copy of the group just built, so that we can remove optional
924     * fields for the lookup: we do this to avoid the possibility that one of
925     * the optional parameters is used to force the library into using a less
926     * performant and less secure EC_METHOD instead of the specialized one.
927     * In any case, `seed` is not really used in any computation, while a
928     * cofactor different from the one in the built-in table is just
929     * mathematically wrong anyway and should not be used.
930     */
931    if ((ctx = BN_CTX_new()) == NULL) {
932        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
933        goto err;
934    }
935    if ((dup = EC_GROUP_dup(ret)) == NULL
936            || EC_GROUP_set_seed(dup, NULL, 0) != 1
937            || !EC_GROUP_set_generator(dup, point, a, NULL)) {
938        ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
939        goto err;
940    }
941    if ((curve_name = ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
942        /*
943         * The input explicit parameters successfully matched one of the
944         * built-in curves: often for built-in curves we have specialized
945         * methods with better performance and hardening.
946         *
947         * In this case we replace the `EC_GROUP` created through explicit
948         * parameters with one created from a named group.
949         */
950        EC_GROUP *named_group = NULL;
951
952#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
953        /*
954         * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
955         * the same curve, we prefer the SECP nid when matching explicit
956         * parameters as that is associated with a specialized EC_METHOD.
957         */
958        if (curve_name == NID_wap_wsg_idm_ecid_wtls12)
959            curve_name = NID_secp224r1;
960#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
961
962        if ((named_group = EC_GROUP_new_by_curve_name(curve_name)) == NULL) {
963            ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
964            goto err;
965        }
966        EC_GROUP_free(ret);
967        ret = named_group;
968
969        /*
970         * Set the flag so that EC_GROUPs created from explicit parameters are
971         * serialized using explicit parameters by default.
972         *
973         * 0x0 = OPENSSL_EC_EXPLICIT_CURVE
974         */
975        EC_GROUP_set_asn1_flag(ret, 0x0);
976    }
977
978    ok = 1;
979
980 err:
981    if (!ok) {
982        if (ret)
983            EC_GROUP_free(ret);
984        ret = NULL;
985    }
986    if (dup)
987        EC_GROUP_free(dup);
988
989    if (p)
990        BN_free(p);
991    if (a)
992        BN_free(a);
993    if (b)
994        BN_free(b);
995    if (point)
996        EC_POINT_free(point);
997    if (ctx)
998        BN_CTX_free(ctx);
999    return (ret);
1000}
1001
1002EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1003{
1004    EC_GROUP *ret = NULL;
1005    int tmp = 0;
1006
1007    if (params == NULL) {
1008        ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS);
1009        return NULL;
1010    }
1011
1012    if (params->type == 0) {    /* the curve is given by an OID */
1013        tmp = OBJ_obj2nid(params->value.named_curve);
1014        if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
1015            ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1016                  EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1017            return NULL;
1018        }
1019        EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1020    } else if (params->type == 1) { /* the parameters are given by a
1021                                     * ECPARAMETERS structure */
1022        ret = ec_asn1_parameters2group(params->value.parameters);
1023        if (!ret) {
1024            ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
1025            return NULL;
1026        }
1027        EC_GROUP_set_asn1_flag(ret, 0x0);
1028    } else if (params->type == 2) { /* implicitlyCA */
1029        return NULL;
1030    } else {
1031        ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
1032        return NULL;
1033    }
1034
1035    return ret;
1036}
1037
1038/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1039
1040EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1041{
1042    EC_GROUP *group = NULL;
1043    ECPKPARAMETERS *params = NULL;
1044    const unsigned char *p = *in;
1045
1046    if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) {
1047        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1048        ECPKPARAMETERS_free(params);
1049        return NULL;
1050    }
1051
1052    if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
1053        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1054        ECPKPARAMETERS_free(params);
1055        return NULL;
1056    }
1057
1058    if (a && *a)
1059        EC_GROUP_free(*a);
1060    if (a)
1061        *a = group;
1062
1063    ECPKPARAMETERS_free(params);
1064    *in = p;
1065    return (group);
1066}
1067
1068int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1069{
1070    int ret = 0;
1071    ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
1072    if (tmp == NULL) {
1073        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1074        return 0;
1075    }
1076    if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
1077        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1078        ECPKPARAMETERS_free(tmp);
1079        return 0;
1080    }
1081    ECPKPARAMETERS_free(tmp);
1082    return (ret);
1083}
1084
1085/* some EC_KEY functions */
1086
1087EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1088{
1089    int ok = 0;
1090    EC_KEY *ret = NULL;
1091    EC_PRIVATEKEY *priv_key = NULL;
1092    const unsigned char *p = *in;
1093
1094    if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) {
1095        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1096        return NULL;
1097    }
1098
1099    if (a == NULL || *a == NULL) {
1100        if ((ret = EC_KEY_new()) == NULL) {
1101            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1102            goto err;
1103        }
1104    } else
1105        ret = *a;
1106
1107    if (priv_key->parameters) {
1108        if (ret->group)
1109            EC_GROUP_free(ret->group);
1110        ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1111    }
1112
1113    if (ret->group == NULL) {
1114        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1115        goto err;
1116    }
1117
1118    ret->version = priv_key->version;
1119
1120    if (priv_key->privateKey) {
1121        ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
1122                                  M_ASN1_STRING_length(priv_key->privateKey),
1123                                  ret->priv_key);
1124        if (ret->priv_key == NULL) {
1125            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB);
1126            goto err;
1127        }
1128    } else {
1129        ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY);
1130        goto err;
1131    }
1132
1133    if (ret->pub_key)
1134        EC_POINT_clear_free(ret->pub_key);
1135    ret->pub_key = EC_POINT_new(ret->group);
1136    if (ret->pub_key == NULL) {
1137        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1138        goto err;
1139    }
1140
1141    if (priv_key->publicKey) {
1142        const unsigned char *pub_oct;
1143        int pub_oct_len;
1144
1145        pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
1146        pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1147        /*
1148         * The first byte - point conversion form - must be present.
1149         */
1150        if (pub_oct_len <= 0) {
1151            ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
1152            goto err;
1153        }
1154        /* Save the point conversion form. */
1155        ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01);
1156        if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1157                                pub_oct, (size_t)(pub_oct_len), NULL)) {
1158            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1159            goto err;
1160        }
1161    } else {
1162        if (!EC_POINT_mul
1163            (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) {
1164            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1165            goto err;
1166        }
1167        /* Remember the original private-key-only encoding. */
1168        ret->enc_flag |= EC_PKEY_NO_PUBKEY;
1169    }
1170
1171    if (a)
1172        *a = ret;
1173    *in = p;
1174    ok = 1;
1175 err:
1176    if (!ok) {
1177        if (ret && (a == NULL || *a != ret))
1178            EC_KEY_free(ret);
1179        ret = NULL;
1180    }
1181
1182    if (priv_key)
1183        EC_PRIVATEKEY_free(priv_key);
1184
1185    return (ret);
1186}
1187
1188int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1189{
1190    int ret = 0, ok = 0;
1191    unsigned char *buffer = NULL;
1192    size_t buf_len = 0, tmp_len, bn_len;
1193    EC_PRIVATEKEY *priv_key = NULL;
1194
1195    if (a == NULL || a->group == NULL || a->priv_key == NULL ||
1196        (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) {
1197        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
1198        goto err;
1199    }
1200
1201    if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
1202        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1203        goto err;
1204    }
1205
1206    priv_key->version = a->version;
1207
1208    bn_len = (size_t)BN_num_bytes(a->priv_key);
1209
1210    /* Octetstring may need leading zeros if BN is to short */
1211
1212    buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8;
1213
1214    if (bn_len > buf_len) {
1215        ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
1216        goto err;
1217    }
1218
1219    buffer = OPENSSL_malloc(buf_len);
1220    if (buffer == NULL) {
1221        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1222        goto err;
1223    }
1224
1225    if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) {
1226        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1227        goto err;
1228    }
1229
1230    if (buf_len - bn_len > 0) {
1231        memset(buffer, 0, buf_len - bn_len);
1232    }
1233
1234    if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
1235        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1236        goto err;
1237    }
1238
1239    if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
1240        if ((priv_key->parameters =
1241             ec_asn1_group2pkparameters(a->group,
1242                                        priv_key->parameters)) == NULL) {
1243            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1244            goto err;
1245        }
1246    }
1247
1248    if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) {
1249        priv_key->publicKey = M_ASN1_BIT_STRING_new();
1250        if (priv_key->publicKey == NULL) {
1251            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1252            goto err;
1253        }
1254
1255        tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1256                                     a->conv_form, NULL, 0, NULL);
1257
1258        if (tmp_len > buf_len) {
1259            unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1260            if (!tmp_buffer) {
1261                ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1262                goto err;
1263            }
1264            buffer = tmp_buffer;
1265            buf_len = tmp_len;
1266        }
1267
1268        if (!EC_POINT_point2oct(a->group, a->pub_key,
1269                                a->conv_form, buffer, buf_len, NULL)) {
1270            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1271            goto err;
1272        }
1273
1274        priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
1275        priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1276        if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
1277            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1278            goto err;
1279        }
1280    }
1281
1282    if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
1283        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1284        goto err;
1285    }
1286    ok = 1;
1287 err:
1288    if (buffer)
1289        OPENSSL_free(buffer);
1290    if (priv_key)
1291        EC_PRIVATEKEY_free(priv_key);
1292    return (ok ? ret : 0);
1293}
1294
1295int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1296{
1297    if (a == NULL) {
1298        ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1299        return 0;
1300    }
1301    return i2d_ECPKParameters(a->group, out);
1302}
1303
1304EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1305{
1306    EC_KEY *ret;
1307
1308    if (in == NULL || *in == NULL) {
1309        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1310        return NULL;
1311    }
1312
1313    if (a == NULL || *a == NULL) {
1314        if ((ret = EC_KEY_new()) == NULL) {
1315            ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1316            return NULL;
1317        }
1318    } else
1319        ret = *a;
1320
1321    if (!d2i_ECPKParameters(&ret->group, in, len)) {
1322        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1323        if (a == NULL || *a != ret)
1324             EC_KEY_free(ret);
1325        return NULL;
1326    }
1327
1328    if (a)
1329        *a = ret;
1330
1331    return ret;
1332}
1333
1334EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1335{
1336    EC_KEY *ret = NULL;
1337
1338    if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
1339        /*
1340         * sorry, but a EC_GROUP-structur is necessary to set the public key
1341         */
1342        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1343        return 0;
1344    }
1345    ret = *a;
1346    if (ret->pub_key == NULL &&
1347        (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
1348        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1349        return 0;
1350    }
1351    if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) {
1352        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1353        return 0;
1354    }
1355    /* save the point conversion form */
1356    ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01);
1357    *in += len;
1358    return ret;
1359}
1360
1361int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1362{
1363    size_t buf_len = 0;
1364    int new_buffer = 0;
1365
1366    if (a == NULL) {
1367        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1368        return 0;
1369    }
1370
1371    buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1372                                 a->conv_form, NULL, 0, NULL);
1373
1374    if (out == NULL || buf_len == 0)
1375        /* out == NULL => just return the length of the octet string */
1376        return buf_len;
1377
1378    if (*out == NULL) {
1379        if ((*out = OPENSSL_malloc(buf_len)) == NULL) {
1380            ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1381            return 0;
1382        }
1383        new_buffer = 1;
1384    }
1385    if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1386                            *out, buf_len, NULL)) {
1387        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1388        if (new_buffer) {
1389            OPENSSL_free(*out);
1390            *out = NULL;
1391        }
1392        return 0;
1393    }
1394    if (!new_buffer)
1395        *out += buf_len;
1396    return buf_len;
1397}
1398