Line data Source code
1 : /* keygen.c - key generation regression tests
2 : * Copyright (C) 2003, 2005, 2012 Free Software Foundation, Inc.
3 : * Copyright (C) 2013, 2015 g10 Code GmbH
4 : *
5 : * This file is part of Libgcrypt.
6 : *
7 : * Libgcrypt is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU Lesser General Public License as
9 : * published by the Free Software Foundation; either version 2.1 of
10 : * the License, or (at your option) any later version.
11 : *
12 : * Libgcrypt is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU Lesser General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU Lesser General Public
18 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : #include <config.h>
23 : #endif
24 : #include <stdio.h>
25 : #include <stdlib.h>
26 : #include <string.h>
27 : #include <stdarg.h>
28 : #include "../src/gcrypt-int.h"
29 :
30 :
31 : #define PGM "keygen"
32 :
33 : #define xmalloc(a) gcry_xmalloc ((a))
34 : #define xcalloc(a,b) gcry_xcalloc ((a),(b))
35 : #define xstrdup(a) gcry_xstrdup ((a))
36 : #define xfree(a) gcry_free ((a))
37 : #define pass() do { ; } while (0)
38 :
39 :
40 : static int verbose;
41 : static int debug;
42 : static int error_count;
43 : static int in_fips_mode;
44 :
45 :
46 : static void
47 0 : die (const char *format, ...)
48 : {
49 : va_list arg_ptr ;
50 :
51 0 : fflush (stdout);
52 0 : fprintf (stderr, "%s: ", PGM);
53 0 : va_start( arg_ptr, format ) ;
54 0 : vfprintf (stderr, format, arg_ptr );
55 0 : va_end(arg_ptr);
56 0 : if (*format && format[strlen(format)-1] != '\n')
57 0 : putc ('\n', stderr);
58 0 : exit (1);
59 : }
60 :
61 : static void
62 0 : fail (const char *format, ...)
63 : {
64 : va_list arg_ptr;
65 :
66 0 : fflush (stdout);
67 0 : fprintf (stderr, "%s: ", PGM);
68 : /* if (wherestr) */
69 : /* fprintf (stderr, "%s: ", wherestr); */
70 0 : va_start (arg_ptr, format);
71 0 : vfprintf (stderr, format, arg_ptr);
72 0 : va_end (arg_ptr);
73 0 : if (*format && format[strlen(format)-1] != '\n')
74 0 : putc ('\n', stderr);
75 0 : error_count++;
76 0 : if (error_count >= 50)
77 0 : die ("stopped after 50 errors.");
78 0 : }
79 :
80 : static void
81 0 : show (const char *format, ...)
82 : {
83 : va_list arg_ptr;
84 :
85 0 : fprintf (stderr, "%s: ", PGM);
86 0 : va_start (arg_ptr, format);
87 0 : vfprintf (stderr, format, arg_ptr);
88 0 : if (*format && format[strlen(format)-1] != '\n')
89 0 : putc ('\n', stderr);
90 0 : va_end (arg_ptr);
91 0 : }
92 :
93 :
94 : /* static void */
95 : /* show_note (const char *format, ...) */
96 : /* { */
97 : /* va_list arg_ptr; */
98 :
99 : /* if (!verbose && getenv ("srcdir")) */
100 : /* fputs (" ", stderr); /\* To align above "PASS: ". *\/ */
101 : /* else */
102 : /* fprintf (stderr, "%s: ", PGM); */
103 : /* va_start (arg_ptr, format); */
104 : /* vfprintf (stderr, format, arg_ptr); */
105 : /* if (*format && format[strlen(format)-1] != '\n') */
106 : /* putc ('\n', stderr); */
107 : /* va_end (arg_ptr); */
108 : /* } */
109 :
110 :
111 : static void
112 0 : show_sexp (const char *prefix, gcry_sexp_t a)
113 : {
114 : char *buf;
115 : size_t size;
116 :
117 0 : fprintf (stderr, "%s: ", PGM);
118 0 : if (prefix)
119 0 : fputs (prefix, stderr);
120 0 : size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
121 0 : buf = xmalloc (size);
122 :
123 0 : gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
124 0 : fprintf (stderr, "%.*s", (int)size, buf);
125 0 : gcry_free (buf);
126 0 : }
127 :
128 :
129 : static void
130 0 : show_mpi (const char *prefix, gcry_mpi_t a)
131 : {
132 : char *buf;
133 0 : void *bufaddr = &buf;
134 : gcry_error_t rc;
135 :
136 0 : fprintf (stderr, "%s: ", PGM);
137 0 : if (prefix)
138 0 : fputs (prefix, stderr);
139 0 : rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
140 0 : if (rc)
141 0 : fprintf (stderr, "[error printing number: %s]\n", gpg_strerror (rc));
142 : else
143 : {
144 0 : fprintf (stderr, "%s\n", buf);
145 0 : gcry_free (buf);
146 : }
147 0 : }
148 :
149 :
150 : static void
151 4 : check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e)
152 : {
153 : gcry_sexp_t skey, pkey, list;
154 :
155 4 : pkey = gcry_sexp_find_token (key, "public-key", 0);
156 4 : if (!pkey)
157 0 : fail ("public part missing in return value\n");
158 : else
159 : {
160 4 : gcry_mpi_t e = NULL;
161 :
162 4 : list = gcry_sexp_find_token (pkey, "e", 0);
163 4 : if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) )
164 0 : fail ("public exponent not found\n");
165 4 : else if (!expected_e)
166 : {
167 1 : if (verbose)
168 0 : show_mpi ("public exponent: ", e);
169 : }
170 3 : else if ( gcry_mpi_cmp_ui (e, expected_e))
171 : {
172 0 : show_mpi ("public exponent: ", e);
173 0 : fail ("public exponent is not %lu\n", expected_e);
174 : }
175 4 : gcry_sexp_release (list);
176 4 : gcry_mpi_release (e);
177 4 : gcry_sexp_release (pkey);
178 : }
179 :
180 4 : skey = gcry_sexp_find_token (key, "private-key", 0);
181 4 : if (!skey)
182 0 : fail ("private part missing in return value\n");
183 : else
184 : {
185 4 : int rc = gcry_pk_testkey (skey);
186 4 : if (rc)
187 0 : fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
188 4 : gcry_sexp_release (skey);
189 : }
190 4 : }
191 :
192 :
193 : static void
194 1 : check_rsa_keys (void)
195 : {
196 : gcry_sexp_t keyparm, key;
197 : int rc;
198 :
199 1 : if (verbose)
200 0 : show ("creating 2048 bit RSA key\n");
201 1 : rc = gcry_sexp_new (&keyparm,
202 : "(genkey\n"
203 : " (rsa\n"
204 : " (nbits 4:2048)\n"
205 : " ))", 0, 1);
206 1 : if (rc)
207 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
208 1 : rc = gcry_pk_genkey (&key, keyparm);
209 1 : gcry_sexp_release (keyparm);
210 1 : if (rc)
211 0 : die ("error generating RSA key: %s\n", gpg_strerror (rc));
212 :
213 1 : if (verbose)
214 0 : show ("creating 1024 bit RSA key\n");
215 1 : rc = gcry_sexp_new (&keyparm,
216 : "(genkey\n"
217 : " (rsa\n"
218 : " (nbits 4:1024)\n"
219 : " ))", 0, 1);
220 1 : if (rc)
221 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
222 :
223 1 : gcry_sexp_release (key);
224 1 : rc = gcry_pk_genkey (&key, keyparm);
225 1 : gcry_sexp_release (keyparm);
226 1 : if (rc && !in_fips_mode)
227 0 : fail ("error generating RSA key: %s\n", gpg_strerror (rc));
228 1 : else if (!rc && in_fips_mode)
229 0 : fail ("generating 1024 bit RSA key must not work!");
230 :
231 1 : if (!rc)
232 : {
233 1 : if (verbose > 1)
234 0 : show_sexp ("1024 bit RSA key:\n", key);
235 1 : check_generated_rsa_key (key, 65537);
236 : }
237 1 : gcry_sexp_release (key);
238 :
239 1 : if (verbose)
240 0 : show ("creating 2048 bit RSA key with e=65539\n");
241 1 : rc = gcry_sexp_new (&keyparm,
242 : "(genkey\n"
243 : " (rsa\n"
244 : " (nbits 4:2048)\n"
245 : " (rsa-use-e 5:65539)\n"
246 : " ))", 0, 1);
247 1 : if (rc)
248 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
249 1 : rc = gcry_pk_genkey (&key, keyparm);
250 1 : gcry_sexp_release (keyparm);
251 1 : if (rc)
252 0 : fail ("error generating RSA key: %s\n", gpg_strerror (rc));
253 :
254 1 : if (!rc)
255 1 : check_generated_rsa_key (key, 65539);
256 1 : gcry_sexp_release (key);
257 :
258 :
259 1 : if (verbose)
260 0 : show ("creating 512 bit RSA key with e=257\n");
261 1 : rc = gcry_sexp_new (&keyparm,
262 : "(genkey\n"
263 : " (rsa\n"
264 : " (nbits 3:512)\n"
265 : " (rsa-use-e 3:257)\n"
266 : " ))", 0, 1);
267 1 : if (rc)
268 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
269 1 : rc = gcry_pk_genkey (&key, keyparm);
270 1 : gcry_sexp_release (keyparm);
271 1 : if (rc && !in_fips_mode)
272 0 : fail ("error generating RSA key: %s\n", gpg_strerror (rc));
273 1 : else if (!rc && in_fips_mode)
274 0 : fail ("generating 512 bit RSA key must not work!");
275 :
276 1 : if (verbose && rc && in_fips_mode)
277 0 : show ("... correctly rejected key creation in FIPS mode (%s)\n",
278 : gpg_strerror (rc));
279 :
280 1 : if (!rc)
281 1 : check_generated_rsa_key (key, 257);
282 1 : gcry_sexp_release (key);
283 :
284 1 : if (verbose)
285 0 : show ("creating 512 bit RSA key with default e\n");
286 1 : rc = gcry_sexp_new (&keyparm,
287 : "(genkey\n"
288 : " (rsa\n"
289 : " (nbits 3:512)\n"
290 : " (rsa-use-e 1:0)\n"
291 : " ))", 0, 1);
292 1 : if (rc)
293 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
294 1 : rc = gcry_pk_genkey (&key, keyparm);
295 1 : gcry_sexp_release (keyparm);
296 1 : if (rc && !in_fips_mode)
297 0 : fail ("error generating RSA key: %s\n", gpg_strerror (rc));
298 1 : else if (!rc && in_fips_mode)
299 0 : fail ("generating 512 bit RSA key must not work!");
300 :
301 1 : if (verbose && rc && in_fips_mode)
302 0 : show ("... correctly rejected key creation in FIPS mode (%s)\n",
303 : gpg_strerror (rc));
304 :
305 :
306 1 : if (!rc)
307 1 : check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
308 1 : gcry_sexp_release (key);
309 1 : }
310 :
311 :
312 : static void
313 1 : check_elg_keys (void)
314 : {
315 : gcry_sexp_t keyparm, key;
316 : int rc;
317 :
318 1 : if (verbose)
319 0 : show ("creating 1024 bit Elgamal key\n");
320 1 : rc = gcry_sexp_new (&keyparm,
321 : "(genkey\n"
322 : " (elg\n"
323 : " (nbits 4:1024)\n"
324 : " ))", 0, 1);
325 1 : if (rc)
326 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
327 1 : rc = gcry_pk_genkey (&key, keyparm);
328 1 : gcry_sexp_release (keyparm);
329 1 : if (rc)
330 0 : die ("error generating Elgamal key: %s\n", gpg_strerror (rc));
331 1 : if (verbose > 1)
332 0 : show_sexp ("1024 bit Elgamal key:\n", key);
333 1 : gcry_sexp_release (key);
334 1 : }
335 :
336 :
337 : static void
338 1 : check_dsa_keys (void)
339 : {
340 : gcry_sexp_t keyparm, key;
341 : int rc;
342 : int i;
343 :
344 : /* Check that DSA generation works and that it can grok the qbits
345 : argument. */
346 1 : if (verbose)
347 0 : show ("creating 5 1024 bit DSA keys\n");
348 6 : for (i=0; i < 5; i++)
349 : {
350 5 : rc = gcry_sexp_new (&keyparm,
351 : "(genkey\n"
352 : " (dsa\n"
353 : " (nbits 4:1024)\n"
354 : " ))", 0, 1);
355 5 : if (rc)
356 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
357 5 : rc = gcry_pk_genkey (&key, keyparm);
358 5 : gcry_sexp_release (keyparm);
359 5 : if (rc && !in_fips_mode)
360 0 : die ("error generating DSA key: %s\n", gpg_strerror (rc));
361 5 : else if (!rc && in_fips_mode)
362 0 : die ("generating 1024 bit DSA key must not work!");
363 5 : if (!i && verbose > 1)
364 0 : show_sexp ("1024 bit DSA key:\n", key);
365 5 : gcry_sexp_release (key);
366 : }
367 :
368 1 : if (verbose)
369 0 : show ("creating 1536 bit DSA key\n");
370 1 : rc = gcry_sexp_new (&keyparm,
371 : "(genkey\n"
372 : " (dsa\n"
373 : " (nbits 4:1536)\n"
374 : " (qbits 3:224)\n"
375 : " ))", 0, 1);
376 1 : if (rc)
377 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
378 1 : rc = gcry_pk_genkey (&key, keyparm);
379 1 : gcry_sexp_release (keyparm);
380 1 : if (rc && !in_fips_mode)
381 0 : die ("error generating DSA key: %s\n", gpg_strerror (rc));
382 1 : else if (!rc && in_fips_mode)
383 0 : die ("generating 1536 bit DSA key must not work!");
384 1 : if (verbose > 1)
385 0 : show_sexp ("1536 bit DSA key:\n", key);
386 1 : gcry_sexp_release (key);
387 :
388 1 : if (verbose)
389 0 : show ("creating 3072 bit DSA key\n");
390 1 : rc = gcry_sexp_new (&keyparm,
391 : "(genkey\n"
392 : " (dsa\n"
393 : " (nbits 4:3072)\n"
394 : " (qbits 3:256)\n"
395 : " ))", 0, 1);
396 1 : if (rc)
397 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
398 1 : rc = gcry_pk_genkey (&key, keyparm);
399 1 : gcry_sexp_release (keyparm);
400 1 : if (rc)
401 0 : die ("error generating DSA key: %s\n", gpg_strerror (rc));
402 1 : if (verbose > 1)
403 0 : show_sexp ("3072 bit DSA key:\n", key);
404 1 : gcry_sexp_release (key);
405 :
406 1 : if (verbose)
407 0 : show ("creating 2048/256 bit DSA key\n");
408 1 : rc = gcry_sexp_new (&keyparm,
409 : "(genkey\n"
410 : " (dsa\n"
411 : " (nbits 4:2048)\n"
412 : " (qbits 3:256)\n"
413 : " ))", 0, 1);
414 1 : if (rc)
415 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
416 1 : rc = gcry_pk_genkey (&key, keyparm);
417 1 : gcry_sexp_release (keyparm);
418 1 : if (rc)
419 0 : die ("error generating DSA key: %s\n", gpg_strerror (rc));
420 1 : if (verbose > 1)
421 0 : show_sexp ("2048 bit DSA key:\n", key);
422 1 : gcry_sexp_release (key);
423 :
424 1 : if (verbose)
425 0 : show ("creating 2048/224 bit DSA key\n");
426 1 : rc = gcry_sexp_new (&keyparm,
427 : "(genkey\n"
428 : " (dsa\n"
429 : " (nbits 4:2048)\n"
430 : " (qbits 3:224)\n"
431 : " ))", 0, 1);
432 1 : if (rc)
433 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
434 1 : rc = gcry_pk_genkey (&key, keyparm);
435 1 : gcry_sexp_release (keyparm);
436 1 : if (rc)
437 0 : die ("error generating DSA key: %s\n", gpg_strerror (rc));
438 1 : if (verbose > 1)
439 0 : show_sexp ("2048 bit DSA key:\n", key);
440 1 : gcry_sexp_release (key);
441 1 : }
442 :
443 :
444 : static void
445 9 : check_generated_ecc_key (gcry_sexp_t key)
446 : {
447 : gcry_sexp_t skey, pkey;
448 :
449 9 : pkey = gcry_sexp_find_token (key, "public-key", 0);
450 9 : if (!pkey)
451 0 : fail ("public part missing in return value\n");
452 : else
453 : {
454 : /* Fixme: Check more stuff. */
455 9 : gcry_sexp_release (pkey);
456 : }
457 :
458 9 : skey = gcry_sexp_find_token (key, "private-key", 0);
459 9 : if (!skey)
460 0 : fail ("private part missing in return value\n");
461 : else
462 : {
463 9 : int rc = gcry_pk_testkey (skey);
464 9 : if (rc)
465 0 : fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
466 9 : gcry_sexp_release (skey);
467 : }
468 :
469 : /* Finally check that gcry_pk_testkey also works on the entire
470 : S-expression. */
471 : {
472 9 : int rc = gcry_pk_testkey (key);
473 9 : if (rc)
474 0 : fail ("gcry_pk_testkey failed on key pair: %s\n", gpg_strerror (rc));
475 : }
476 9 : }
477 :
478 :
479 : static void
480 1 : check_ecc_keys (void)
481 : {
482 1 : const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256",
483 : "Ed25519", NULL };
484 : int testno;
485 : gcry_sexp_t keyparm, key;
486 : int rc;
487 :
488 5 : for (testno=0; curves[testno]; testno++)
489 : {
490 4 : if (verbose)
491 0 : show ("creating ECC key using curve %s\n", curves[testno]);
492 4 : if (!strcmp (curves[testno], "Ed25519"))
493 : {
494 : /* Ed25519 isn't allowed in fips mode */
495 1 : if (in_fips_mode)
496 0 : continue;
497 1 : rc = gcry_sexp_build (&keyparm, NULL,
498 : "(genkey(ecc(curve %s)(flags param eddsa)))",
499 : curves[testno]);
500 : }
501 : else
502 3 : rc = gcry_sexp_build (&keyparm, NULL,
503 : "(genkey(ecc(curve %s)(flags param)))",
504 : curves[testno]);
505 4 : if (rc)
506 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
507 4 : rc = gcry_pk_genkey (&key, keyparm);
508 4 : gcry_sexp_release (keyparm);
509 4 : if (rc)
510 0 : die ("error generating ECC key using curve %s: %s\n",
511 : curves[testno], gpg_strerror (rc));
512 :
513 4 : if (verbose > 1)
514 0 : show_sexp ("ECC key:\n", key);
515 :
516 4 : check_generated_ecc_key (key);
517 :
518 4 : gcry_sexp_release (key);
519 : }
520 :
521 1 : if (verbose)
522 0 : show ("creating ECC key using curve Ed25519 for ECDSA\n");
523 1 : rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve Ed25519)))");
524 1 : if (rc)
525 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
526 1 : rc = gcry_pk_genkey (&key, keyparm);
527 1 : gcry_sexp_release (keyparm);
528 1 : if (rc && !in_fips_mode)
529 0 : die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
530 : gpg_strerror (rc));
531 1 : else if (!rc && in_fips_mode)
532 0 : fail ("generating Ed25519 key must not work!");
533 :
534 1 : if (verbose && rc && in_fips_mode)
535 0 : show ("... correctly rejected key creation in FIPS mode (%s)\n",
536 : gpg_strerror (rc));
537 :
538 1 : if (!rc)
539 : {
540 1 : if (verbose > 1)
541 0 : show_sexp ("ECC key:\n", key);
542 :
543 1 : check_generated_ecc_key (key);
544 : }
545 1 : gcry_sexp_release (key);
546 :
547 1 : if (verbose)
548 0 : show ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
549 1 : rc = gcry_sexp_build (&keyparm, NULL,
550 : "(genkey(ecc(curve Ed25519)(flags nocomp)))");
551 1 : if (rc)
552 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
553 1 : rc = gcry_pk_genkey (&key, keyparm);
554 1 : gcry_sexp_release (keyparm);
555 1 : if (rc && !in_fips_mode)
556 0 : die ("error generating ECC key using curve Ed25519 for ECDSA"
557 : " (nocomp): %s\n",
558 : gpg_strerror (rc));
559 1 : else if (!rc && in_fips_mode)
560 0 : fail ("generating Ed25519 key must not work in FIPS mode!");
561 :
562 1 : if (verbose && rc && in_fips_mode)
563 0 : show ("... correctly rejected key creation in FIPS mode (%s)\n",
564 : gpg_strerror (rc));
565 1 : gcry_sexp_release (key);
566 :
567 1 : if (verbose)
568 0 : show ("creating ECC key using curve NIST P-384 for ECDSA\n");
569 :
570 : /* Must be specified as nistp384 (one word), because ecc_generate
571 : * uses _gcry_sexp_nth_string which takes the first word of the name
572 : * and thus libgcrypt can't find it later in its curves table. */
573 1 : rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve nistp384)))");
574 1 : if (rc)
575 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
576 1 : rc = gcry_pk_genkey (&key, keyparm);
577 1 : gcry_sexp_release (keyparm);
578 1 : if (rc)
579 0 : die ("error generating ECC key using curve NIST P-384 for ECDSA: %s\n",
580 : gpg_strerror (rc));
581 :
582 1 : if (verbose > 1)
583 0 : show_sexp ("ECC key:\n", key);
584 :
585 1 : check_generated_ecc_key (key);
586 1 : gcry_sexp_release (key);
587 :
588 1 : if (verbose)
589 0 : show ("creating ECC key using curve NIST P-384 for ECDSA (nocomp)\n");
590 1 : rc = gcry_sexp_build (&keyparm, NULL,
591 : "(genkey(ecc(curve nistp384)(flags nocomp)))");
592 1 : if (rc)
593 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
594 1 : rc = gcry_pk_genkey (&key, keyparm);
595 1 : gcry_sexp_release (keyparm);
596 1 : if (rc)
597 0 : die ("error generating ECC key using curve NIST P-384 for ECDSA"
598 : " (nocomp): %s\n",
599 : gpg_strerror (rc));
600 :
601 1 : if (verbose > 1)
602 0 : show_sexp ("ECC key:\n", key);
603 :
604 1 : check_generated_ecc_key (key);
605 1 : gcry_sexp_release (key);
606 :
607 :
608 1 : if (verbose)
609 0 : show ("creating ECC key using curve Ed25519 for ECDSA (transient-key)\n");
610 1 : rc = gcry_sexp_build (&keyparm, NULL,
611 : "(genkey(ecc(curve Ed25519)(flags transient-key)))");
612 1 : if (rc)
613 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
614 1 : rc = gcry_pk_genkey (&key, keyparm);
615 1 : gcry_sexp_release (keyparm);
616 1 : if (rc && !in_fips_mode)
617 0 : die ("error generating ECC key using curve Ed25519 for ECDSA"
618 : " (transient-key): %s\n",
619 : gpg_strerror (rc));
620 1 : else if (!rc && in_fips_mode)
621 0 : fail ("generating Ed25519 key must not work in FIPS mode!");
622 :
623 1 : if (verbose && rc && in_fips_mode)
624 0 : show ("... correctly rejected key creation in FIPS mode (%s)\n",
625 : gpg_strerror (rc));
626 :
627 1 : if (!rc)
628 : {
629 1 : if (verbose > 1)
630 0 : show_sexp ("ECC key:\n", key);
631 1 : check_generated_ecc_key (key);
632 : }
633 1 : gcry_sexp_release (key);
634 :
635 1 : if (verbose)
636 0 : show ("creating ECC key using curve Ed25519 for ECDSA "
637 : "(transient-key no-keytest)\n");
638 1 : rc = gcry_sexp_build (&keyparm, NULL,
639 : "(genkey(ecc(curve Ed25519)"
640 : "(flags transient-key no-keytest)))");
641 1 : if (rc)
642 0 : die ("error creating S-expression: %s\n", gpg_strerror (rc));
643 1 : rc = gcry_pk_genkey (&key, keyparm);
644 1 : gcry_sexp_release (keyparm);
645 1 : if (rc && !in_fips_mode)
646 0 : die ("error generating ECC key using curve Ed25519 for ECDSA"
647 : " (transient-key no-keytest): %s\n",
648 : gpg_strerror (rc));
649 1 : else if (!rc && in_fips_mode)
650 0 : fail ("generating Ed25519 key must not work in FIPS mode!");
651 :
652 1 : if (verbose && rc && in_fips_mode)
653 0 : show ("... correctly rejected key creation in FIPS mode (%s)\n",
654 : gpg_strerror (rc));
655 :
656 1 : if (!rc)
657 : {
658 1 : if (verbose > 1)
659 0 : show_sexp ("ECC key:\n", key);
660 1 : check_generated_ecc_key (key);
661 : }
662 1 : gcry_sexp_release (key);
663 1 : }
664 :
665 :
666 : static void
667 1 : check_nonce (void)
668 : {
669 : char a[32], b[32];
670 : int i,j;
671 1 : int oops=0;
672 :
673 1 : if (verbose)
674 0 : show ("checking gcry_create_nonce\n");
675 :
676 1 : gcry_create_nonce (a, sizeof a);
677 11 : for (i=0; i < 10; i++)
678 : {
679 10 : gcry_create_nonce (b, sizeof b);
680 10 : if (!memcmp (a, b, sizeof a))
681 0 : die ("identical nonce found\n");
682 : }
683 11 : for (i=0; i < 10; i++)
684 : {
685 10 : gcry_create_nonce (a, sizeof a);
686 10 : if (!memcmp (a, b, sizeof a))
687 0 : die ("identical nonce found\n");
688 : }
689 :
690 : again:
691 32 : for (i=1,j=0; i < sizeof a; i++)
692 31 : if (a[0] == a[i])
693 0 : j++;
694 1 : if (j+1 == sizeof (a))
695 : {
696 0 : if (oops)
697 0 : die ("impossible nonce found\n");
698 0 : oops++;
699 0 : gcry_create_nonce (a, sizeof a);
700 0 : goto again;
701 : }
702 1 : }
703 :
704 :
705 : static void
706 0 : progress_cb (void *cb_data, const char *what, int printchar,
707 : int current, int total)
708 : {
709 : (void)cb_data;
710 : (void)what;
711 : (void)current;
712 : (void)total;
713 :
714 0 : if (printchar == '\n')
715 0 : fputs ( "<LF>", stdout);
716 : else
717 0 : putchar (printchar);
718 0 : fflush (stdout);
719 0 : }
720 :
721 :
722 : static void
723 0 : usage (int mode)
724 : {
725 0 : fputs ("usage: " PGM " [options] [{rsa|elg|dsa|ecc|nonce}]\n"
726 : "Options:\n"
727 : " --verbose be verbose\n"
728 : " --debug flyswatter\n"
729 : " --fips run in FIPS mode\n"
730 : " --progress print progress indicators\n",
731 : mode? stderr : stdout);
732 0 : if (mode)
733 0 : exit (1);
734 0 : }
735 :
736 : int
737 1 : main (int argc, char **argv)
738 : {
739 1 : int last_argc = -1;
740 1 : int opt_fips = 0;
741 1 : int with_progress = 0;
742 :
743 1 : if (argc)
744 1 : { argc--; argv++; }
745 :
746 2 : while (argc && last_argc != argc )
747 : {
748 0 : last_argc = argc;
749 0 : if (!strcmp (*argv, "--"))
750 : {
751 0 : argc--; argv++;
752 0 : break;
753 : }
754 0 : else if (!strcmp (*argv, "--help"))
755 : {
756 0 : usage (0);
757 0 : exit (0);
758 : }
759 0 : else if (!strcmp (*argv, "--verbose"))
760 : {
761 0 : verbose++;
762 0 : argc--; argv++;
763 : }
764 0 : else if (!strcmp (*argv, "--debug"))
765 : {
766 0 : verbose += 2;
767 0 : debug++;
768 0 : argc--; argv++;
769 : }
770 0 : else if (!strcmp (*argv, "--fips"))
771 : {
772 0 : argc--; argv++;
773 0 : opt_fips = 1;
774 : }
775 0 : else if (!strcmp (*argv, "--progress"))
776 : {
777 0 : argc--; argv++;
778 0 : with_progress = 1;
779 : }
780 0 : else if (!strncmp (*argv, "--", 2))
781 0 : die ("unknown option '%s'", *argv);
782 : else
783 0 : break;
784 : }
785 :
786 1 : gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
787 1 : if (opt_fips)
788 0 : gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
789 :
790 1 : if (!gcry_check_version (GCRYPT_VERSION))
791 0 : die ("version mismatch\n");
792 :
793 1 : if (!opt_fips)
794 1 : gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
795 :
796 1 : gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
797 1 : if (debug)
798 0 : gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
799 : /* No valuable keys are create, so we can speed up our RNG. */
800 1 : gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
801 1 : if (with_progress)
802 0 : gcry_set_progress_handler (progress_cb, NULL);
803 :
804 1 : if ( gcry_fips_mode_active () )
805 0 : in_fips_mode = 1;
806 :
807 1 : if (opt_fips && !in_fips_mode)
808 0 : die ("failed to switch into FIPS mode\n");
809 :
810 1 : if (!argc)
811 : {
812 1 : check_rsa_keys ();
813 1 : check_elg_keys ();
814 1 : check_dsa_keys ();
815 1 : check_ecc_keys ();
816 1 : check_nonce ();
817 : }
818 : else
819 : {
820 0 : for (; argc; argc--, argv++)
821 0 : if (!strcmp (*argv, "rsa"))
822 0 : check_rsa_keys ();
823 0 : else if (!strcmp (*argv, "elg"))
824 0 : check_elg_keys ();
825 0 : else if (!strcmp (*argv, "dsa"))
826 0 : check_dsa_keys ();
827 0 : else if (!strcmp (*argv, "ecc"))
828 0 : check_ecc_keys ();
829 0 : else if (!strcmp (*argv, "nonce"))
830 0 : check_nonce ();
831 : else
832 0 : usage (1);
833 : }
834 :
835 1 : return error_count? 1:0;
836 : }
|