tests: Fixes for RSA testsuite in FIPS mode
[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 512 bit RSA key with e=257\n");
240   rc = gcry_sexp_new (&keyparm,
241                       "(genkey\n"
242                       " (rsa\n"
243                       "  (nbits 3:512)\n"
244                       "  (rsa-use-e 3:257)\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 512 bit RSA key must not work!");
254
255   if (!rc)
256     check_generated_rsa_key (key, 257);
257   gcry_sexp_release (key);
258
259   if (verbose)
260     show ("creating 512 bit RSA key with default e\n");
261   rc = gcry_sexp_new (&keyparm,
262                       "(genkey\n"
263                       " (rsa\n"
264                       "  (nbits 3:512)\n"
265                       "  (rsa-use-e 1:0)\n"
266                       " ))", 0, 1);
267   if (rc)
268     die ("error creating S-expression: %s\n", gpg_strerror (rc));
269   rc = gcry_pk_genkey (&key, keyparm);
270   gcry_sexp_release (keyparm);
271   if (rc && !in_fips_mode)
272     fail ("error generating RSA key: %s\n", gpg_strerror (rc));
273   else if (!rc && in_fips_mode)
274     fail ("generating 512 bit RSA key must not work!");
275
276   if (!rc)
277     check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
278   gcry_sexp_release (key);
279 }
280
281
282 static void
283 check_elg_keys (void)
284 {
285   gcry_sexp_t keyparm, key;
286   int rc;
287
288   if (verbose)
289     show ("creating 1024 bit Elgamal key\n");
290   rc = gcry_sexp_new (&keyparm,
291                       "(genkey\n"
292                       " (elg\n"
293                       "  (nbits 4:1024)\n"
294                       " ))", 0, 1);
295   if (rc)
296     die ("error creating S-expression: %s\n", gpg_strerror (rc));
297   rc = gcry_pk_genkey (&key, keyparm);
298   gcry_sexp_release (keyparm);
299   if (rc)
300     die ("error generating Elgamal key: %s\n", gpg_strerror (rc));
301   if (verbose > 1)
302     show_sexp ("1024 bit Elgamal key:\n", key);
303   gcry_sexp_release (key);
304 }
305
306
307 static void
308 check_dsa_keys (void)
309 {
310   gcry_sexp_t keyparm, key;
311   int rc;
312   int i;
313
314   /* Check that DSA generation works and that it can grok the qbits
315      argument. */
316   if (verbose)
317     show ("creating 5 1024 bit DSA keys\n");
318   for (i=0; i < 5; i++)
319     {
320       rc = gcry_sexp_new (&keyparm,
321                           "(genkey\n"
322                           " (dsa\n"
323                           "  (nbits 4:1024)\n"
324                           " ))", 0, 1);
325       if (rc)
326         die ("error creating S-expression: %s\n", gpg_strerror (rc));
327       rc = gcry_pk_genkey (&key, keyparm);
328       gcry_sexp_release (keyparm);
329       if (rc && !in_fips_mode)
330         die ("error generating DSA key: %s\n", gpg_strerror (rc));
331       else if (!rc && in_fips_mode)
332         die ("generating 512 bit DSA key must not work!");
333       if (!i && verbose > 1)
334         show_sexp ("1024 bit DSA key:\n", key);
335       gcry_sexp_release (key);
336     }
337
338   if (verbose)
339     show ("creating 1536 bit DSA key\n");
340   rc = gcry_sexp_new (&keyparm,
341                       "(genkey\n"
342                       " (dsa\n"
343                       "  (nbits 4:1536)\n"
344                       "  (qbits 3:224)\n"
345                       " ))", 0, 1);
346   if (rc)
347     die ("error creating S-expression: %s\n", gpg_strerror (rc));
348   rc = gcry_pk_genkey (&key, keyparm);
349   gcry_sexp_release (keyparm);
350   if (rc && !in_fips_mode)
351     die ("error generating DSA key: %s\n", gpg_strerror (rc));
352   else if (!rc && in_fips_mode)
353     die ("generating 1536 bit DSA key must not work!");
354   if (verbose > 1)
355     show_sexp ("1536 bit DSA key:\n", key);
356   gcry_sexp_release (key);
357 }
358
359
360 static void
361 check_generated_ecc_key (gcry_sexp_t key)
362 {
363   gcry_sexp_t skey, pkey;
364
365   pkey = gcry_sexp_find_token (key, "public-key", 0);
366   if (!pkey)
367     fail ("public part missing in return value\n");
368   else
369     {
370       /* Fixme: Check more stuff.  */
371       gcry_sexp_release (pkey);
372     }
373
374   skey = gcry_sexp_find_token (key, "private-key", 0);
375   if (!skey)
376     fail ("private part missing in return value\n");
377   else
378     {
379       int rc = gcry_pk_testkey (skey);
380       if (rc)
381         fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
382       gcry_sexp_release (skey);
383     }
384
385   /* Finally check that gcry_pk_testkey also works on the entire
386      S-expression.  */
387   {
388     int rc = gcry_pk_testkey (key);
389     if (rc)
390       fail ("gcry_pk_testkey failed on key pair: %s\n", gpg_strerror (rc));
391   }
392 }
393
394
395 static void
396 check_ecc_keys (void)
397 {
398   const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256",
399                            "Ed25519", NULL };
400   int testno;
401   gcry_sexp_t keyparm, key;
402   int rc;
403
404   for (testno=0; curves[testno]; testno++)
405     {
406       if (verbose)
407         show ("creating ECC key using curve %s\n", curves[testno]);
408       if (!strcmp (curves[testno], "Ed25519"))
409         rc = gcry_sexp_build (&keyparm, NULL,
410                               "(genkey(ecc(curve %s)(flags param eddsa)))",
411                               curves[testno]);
412       else
413         rc = gcry_sexp_build (&keyparm, NULL,
414                               "(genkey(ecc(curve %s)(flags param)))",
415                               curves[testno]);
416       if (rc)
417         die ("error creating S-expression: %s\n", gpg_strerror (rc));
418       rc = gcry_pk_genkey (&key, keyparm);
419       gcry_sexp_release (keyparm);
420       if (rc)
421         die ("error generating ECC key using curve %s: %s\n",
422              curves[testno], gpg_strerror (rc));
423
424       if (verbose > 1)
425         show_sexp ("ECC key:\n", key);
426
427       check_generated_ecc_key (key);
428
429       gcry_sexp_release (key);
430     }
431
432   if (verbose)
433     show ("creating ECC key using curve Ed25519 for ECDSA\n");
434   rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve Ed25519)))");
435   if (rc)
436     die ("error creating S-expression: %s\n", gpg_strerror (rc));
437   rc = gcry_pk_genkey (&key, keyparm);
438   gcry_sexp_release (keyparm);
439   if (rc)
440     die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
441          gpg_strerror (rc));
442
443   if (verbose > 1)
444     show_sexp ("ECC key:\n", key);
445
446   check_generated_ecc_key (key);
447   gcry_sexp_release (key);
448
449   if (verbose)
450     show ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
451   rc = gcry_sexp_build (&keyparm, NULL,
452                         "(genkey(ecc(curve Ed25519)(flags nocomp)))");
453   if (rc)
454     die ("error creating S-expression: %s\n", gpg_strerror (rc));
455   rc = gcry_pk_genkey (&key, keyparm);
456   gcry_sexp_release (keyparm);
457   if (rc)
458     die ("error generating ECC key using curve Ed25519 for ECDSA"
459          " (nocomp): %s\n",
460          gpg_strerror (rc));
461
462   if (verbose > 1)
463     show_sexp ("ECC key:\n", key);
464
465   check_generated_ecc_key (key);
466   gcry_sexp_release (key);
467
468
469   if (verbose)
470     show ("creating ECC key using curve Ed25519 for ECDSA (transient-key)\n");
471   rc = gcry_sexp_build (&keyparm, NULL,
472                         "(genkey(ecc(curve Ed25519)(flags transient-key)))");
473   if (rc)
474     die ("error creating S-expression: %s\n", gpg_strerror (rc));
475   rc = gcry_pk_genkey (&key, keyparm);
476   gcry_sexp_release (keyparm);
477   if (rc)
478     die ("error generating ECC key using curve Ed25519 for ECDSA"
479          " (transient-key): %s\n",
480          gpg_strerror (rc));
481   if (verbose > 1)
482     show_sexp ("ECC key:\n", key);
483   check_generated_ecc_key (key);
484   gcry_sexp_release (key);
485
486   if (verbose)
487     show ("creating ECC key using curve Ed25519 for ECDSA "
488           "(transient-key no-keytest)\n");
489   rc = gcry_sexp_build (&keyparm, NULL,
490                         "(genkey(ecc(curve Ed25519)"
491                         "(flags transient-key no-keytest)))");
492   if (rc)
493     die ("error creating S-expression: %s\n", gpg_strerror (rc));
494   rc = gcry_pk_genkey (&key, keyparm);
495   gcry_sexp_release (keyparm);
496   if (rc)
497     die ("error generating ECC key using curve Ed25519 for ECDSA"
498          " (transient-key no-keytest): %s\n",
499          gpg_strerror (rc));
500   if (verbose > 1)
501     show_sexp ("ECC key:\n", key);
502   check_generated_ecc_key (key);
503   gcry_sexp_release (key);
504 }
505
506
507 static void
508 check_nonce (void)
509 {
510   char a[32], b[32];
511   int i,j;
512   int oops=0;
513
514   if (verbose)
515     show ("checking gcry_create_nonce\n");
516
517   gcry_create_nonce (a, sizeof a);
518   for (i=0; i < 10; i++)
519     {
520       gcry_create_nonce (b, sizeof b);
521       if (!memcmp (a, b, sizeof a))
522         die ("identical nonce found\n");
523     }
524   for (i=0; i < 10; i++)
525     {
526       gcry_create_nonce (a, sizeof a);
527       if (!memcmp (a, b, sizeof a))
528         die ("identical nonce found\n");
529     }
530
531  again:
532   for (i=1,j=0; i < sizeof a; i++)
533     if (a[0] == a[i])
534       j++;
535   if (j+1 == sizeof (a))
536     {
537       if (oops)
538         die ("impossible nonce found\n");
539       oops++;
540       gcry_create_nonce (a, sizeof a);
541       goto again;
542     }
543 }
544
545
546 static void
547 progress_cb (void *cb_data, const char *what, int printchar,
548                   int current, int total)
549 {
550   (void)cb_data;
551   (void)what;
552   (void)current;
553   (void)total;
554
555   if (printchar == '\n')
556     fputs ( "<LF>", stdout);
557   else
558     putchar (printchar);
559   fflush (stdout);
560 }
561
562
563 static void
564 usage (int mode)
565 {
566   fputs ("usage: " PGM " [options] [{rsa|elg|dsa|ecc|nonce}]\n"
567          "Options:\n"
568          "  --verbose       be verbose\n"
569          "  --debug         flyswatter\n"
570          "  --progress      print progress indicators\n",
571          mode? stderr : stdout);
572   if (mode)
573     exit (1);
574 }
575
576 int
577 main (int argc, char **argv)
578 {
579   int last_argc = -1;
580   int with_progress = 0;
581
582   if (argc)
583     { argc--; argv++; }
584
585   while (argc && last_argc != argc )
586     {
587       last_argc = argc;
588       if (!strcmp (*argv, "--"))
589         {
590           argc--; argv++;
591           break;
592         }
593       else if (!strcmp (*argv, "--help"))
594         {
595           usage (0);
596           exit (0);
597         }
598       else if (!strcmp (*argv, "--verbose"))
599         {
600           verbose++;
601           argc--; argv++;
602         }
603       else if (!strcmp (*argv, "--debug"))
604         {
605           verbose += 2;
606           debug++;
607           argc--; argv++;
608         }
609       else if (!strcmp (*argv, "--progress"))
610         {
611           argc--; argv++;
612           with_progress = 1;
613         }
614       else if (!strncmp (*argv, "--", 2))
615         die ("unknown option '%s'", *argv);
616       else
617         break;
618     }
619
620   if (!gcry_check_version (GCRYPT_VERSION))
621     die ("version mismatch\n");
622   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
623   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
624   if (debug)
625     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
626   /* No valuable keys are create, so we can speed up our RNG. */
627   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
628   if (with_progress)
629     gcry_set_progress_handler (progress_cb, NULL);
630
631   if ( gcry_fips_mode_active () )
632     in_fips_mode = 1;
633
634   if (!argc)
635     {
636       check_rsa_keys ();
637       check_elg_keys ();
638       check_dsa_keys ();
639       check_ecc_keys ();
640       check_nonce ();
641     }
642   else
643     {
644       for (; argc; argc--, argv++)
645         if (!strcmp (*argv, "rsa"))
646           check_rsa_keys ();
647         else if (!strcmp (*argv, "elg"))
648           check_elg_keys ();
649         else if (!strcmp (*argv, "dsa"))
650           check_dsa_keys ();
651         else if (!strcmp (*argv, "ecc"))
652           check_ecc_keys ();
653         else if (!strcmp (*argv, "nonce"))
654           check_nonce ();
655         else
656           usage (1);
657     }
658
659   return error_count? 1:0;
660 }