ecparam.c 23 KB

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