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