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