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