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