Add GMAC to MAC API
[libgcrypt.git] / tests / keygen.c
1 /* keygen.c  -  key generation regression tests
2  * Copyright (C) 2003, 2005, 2012 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
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
44
45 static void
46 die (const char *format, ...)
47 {
48   va_list arg_ptr ;
49
50   fflush (stdout);
51   fprintf (stderr, "%s: ", PGM);
52   va_start( arg_ptr, format ) ;
53   vfprintf (stderr, format, arg_ptr );
54   va_end(arg_ptr);
55   if (*format && format[strlen(format)-1] != '\n')
56     putc ('\n', stderr);
57   exit (1);
58 }
59
60 static void
61 fail (const char *format, ...)
62 {
63   va_list arg_ptr;
64
65   fflush (stdout);
66   fprintf (stderr, "%s: ", PGM);
67   /* if (wherestr) */
68   /*   fprintf (stderr, "%s: ", wherestr); */
69   va_start (arg_ptr, format);
70   vfprintf (stderr, format, arg_ptr);
71   va_end (arg_ptr);
72   if (*format && format[strlen(format)-1] != '\n')
73     putc ('\n', stderr);
74   error_count++;
75   if (error_count >= 50)
76     die ("stopped after 50 errors.");
77 }
78
79 static void
80 show (const char *format, ...)
81 {
82   va_list arg_ptr;
83
84   fprintf (stderr, "%s: ", PGM);
85   va_start (arg_ptr, format);
86   vfprintf (stderr, format, arg_ptr);
87   if (*format && format[strlen(format)-1] != '\n')
88     putc ('\n', stderr);
89   va_end (arg_ptr);
90 }
91
92
93 static void
94 show_note (const char *format, ...)
95 {
96   va_list arg_ptr;
97
98   if (!verbose && getenv ("srcdir"))
99     fputs ("      ", stderr);  /* To align above "PASS: ".  */
100   else
101     fprintf (stderr, "%s: ", PGM);
102   va_start (arg_ptr, format);
103   vfprintf (stderr, format, arg_ptr);
104   if (*format && format[strlen(format)-1] != '\n')
105     putc ('\n', stderr);
106   va_end (arg_ptr);
107 }
108
109
110 static void
111 show_sexp (const char *prefix, gcry_sexp_t a)
112 {
113   char *buf;
114   size_t size;
115
116   fprintf (stderr, "%s: ", PGM);
117   if (prefix)
118     fputs (prefix, stderr);
119   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
120   buf = xmalloc (size);
121
122   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
123   fprintf (stderr, "%.*s", (int)size, buf);
124   gcry_free (buf);
125 }
126
127
128 static void
129 show_mpi (const char *prefix, gcry_mpi_t a)
130 {
131   char *buf;
132   void *bufaddr = &buf;
133   gcry_error_t rc;
134
135   fprintf (stderr, "%s: ", PGM);
136   if (prefix)
137     fputs (prefix, stderr);
138   rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
139   if (rc)
140     fprintf (stderr, "[error printing number: %s]\n",  gpg_strerror (rc));
141   else
142     {
143       fprintf (stderr, "%s\n", buf);
144       gcry_free (buf);
145     }
146 }
147
148
149 static void
150 check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e)
151 {
152   gcry_sexp_t skey, pkey, list;
153
154   pkey = gcry_sexp_find_token (key, "public-key", 0);
155   if (!pkey)
156     fail ("public part missing in return value\n");
157   else
158     {
159       gcry_mpi_t e = NULL;
160
161       list = gcry_sexp_find_token (pkey, "e", 0);
162       if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) )
163         fail ("public exponent not found\n");
164       else if (!expected_e)
165         {
166           if (verbose)
167             show_mpi ("public exponent: ", e);
168         }
169       else if ( gcry_mpi_cmp_ui (e, expected_e))
170         {
171           show_mpi ("public exponent: ", e);
172           fail ("public exponent is not %lu\n", expected_e);
173         }
174       gcry_sexp_release (list);
175       gcry_mpi_release (e);
176       gcry_sexp_release (pkey);
177     }
178
179   skey = gcry_sexp_find_token (key, "private-key", 0);
180   if (!skey)
181     fail ("private part missing in return value\n");
182   else
183     {
184       int rc = gcry_pk_testkey (skey);
185       if (rc)
186         fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
187       gcry_sexp_release (skey);
188     }
189 }
190
191
192 static void
193 check_rsa_keys (void)
194 {
195   gcry_sexp_t keyparm, key;
196   int rc;
197
198   if (verbose)
199     show ("creating 1024 bit RSA key\n");
200   rc = gcry_sexp_new (&keyparm,
201                       "(genkey\n"
202                       " (rsa\n"
203                       "  (nbits 4:1024)\n"
204                       " ))", 0, 1);
205   if (rc)
206     die ("error creating S-expression: %s\n", gpg_strerror (rc));
207   rc = gcry_pk_genkey (&key, keyparm);
208   gcry_sexp_release (keyparm);
209   if (rc)
210     die ("error generating RSA key: %s\n", gpg_strerror (rc));
211   if (verbose > 1)
212     show_sexp ("1024 bit RSA key:\n", key);
213   check_generated_rsa_key (key, 65537);
214   gcry_sexp_release (key);
215
216
217   if (verbose)
218     show ("creating 512 bit RSA key with e=257\n");
219   rc = gcry_sexp_new (&keyparm,
220                       "(genkey\n"
221                       " (rsa\n"
222                       "  (nbits 3:512)\n"
223                       "  (rsa-use-e 3:257)\n"
224                       " ))", 0, 1);
225   if (rc)
226     die ("error creating S-expression: %s\n", gpg_strerror (rc));
227   rc = gcry_pk_genkey (&key, keyparm);
228   gcry_sexp_release (keyparm);
229   if (rc)
230     die ("error generating RSA key: %s\n", gpg_strerror (rc));
231
232   check_generated_rsa_key (key, 257);
233   gcry_sexp_release (key);
234
235   if (verbose)
236     show ("creating 512 bit RSA key with default e\n");
237   rc = gcry_sexp_new (&keyparm,
238                       "(genkey\n"
239                       " (rsa\n"
240                       "  (nbits 3:512)\n"
241                       "  (rsa-use-e 1:0)\n"
242                       " ))", 0, 1);
243   if (rc)
244     die ("error creating S-expression: %s\n", gpg_strerror (rc));
245   rc = gcry_pk_genkey (&key, keyparm);
246   gcry_sexp_release (keyparm);
247   if (rc)
248     die ("error generating RSA key: %s\n", gpg_strerror (rc));
249
250   check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
251   gcry_sexp_release (key);
252 }
253
254
255 static void
256 check_elg_keys (void)
257 {
258   gcry_sexp_t keyparm, key;
259   int rc;
260
261   if (verbose)
262     show ("creating 1024 bit Elgamal key\n");
263   rc = gcry_sexp_new (&keyparm,
264                       "(genkey\n"
265                       " (elg\n"
266                       "  (nbits 4:1024)\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)
273     die ("error generating Elgamal key: %s\n", gpg_strerror (rc));
274   if (verbose > 1)
275     show_sexp ("1024 bit Elgamal key:\n", key);
276   gcry_sexp_release (key);
277 }
278
279
280 static void
281 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   if (verbose)
290     show ("creating 5 1024 bit DSA keys\n");
291   for (i=0; i < 5; i++)
292     {
293       rc = gcry_sexp_new (&keyparm,
294                           "(genkey\n"
295                           " (dsa\n"
296                           "  (nbits 4:1024)\n"
297                           " ))", 0, 1);
298       if (rc)
299         die ("error creating S-expression: %s\n", gpg_strerror (rc));
300       rc = gcry_pk_genkey (&key, keyparm);
301       gcry_sexp_release (keyparm);
302       if (rc)
303         die ("error generating DSA key: %s\n", gpg_strerror (rc));
304       if (!i && verbose > 1)
305         show_sexp ("1024 bit DSA key:\n", key);
306       gcry_sexp_release (key);
307     }
308
309   if (verbose)
310     show ("creating 1536 bit DSA key\n");
311   rc = gcry_sexp_new (&keyparm,
312                       "(genkey\n"
313                       " (dsa\n"
314                       "  (nbits 4:1536)\n"
315                       "  (qbits 3:224)\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 DSA key: %s\n", gpg_strerror (rc));
323   if (verbose > 1)
324     show_sexp ("1536 bit DSA key:\n", key);
325   gcry_sexp_release (key);
326 }
327
328
329 static void
330 check_generated_ecc_key (gcry_sexp_t key)
331 {
332   gcry_sexp_t skey, pkey;
333
334   pkey = gcry_sexp_find_token (key, "public-key", 0);
335   if (!pkey)
336     fail ("public part missing in return value\n");
337   else
338     {
339       /* Fixme: Check more stuff.  */
340       gcry_sexp_release (pkey);
341     }
342
343   skey = gcry_sexp_find_token (key, "private-key", 0);
344   if (!skey)
345     fail ("private part missing in return value\n");
346   else
347     {
348       int rc = gcry_pk_testkey (skey);
349       if (rc)
350         fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
351       gcry_sexp_release (skey);
352     }
353
354   /* Finally check that gcry_pk_testkey also works on the entire
355      S-expression.  */
356   {
357     int rc = gcry_pk_testkey (key);
358     if (rc)
359       fail ("gcry_pk_testkey failed on key pair: %s\n", gpg_strerror (rc));
360   }
361 }
362
363
364 static void
365 check_ecc_keys (void)
366 {
367   const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256",
368                            "Ed25519", NULL };
369   int testno;
370   gcry_sexp_t keyparm, key;
371   int rc;
372
373   for (testno=0; curves[testno]; testno++)
374     {
375       if (verbose)
376         show ("creating ECC key using curve %s\n", curves[testno]);
377       if (!strcmp (curves[testno], "Ed25519"))
378         rc = gcry_sexp_build (&keyparm, NULL,
379                               "(genkey(ecc(curve %s)(flags eddsa)))",
380                               curves[testno]);
381       else
382         rc = gcry_sexp_build (&keyparm, NULL,
383                               "(genkey(ecc(curve %s)(flags )))",
384                               curves[testno]);
385       if (rc)
386         die ("error creating S-expression: %s\n", gpg_strerror (rc));
387       rc = gcry_pk_genkey (&key, keyparm);
388       gcry_sexp_release (keyparm);
389       if (rc)
390         die ("error generating ECC key using curve %s: %s\n",
391              curves[testno], gpg_strerror (rc));
392
393       if (verbose > 1)
394         show_sexp ("ECC key:\n", key);
395
396       if (!strcmp (curves[testno], "Ed25519"))
397         show_note ("note: gcry_pk_testkey does not yet work for Ed25519\n");
398       else
399         check_generated_ecc_key (key);
400
401       gcry_sexp_release (key);
402     }
403
404   if (verbose)
405     show ("creating ECC key using curve Ed25519 for ECDSA\n");
406   rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve Ed25519)))");
407   if (rc)
408     die ("error creating S-expression: %s\n", gpg_strerror (rc));
409   rc = gcry_pk_genkey (&key, keyparm);
410   gcry_sexp_release (keyparm);
411   if (rc)
412     die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
413          gpg_strerror (rc));
414
415   if (verbose > 1)
416     show_sexp ("ECC key:\n", key);
417
418   if (verbose)
419     show ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
420   rc = gcry_sexp_build (&keyparm, NULL,
421                         "(genkey(ecc(curve Ed25519)(flags nocomp)))");
422   if (rc)
423     die ("error creating S-expression: %s\n", gpg_strerror (rc));
424   rc = gcry_pk_genkey (&key, keyparm);
425   gcry_sexp_release (keyparm);
426   if (rc)
427     die ("error generating ECC key using curve Ed25519 for ECDSA"
428          " (nocomp): %s\n",
429          gpg_strerror (rc));
430
431   if (verbose > 1)
432     show_sexp ("ECC key:\n", key);
433
434   gcry_sexp_release (key);
435 }
436
437
438 static void
439 check_nonce (void)
440 {
441   char a[32], b[32];
442   int i,j;
443   int oops=0;
444
445   if (verbose)
446     show ("checking gcry_create_nonce\n");
447
448   gcry_create_nonce (a, sizeof a);
449   for (i=0; i < 10; i++)
450     {
451       gcry_create_nonce (b, sizeof b);
452       if (!memcmp (a, b, sizeof a))
453         die ("identical nonce found\n");
454     }
455   for (i=0; i < 10; i++)
456     {
457       gcry_create_nonce (a, sizeof a);
458       if (!memcmp (a, b, sizeof a))
459         die ("identical nonce found\n");
460     }
461
462  again:
463   for (i=1,j=0; i < sizeof a; i++)
464     if (a[0] == a[i])
465       j++;
466   if (j+1 == sizeof (a))
467     {
468       if (oops)
469         die ("impossible nonce found\n");
470       oops++;
471       gcry_create_nonce (a, sizeof a);
472       goto again;
473     }
474 }
475
476
477 static void
478 progress_cb (void *cb_data, const char *what, int printchar,
479                   int current, int total)
480 {
481   (void)cb_data;
482   (void)what;
483   (void)current;
484   (void)total;
485
486   if (printchar == '\n')
487     fputs ( "<LF>", stdout);
488   else
489     putchar (printchar);
490   fflush (stdout);
491 }
492
493
494 static void
495 usage (int mode)
496 {
497   fputs ("usage: " PGM " [options] [{rsa|elg|dsa|ecc|nonce}]\n"
498          "Options:\n"
499          "  --verbose       be verbose\n"
500          "  --debug         flyswatter\n"
501          "  --progress      print progress indicators\n",
502          mode? stderr : stdout);
503   if (mode)
504     exit (1);
505 }
506
507 int
508 main (int argc, char **argv)
509 {
510   int last_argc = -1;
511   int with_progress = 0;
512
513   if (argc)
514     { argc--; argv++; }
515
516   while (argc && last_argc != argc )
517     {
518       last_argc = argc;
519       if (!strcmp (*argv, "--"))
520         {
521           argc--; argv++;
522           break;
523         }
524       else if (!strcmp (*argv, "--help"))
525         {
526           usage (0);
527           exit (0);
528         }
529       else if (!strcmp (*argv, "--verbose"))
530         {
531           verbose++;
532           argc--; argv++;
533         }
534       else if (!strcmp (*argv, "--debug"))
535         {
536           verbose += 2;
537           debug++;
538           argc--; argv++;
539         }
540       else if (!strcmp (*argv, "--progress"))
541         {
542           argc--; argv++;
543           with_progress = 1;
544         }
545       else if (!strncmp (*argv, "--", 2))
546         die ("unknown option '%s'", *argv);
547       else
548         break;
549     }
550
551   if (!gcry_check_version (GCRYPT_VERSION))
552     die ("version mismatch\n");
553   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
554   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
555   if (debug)
556     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
557   /* No valuable keys are create, so we can speed up our RNG. */
558   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
559   if (with_progress)
560     gcry_set_progress_handler (progress_cb, NULL);
561
562   if (!argc)
563     {
564       check_rsa_keys ();
565       check_elg_keys ();
566       check_dsa_keys ();
567       check_ecc_keys ();
568       check_nonce ();
569     }
570   else
571     {
572       for (; argc; argc--, argv++)
573         if (!strcmp (*argv, "rsa"))
574           check_rsa_keys ();
575         else if (!strcmp (*argv, "elg"))
576           check_elg_keys ();
577         else if (!strcmp (*argv, "dsa"))
578           check_dsa_keys ();
579         else if (!strcmp (*argv, "ecc"))
580           check_ecc_keys ();
581         else if (!strcmp (*argv, "nonce"))
582           check_nonce ();
583         else
584           usage (1);
585     }
586
587   return error_count? 1:0;
588 }