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