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