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