Branch data Line data Source code
1 : : /* apps/ecparam.c */
2 : : /*
3 : : * Written by Nils Larsch for the OpenSSL project.
4 : : */
5 : : /* ====================================================================
6 : : * Copyright (c) 1998-2005 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 : : * openssl-core@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 : : * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 : : *
61 : : * Portions of the attached software ("Contribution") are developed by
62 : : * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 : : *
64 : : * The Contribution is licensed pursuant to the OpenSSL open source
65 : : * license provided above.
66 : : *
67 : : * The elliptic curve binary polynomial software is originally written by
68 : : * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 : : *
70 : : */
71 : :
72 : : #include <openssl/opensslconf.h>
73 : : #ifndef OPENSSL_NO_EC
74 : : #include <assert.h>
75 : : #include <stdio.h>
76 : : #include <stdlib.h>
77 : : #include <time.h>
78 : : #include <string.h>
79 : : #include "apps.h"
80 : : #include <openssl/bio.h>
81 : : #include <openssl/err.h>
82 : : #include <openssl/bn.h>
83 : : #include <openssl/ec.h>
84 : : #include <openssl/x509.h>
85 : : #include <openssl/pem.h>
86 : :
87 : : #undef PROG
88 : : #define PROG ecparam_main
89 : :
90 : : /* -inform arg - input format - default PEM (DER or PEM)
91 : : * -outform arg - output format - default PEM
92 : : * -in arg - input file - default stdin
93 : : * -out arg - output file - default stdout
94 : : * -noout - do not print the ec parameter
95 : : * -text - print the ec parameters in text form
96 : : * -check - validate the ec parameters
97 : : * -C - print a 'C' function creating the parameters
98 : : * -name arg - use the ec parameters with 'short name' name
99 : : * -list_curves - prints a list of all currently available curve 'short names'
100 : : * -conv_form arg - specifies the point conversion form
101 : : * - possible values: compressed
102 : : * uncompressed (default)
103 : : * hybrid
104 : : * -param_enc arg - specifies the way the ec parameters are encoded
105 : : * in the asn1 der encoding
106 : : * possible values: named_curve (default)
107 : : * explicit
108 : : * -no_seed - if 'explicit' parameters are chosen do not use the seed
109 : : * -genkey - generate ec key
110 : : * -rand file - files to use for random number input
111 : : * -engine e - use engine e, possibly a hardware device
112 : : */
113 : :
114 : :
115 : : static int ecparam_print_var(BIO *,BIGNUM *,const char *,int,unsigned char *);
116 : :
117 : : int MAIN(int, char **);
118 : :
119 : 0 : int MAIN(int argc, char **argv)
120 : : {
121 : 0 : EC_GROUP *group = NULL;
122 : 0 : point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
123 : 0 : int new_form = 0;
124 : 0 : int asn1_flag = OPENSSL_EC_NAMED_CURVE;
125 : 0 : int new_asn1_flag = 0;
126 : 0 : char *curve_name = NULL, *inrand = NULL;
127 : 0 : int list_curves = 0, no_seed = 0, check = 0,
128 : 0 : badops = 0, text = 0, i, need_rand = 0, genkey = 0;
129 : 0 : char *infile = NULL, *outfile = NULL, *prog;
130 : 0 : BIO *in = NULL, *out = NULL;
131 : 0 : int informat, outformat, noout = 0, C = 0, ret = 1;
132 : 0 : char *engine = NULL;
133 : :
134 : 0 : BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL,
135 : 0 : *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
136 : 0 : unsigned char *buffer = NULL;
137 : :
138 : 0 : apps_startup();
139 : :
140 [ # # ]: 0 : if (bio_err == NULL)
141 [ # # ]: 0 : if ((bio_err=BIO_new(BIO_s_file())) != NULL)
142 : 0 : BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
143 : :
144 [ # # ]: 0 : if (!load_config(bio_err, NULL))
145 : : goto end;
146 : :
147 : 0 : informat=FORMAT_PEM;
148 : 0 : outformat=FORMAT_PEM;
149 : :
150 : 0 : prog=argv[0];
151 : 0 : argc--;
152 : 0 : argv++;
153 [ # # ]: 0 : while (argc >= 1)
154 : : {
155 [ # # ]: 0 : if (strcmp(*argv,"-inform") == 0)
156 : : {
157 [ # # ]: 0 : if (--argc < 1) goto bad;
158 : 0 : informat=str2fmt(*(++argv));
159 : : }
160 [ # # ]: 0 : else if (strcmp(*argv,"-outform") == 0)
161 : : {
162 [ # # ]: 0 : if (--argc < 1) goto bad;
163 : 0 : outformat=str2fmt(*(++argv));
164 : : }
165 [ # # ]: 0 : else if (strcmp(*argv,"-in") == 0)
166 : : {
167 [ # # ]: 0 : if (--argc < 1) goto bad;
168 : 0 : infile= *(++argv);
169 : : }
170 [ # # ]: 0 : else if (strcmp(*argv,"-out") == 0)
171 : : {
172 [ # # ]: 0 : if (--argc < 1) goto bad;
173 : 0 : outfile= *(++argv);
174 : : }
175 [ # # ]: 0 : else if (strcmp(*argv,"-text") == 0)
176 : : text = 1;
177 [ # # ]: 0 : else if (strcmp(*argv,"-C") == 0)
178 : : C = 1;
179 [ # # ]: 0 : else if (strcmp(*argv,"-check") == 0)
180 : : check = 1;
181 [ # # ]: 0 : else if (strcmp (*argv, "-name") == 0)
182 : : {
183 [ # # ]: 0 : if (--argc < 1)
184 : : goto bad;
185 : 0 : curve_name = *(++argv);
186 : : }
187 [ # # ]: 0 : else if (strcmp(*argv, "-list_curves") == 0)
188 : : list_curves = 1;
189 [ # # ]: 0 : else if (strcmp(*argv, "-conv_form") == 0)
190 : : {
191 [ # # ]: 0 : if (--argc < 1)
192 : : goto bad;
193 : 0 : ++argv;
194 : 0 : new_form = 1;
195 [ # # ]: 0 : if (strcmp(*argv, "compressed") == 0)
196 : : form = POINT_CONVERSION_COMPRESSED;
197 [ # # ]: 0 : else if (strcmp(*argv, "uncompressed") == 0)
198 : : form = POINT_CONVERSION_UNCOMPRESSED;
199 [ # # ]: 0 : else if (strcmp(*argv, "hybrid") == 0)
200 : : form = POINT_CONVERSION_HYBRID;
201 : : else
202 : : goto bad;
203 : : }
204 [ # # ]: 0 : else if (strcmp(*argv, "-param_enc") == 0)
205 : : {
206 [ # # ]: 0 : if (--argc < 1)
207 : : goto bad;
208 : 0 : ++argv;
209 : 0 : new_asn1_flag = 1;
210 [ # # ]: 0 : if (strcmp(*argv, "named_curve") == 0)
211 : : asn1_flag = OPENSSL_EC_NAMED_CURVE;
212 [ # # ]: 0 : else if (strcmp(*argv, "explicit") == 0)
213 : : asn1_flag = 0;
214 : : else
215 : : goto bad;
216 : : }
217 [ # # ]: 0 : else if (strcmp(*argv, "-no_seed") == 0)
218 : : no_seed = 1;
219 [ # # ]: 0 : else if (strcmp(*argv, "-noout") == 0)
220 : : noout=1;
221 [ # # ]: 0 : else if (strcmp(*argv,"-genkey") == 0)
222 : : {
223 : : genkey=1;
224 : : need_rand=1;
225 : : }
226 [ # # ]: 0 : else if (strcmp(*argv, "-rand") == 0)
227 : : {
228 [ # # ]: 0 : if (--argc < 1) goto bad;
229 : 0 : inrand= *(++argv);
230 : 0 : need_rand=1;
231 : : }
232 [ # # ]: 0 : else if(strcmp(*argv, "-engine") == 0)
233 : : {
234 [ # # ]: 0 : if (--argc < 1) goto bad;
235 : 0 : engine = *(++argv);
236 : : }
237 : : else
238 : : {
239 : 0 : BIO_printf(bio_err,"unknown option %s\n",*argv);
240 : 0 : badops=1;
241 : 0 : break;
242 : : }
243 : 0 : argc--;
244 : 0 : argv++;
245 : : }
246 : :
247 [ # # ]: 0 : if (badops)
248 : : {
249 : : bad:
250 : 0 : BIO_printf(bio_err, "%s [options] <infile >outfile\n",prog);
251 : 0 : BIO_printf(bio_err, "where options are\n");
252 : 0 : BIO_printf(bio_err, " -inform arg input format - "
253 : : "default PEM (DER or PEM)\n");
254 : 0 : BIO_printf(bio_err, " -outform arg output format - "
255 : : "default PEM\n");
256 : 0 : BIO_printf(bio_err, " -in arg input file - "
257 : : "default stdin\n");
258 : 0 : BIO_printf(bio_err, " -out arg output file - "
259 : : "default stdout\n");
260 : 0 : BIO_printf(bio_err, " -noout do not print the "
261 : : "ec parameter\n");
262 : 0 : BIO_printf(bio_err, " -text print the ec "
263 : : "parameters in text form\n");
264 : 0 : BIO_printf(bio_err, " -check validate the ec "
265 : : "parameters\n");
266 : 0 : BIO_printf(bio_err, " -C print a 'C' "
267 : : "function creating the parameters\n");
268 : 0 : BIO_printf(bio_err, " -name arg use the "
269 : : "ec parameters with 'short name' name\n");
270 : 0 : BIO_printf(bio_err, " -list_curves prints a list of "
271 : : "all currently available curve 'short names'\n");
272 : 0 : BIO_printf(bio_err, " -conv_form arg specifies the "
273 : : "point conversion form \n");
274 : 0 : BIO_printf(bio_err, " possible values:"
275 : : " compressed\n");
276 : 0 : BIO_printf(bio_err, " "
277 : : " uncompressed (default)\n");
278 : 0 : BIO_printf(bio_err, " "
279 : : " hybrid\n");
280 : 0 : BIO_printf(bio_err, " -param_enc arg specifies the way"
281 : : " the ec parameters are encoded\n");
282 : 0 : BIO_printf(bio_err, " in the asn1 der "
283 : : "encoding\n");
284 : 0 : BIO_printf(bio_err, " possible values:"
285 : : " named_curve (default)\n");
286 : 0 : BIO_printf(bio_err, " "
287 : : " explicit\n");
288 : 0 : BIO_printf(bio_err, " -no_seed if 'explicit'"
289 : : " parameters are chosen do not"
290 : : " use the seed\n");
291 : 0 : BIO_printf(bio_err, " -genkey generate ec"
292 : : " key\n");
293 : 0 : BIO_printf(bio_err, " -rand file files to use for"
294 : : " random number input\n");
295 : 0 : BIO_printf(bio_err, " -engine e use engine e, "
296 : : "possibly a hardware device\n");
297 : 0 : goto end;
298 : : }
299 : :
300 : 0 : ERR_load_crypto_strings();
301 : :
302 : 0 : in=BIO_new(BIO_s_file());
303 : 0 : out=BIO_new(BIO_s_file());
304 [ # # ]: 0 : if ((in == NULL) || (out == NULL))
305 : : {
306 : 0 : ERR_print_errors(bio_err);
307 : 0 : goto end;
308 : : }
309 : :
310 [ # # ]: 0 : if (infile == NULL)
311 : 0 : BIO_set_fp(in,stdin,BIO_NOCLOSE);
312 : : else
313 : : {
314 [ # # ]: 0 : if (BIO_read_filename(in,infile) <= 0)
315 : : {
316 : 0 : perror(infile);
317 : 0 : goto end;
318 : : }
319 : : }
320 [ # # ]: 0 : if (outfile == NULL)
321 : : {
322 : 0 : BIO_set_fp(out,stdout,BIO_NOCLOSE);
323 : : #ifdef OPENSSL_SYS_VMS
324 : : {
325 : : BIO *tmpbio = BIO_new(BIO_f_linebuffer());
326 : : out = BIO_push(tmpbio, out);
327 : : }
328 : : #endif
329 : : }
330 : : else
331 : : {
332 [ # # ]: 0 : if (BIO_write_filename(out,outfile) <= 0)
333 : : {
334 : 0 : perror(outfile);
335 : 0 : goto end;
336 : : }
337 : : }
338 : :
339 : : #ifndef OPENSSL_NO_ENGINE
340 : 0 : setup_engine(bio_err, engine, 0);
341 : : #endif
342 : :
343 [ # # ]: 0 : if (list_curves)
344 : : {
345 : 0 : EC_builtin_curve *curves = NULL;
346 : 0 : size_t crv_len = 0;
347 : 0 : size_t n = 0;
348 : :
349 : 0 : crv_len = EC_get_builtin_curves(NULL, 0);
350 : :
351 : 0 : curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len));
352 : :
353 [ # # ]: 0 : if (curves == NULL)
354 : : goto end;
355 : :
356 [ # # ]: 0 : if (!EC_get_builtin_curves(curves, crv_len))
357 : : {
358 : 0 : OPENSSL_free(curves);
359 : 0 : goto end;
360 : : }
361 : :
362 : :
363 [ # # ]: 0 : for (n = 0; n < crv_len; n++)
364 : : {
365 : : const char *comment;
366 : : const char *sname;
367 : 0 : comment = curves[n].comment;
368 : 0 : sname = OBJ_nid2sn(curves[n].nid);
369 [ # # ]: 0 : if (comment == NULL)
370 : 0 : comment = "CURVE DESCRIPTION NOT AVAILABLE";
371 [ # # ]: 0 : if (sname == NULL)
372 : 0 : sname = "";
373 : :
374 : 0 : BIO_printf(out, " %-10s: ", sname);
375 : 0 : BIO_printf(out, "%s\n", comment);
376 : : }
377 : :
378 : 0 : OPENSSL_free(curves);
379 : 0 : ret = 0;
380 : 0 : goto end;
381 : : }
382 : :
383 [ # # ]: 0 : if (curve_name != NULL)
384 : : {
385 : : int nid;
386 : :
387 : : /* workaround for the SECG curve names secp192r1
388 : : * and secp256r1 (which are the same as the curves
389 : : * prime192v1 and prime256v1 defined in X9.62)
390 : : */
391 [ # # ]: 0 : if (!strcmp(curve_name, "secp192r1"))
392 : : {
393 : 0 : BIO_printf(bio_err, "using curve name prime192v1 "
394 : : "instead of secp192r1\n");
395 : 0 : nid = NID_X9_62_prime192v1;
396 : : }
397 [ # # ]: 0 : else if (!strcmp(curve_name, "secp256r1"))
398 : : {
399 : 0 : BIO_printf(bio_err, "using curve name prime256v1 "
400 : : "instead of secp256r1\n");
401 : 0 : nid = NID_X9_62_prime256v1;
402 : : }
403 : : else
404 : 0 : nid = OBJ_sn2nid(curve_name);
405 : :
406 [ # # ]: 0 : if (nid == 0)
407 : 0 : nid = EC_curve_nist2nid(curve_name);
408 : :
409 [ # # ]: 0 : if (nid == 0)
410 : : {
411 : 0 : BIO_printf(bio_err, "unknown curve name (%s)\n",
412 : : curve_name);
413 : 0 : goto end;
414 : : }
415 : :
416 : 0 : group = EC_GROUP_new_by_curve_name(nid);
417 [ # # ]: 0 : if (group == NULL)
418 : : {
419 : 0 : BIO_printf(bio_err, "unable to create curve (%s)\n",
420 : : curve_name);
421 : 0 : goto end;
422 : : }
423 : 0 : EC_GROUP_set_asn1_flag(group, asn1_flag);
424 : 0 : EC_GROUP_set_point_conversion_form(group, form);
425 : : }
426 [ # # ]: 0 : else if (informat == FORMAT_ASN1)
427 : : {
428 : 0 : group = d2i_ECPKParameters_bio(in, NULL);
429 : : }
430 [ # # ]: 0 : else if (informat == FORMAT_PEM)
431 : : {
432 : 0 : group = PEM_read_bio_ECPKParameters(in,NULL,NULL,NULL);
433 : : }
434 : : else
435 : : {
436 : 0 : BIO_printf(bio_err, "bad input format specified\n");
437 : 0 : goto end;
438 : : }
439 : :
440 [ # # ]: 0 : if (group == NULL)
441 : : {
442 : 0 : BIO_printf(bio_err,
443 : : "unable to load elliptic curve parameters\n");
444 : 0 : ERR_print_errors(bio_err);
445 : 0 : goto end;
446 : : }
447 : :
448 [ # # ]: 0 : if (new_form)
449 : 0 : EC_GROUP_set_point_conversion_form(group, form);
450 : :
451 [ # # ]: 0 : if (new_asn1_flag)
452 : 0 : EC_GROUP_set_asn1_flag(group, asn1_flag);
453 : :
454 [ # # ]: 0 : if (no_seed)
455 : : {
456 : 0 : EC_GROUP_set_seed(group, NULL, 0);
457 : : }
458 : :
459 [ # # ]: 0 : if (text)
460 : : {
461 [ # # ]: 0 : if (!ECPKParameters_print(out, group, 0))
462 : : goto end;
463 : : }
464 : :
465 [ # # ]: 0 : if (check)
466 : : {
467 [ # # ]: 0 : if (group == NULL)
468 : 0 : BIO_printf(bio_err, "no elliptic curve parameters\n");
469 : 0 : BIO_printf(bio_err, "checking elliptic curve parameters: ");
470 [ # # ]: 0 : if (!EC_GROUP_check(group, NULL))
471 : : {
472 : 0 : BIO_printf(bio_err, "failed\n");
473 : 0 : ERR_print_errors(bio_err);
474 : : }
475 : : else
476 : 0 : BIO_printf(bio_err, "ok\n");
477 : :
478 : : }
479 : :
480 [ # # ]: 0 : if (C)
481 : : {
482 : 0 : size_t buf_len = 0, tmp_len = 0;
483 : : const EC_POINT *point;
484 : 0 : int is_prime, len = 0;
485 : 0 : const EC_METHOD *meth = EC_GROUP_method_of(group);
486 : :
487 [ # # ][ # # ]: 0 : if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
[ # # ]
488 [ # # ][ # # ]: 0 : (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
489 [ # # ]: 0 : (ec_order = BN_new()) == NULL ||
490 : : (ec_cofactor = BN_new()) == NULL )
491 : : {
492 : 0 : perror("OPENSSL_malloc");
493 : 0 : goto end;
494 : : }
495 : :
496 : 0 : is_prime = (EC_METHOD_get_field_type(meth) ==
497 : : NID_X9_62_prime_field);
498 : :
499 [ # # ]: 0 : if (is_prime)
500 : : {
501 [ # # ]: 0 : if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
502 : : ec_b, NULL))
503 : : goto end;
504 : : }
505 : : else
506 : : {
507 : : /* TODO */
508 : : goto end;
509 : : }
510 : :
511 [ # # ]: 0 : if ((point = EC_GROUP_get0_generator(group)) == NULL)
512 : : goto end;
513 [ # # ]: 0 : if (!EC_POINT_point2bn(group, point,
514 : : EC_GROUP_get_point_conversion_form(group), ec_gen,
515 : : NULL))
516 : : goto end;
517 [ # # ]: 0 : if (!EC_GROUP_get_order(group, ec_order, NULL))
518 : : goto end;
519 [ # # ]: 0 : if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
520 : : goto end;
521 : :
522 [ # # ][ # # ]: 0 : if (!ec_p || !ec_a || !ec_b || !ec_gen ||
523 [ # # ]: 0 : !ec_order || !ec_cofactor)
524 : : goto end;
525 : :
526 : 0 : len = BN_num_bits(ec_order);
527 : :
528 [ # # ]: 0 : if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
529 : 0 : buf_len = tmp_len;
530 [ # # ]: 0 : if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
531 : 0 : buf_len = tmp_len;
532 [ # # ]: 0 : if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
533 : 0 : buf_len = tmp_len;
534 [ # # ]: 0 : if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
535 : 0 : buf_len = tmp_len;
536 [ # # ]: 0 : if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
537 : 0 : buf_len = tmp_len;
538 [ # # ]: 0 : if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
539 : 0 : buf_len = tmp_len;
540 : :
541 : 0 : buffer = (unsigned char *)OPENSSL_malloc(buf_len);
542 : :
543 [ # # ]: 0 : if (buffer == NULL)
544 : : {
545 : 0 : perror("OPENSSL_malloc");
546 : 0 : goto end;
547 : : }
548 : :
549 : 0 : ecparam_print_var(out, ec_p, "ec_p", len, buffer);
550 : 0 : ecparam_print_var(out, ec_a, "ec_a", len, buffer);
551 : 0 : ecparam_print_var(out, ec_b, "ec_b", len, buffer);
552 : 0 : ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
553 : 0 : ecparam_print_var(out, ec_order, "ec_order", len, buffer);
554 : 0 : ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
555 : : buffer);
556 : :
557 : 0 : BIO_printf(out, "\n\n");
558 : :
559 : 0 : BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
560 : 0 : BIO_printf(out, "\tint ok=0;\n");
561 : 0 : BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
562 : 0 : BIO_printf(out, "\tEC_POINT *point = NULL;\n");
563 : 0 : BIO_printf(out, "\tBIGNUM *tmp_1 = NULL, *tmp_2 = NULL, "
564 : : "*tmp_3 = NULL;\n\n");
565 : 0 : BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
566 : : "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
567 : : "goto err;\n", len, len);
568 : 0 : BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
569 : : "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
570 : : "goto err;\n", len, len);
571 : 0 : BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
572 : : "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
573 : : "goto err;\n", len, len);
574 [ # # ]: 0 : if (is_prime)
575 : : {
576 : 0 : BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
577 : : "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
578 : : "\n\t\tgoto err;\n\n");
579 : : }
580 : : else
581 : : {
582 : : /* TODO */
583 : : goto end;
584 : : }
585 : 0 : BIO_printf(out, "\t/* build generator */\n");
586 : 0 : BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
587 : : "sizeof(ec_gen_%d), tmp_1)) == NULL)"
588 : : "\n\t\tgoto err;\n", len, len);
589 : 0 : BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
590 : : "NULL, NULL);\n");
591 : 0 : BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
592 : 0 : BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
593 : : "sizeof(ec_order_%d), tmp_2)) == NULL)"
594 : : "\n\t\tgoto err;\n", len, len);
595 : 0 : BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
596 : : "sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
597 : : "\n\t\tgoto err;\n", len, len);
598 : 0 : BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
599 : : " tmp_2, tmp_3))\n\t\tgoto err;\n");
600 : 0 : BIO_printf(out, "\n\tok=1;\n");
601 : 0 : BIO_printf(out, "err:\n");
602 : 0 : BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
603 : 0 : BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
604 : 0 : BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
605 : 0 : BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
606 : 0 : BIO_printf(out, "\tif (!ok)\n");
607 : 0 : BIO_printf(out, "\t\t{\n");
608 : 0 : BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
609 : 0 : BIO_printf(out, "\t\tgroup = NULL;\n");
610 : 0 : BIO_printf(out, "\t\t}\n");
611 : 0 : BIO_printf(out, "\treturn(group);\n\t}\n");
612 : : }
613 : :
614 [ # # ]: 0 : if (!noout)
615 : : {
616 [ # # ]: 0 : if (outformat == FORMAT_ASN1)
617 : 0 : i = i2d_ECPKParameters_bio(out, group);
618 [ # # ]: 0 : else if (outformat == FORMAT_PEM)
619 : 0 : i = PEM_write_bio_ECPKParameters(out, group);
620 : : else
621 : : {
622 : 0 : BIO_printf(bio_err,"bad output format specified for"
623 : : " outfile\n");
624 : 0 : goto end;
625 : : }
626 [ # # ]: 0 : if (!i)
627 : : {
628 : 0 : BIO_printf(bio_err, "unable to write elliptic "
629 : : "curve parameters\n");
630 : 0 : ERR_print_errors(bio_err);
631 : 0 : goto end;
632 : : }
633 : : }
634 : :
635 [ # # ]: 0 : if (need_rand)
636 : : {
637 : 0 : app_RAND_load_file(NULL, bio_err, (inrand != NULL));
638 [ # # ]: 0 : if (inrand != NULL)
639 : 0 : BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
640 : : app_RAND_load_files(inrand));
641 : : }
642 : :
643 [ # # ]: 0 : if (genkey)
644 : : {
645 : 0 : EC_KEY *eckey = EC_KEY_new();
646 : :
647 [ # # ]: 0 : if (eckey == NULL)
648 : : goto end;
649 : :
650 [ # # ]: 0 : assert(need_rand);
651 : :
652 [ # # ]: 0 : if (EC_KEY_set_group(eckey, group) == 0)
653 : : goto end;
654 : :
655 [ # # ]: 0 : if (!EC_KEY_generate_key(eckey))
656 : : {
657 : 0 : EC_KEY_free(eckey);
658 : 0 : goto end;
659 : : }
660 [ # # ]: 0 : if (outformat == FORMAT_ASN1)
661 : 0 : i = i2d_ECPrivateKey_bio(out, eckey);
662 [ # # ]: 0 : else if (outformat == FORMAT_PEM)
663 : 0 : i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
664 : : NULL, 0, NULL, NULL);
665 : : else
666 : : {
667 : 0 : BIO_printf(bio_err, "bad output format specified "
668 : : "for outfile\n");
669 : 0 : EC_KEY_free(eckey);
670 : 0 : goto end;
671 : : }
672 : 0 : EC_KEY_free(eckey);
673 : : }
674 : :
675 [ # # ]: 0 : if (need_rand)
676 : 0 : app_RAND_write_file(NULL, bio_err);
677 : :
678 : : ret=0;
679 : : end:
680 [ # # ]: 0 : if (ec_p)
681 : 0 : BN_free(ec_p);
682 [ # # ]: 0 : if (ec_a)
683 : 0 : BN_free(ec_a);
684 [ # # ]: 0 : if (ec_b)
685 : 0 : BN_free(ec_b);
686 [ # # ]: 0 : if (ec_gen)
687 : 0 : BN_free(ec_gen);
688 [ # # ]: 0 : if (ec_order)
689 : 0 : BN_free(ec_order);
690 [ # # ]: 0 : if (ec_cofactor)
691 : 0 : BN_free(ec_cofactor);
692 [ # # ]: 0 : if (buffer)
693 : 0 : OPENSSL_free(buffer);
694 [ # # ]: 0 : if (in != NULL)
695 : 0 : BIO_free(in);
696 [ # # ]: 0 : if (out != NULL)
697 : 0 : BIO_free_all(out);
698 [ # # ]: 0 : if (group != NULL)
699 : 0 : EC_GROUP_free(group);
700 : : apps_shutdown();
701 : 0 : OPENSSL_EXIT(ret);
702 : : }
703 : :
704 : 0 : static int ecparam_print_var(BIO *out, BIGNUM *in, const char *var,
705 : : int len, unsigned char *buffer)
706 : : {
707 : 0 : BIO_printf(out, "static unsigned char %s_%d[] = {", var, len);
708 [ # # ]: 0 : if (BN_is_zero(in))
709 : 0 : BIO_printf(out, "\n\t0x00");
710 : : else
711 : : {
712 : : int i, l;
713 : :
714 : 0 : l = BN_bn2bin(in, buffer);
715 [ # # ]: 0 : for (i=0; i<l-1; i++)
716 : : {
717 [ # # ]: 0 : if ((i%12) == 0)
718 : 0 : BIO_printf(out, "\n\t");
719 : 0 : BIO_printf(out, "0x%02X,", buffer[i]);
720 : : }
721 [ # # ]: 0 : if ((i%12) == 0)
722 : 0 : BIO_printf(out, "\n\t");
723 : 0 : BIO_printf(out, "0x%02X", buffer[i]);
724 : : }
725 : 0 : BIO_printf(out, "\n\t};\n\n");
726 : 0 : return 1;
727 : : }
728 : : #else /* !OPENSSL_NO_EC */
729 : :
730 : : # if PEDANTIC
731 : : static void *dummy=&dummy;
732 : : # endif
733 : :
734 : : #endif
|