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