ecc: Add flags "noparam" and "comp".
[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       rc = gcry_sexp_build (&keyparm, NULL,
378                             "(genkey(ecc(curve %s)(flags noparam)))",
379                             curves[testno]);
380       if (rc)
381         die ("error creating S-expression: %s\n", gpg_strerror (rc));
382       rc = gcry_pk_genkey (&key, keyparm);
383       gcry_sexp_release (keyparm);
384       if (rc)
385         die ("error generating ECC key using curve %s: %s\n",
386              curves[testno], gpg_strerror (rc));
387
388       if (verbose > 1)
389         show_sexp ("ECC key:\n", key);
390
391       if (!strcmp (curves[testno], "Ed25519"))
392         show_note ("note: gcry_pk_testkey does not yet work for Ed25519\n");
393       else
394         check_generated_ecc_key (key);
395
396       gcry_sexp_release (key);
397     }
398
399   if (verbose)
400     show ("creating ECC key using curve Ed25519 for ECDSA\n");
401   rc = gcry_sexp_build (&keyparm, NULL,
402                         "(genkey(ecc(curve Ed25519)(flags ecdsa)))");
403   if (rc)
404     die ("error creating S-expression: %s\n", gpg_strerror (rc));
405   rc = gcry_pk_genkey (&key, keyparm);
406   gcry_sexp_release (keyparm);
407   if (rc)
408     die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
409          gpg_strerror (rc));
410
411   if (verbose > 1)
412     show_sexp ("ECC key:\n", key);
413
414   if (verbose)
415     show ("creating ECC key using curve Ed25519 for ECDSA\n");
416   rc = gcry_sexp_build (&keyparm, NULL,
417                         "(genkey(ecc(curve Ed25519)(flags noparam ecdsa)))");
418   if (rc)
419     die ("error creating S-expression: %s\n", gpg_strerror (rc));
420   rc = gcry_pk_genkey (&key, keyparm);
421   gcry_sexp_release (keyparm);
422   if (rc)
423     die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
424          gpg_strerror (rc));
425
426   if (verbose > 1)
427     show_sexp ("ECC key:\n", key);
428
429   gcry_sexp_release (key);
430 }
431
432
433 static void
434 check_nonce (void)
435 {
436   char a[32], b[32];
437   int i,j;
438   int oops=0;
439
440   if (verbose)
441     show ("checking gcry_create_nonce\n");
442
443   gcry_create_nonce (a, sizeof a);
444   for (i=0; i < 10; i++)
445     {
446       gcry_create_nonce (b, sizeof b);
447       if (!memcmp (a, b, sizeof a))
448         die ("identical nonce found\n");
449     }
450   for (i=0; i < 10; i++)
451     {
452       gcry_create_nonce (a, sizeof a);
453       if (!memcmp (a, b, sizeof a))
454         die ("identical nonce found\n");
455     }
456
457  again:
458   for (i=1,j=0; i < sizeof a; i++)
459     if (a[0] == a[i])
460       j++;
461   if (j+1 == sizeof (a))
462     {
463       if (oops)
464         die ("impossible nonce found\n");
465       oops++;
466       gcry_create_nonce (a, sizeof a);
467       goto again;
468     }
469 }
470
471
472 static void
473 progress_cb (void *cb_data, const char *what, int printchar,
474                   int current, int total)
475 {
476   (void)cb_data;
477   (void)what;
478   (void)current;
479   (void)total;
480
481   if (printchar == '\n')
482     fputs ( "<LF>", stdout);
483   else
484     putchar (printchar);
485   fflush (stdout);
486 }
487
488
489 static void
490 usage (int mode)
491 {
492   fputs ("usage: " PGM " [options] [{rsa|elg|dsa|ecc|nonce}]\n"
493          "Options:\n"
494          "  --verbose       be verbose\n"
495          "  --debug         flyswatter\n"
496          "  --progress      print progress indicators\n",
497          mode? stderr : stdout);
498   if (mode)
499     exit (1);
500 }
501
502 int
503 main (int argc, char **argv)
504 {
505   int last_argc = -1;
506   int with_progress = 0;
507
508   if (argc)
509     { argc--; argv++; }
510
511   while (argc && last_argc != argc )
512     {
513       last_argc = argc;
514       if (!strcmp (*argv, "--"))
515         {
516           argc--; argv++;
517           break;
518         }
519       else if (!strcmp (*argv, "--help"))
520         {
521           usage (0);
522           exit (0);
523         }
524       else if (!strcmp (*argv, "--verbose"))
525         {
526           verbose++;
527           argc--; argv++;
528         }
529       else if (!strcmp (*argv, "--debug"))
530         {
531           verbose += 2;
532           debug++;
533           argc--; argv++;
534         }
535       else if (!strcmp (*argv, "--progress"))
536         {
537           argc--; argv++;
538           with_progress = 1;
539         }
540       else if (!strncmp (*argv, "--", 2))
541         die ("unknown option '%s'", *argv);
542       else
543         break;
544     }
545
546   if (!gcry_check_version (GCRYPT_VERSION))
547     die ("version mismatch\n");
548   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
549   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
550   if (debug)
551     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
552   /* No valuable keys are create, so we can speed up our RNG. */
553   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
554   if (with_progress)
555     gcry_set_progress_handler (progress_cb, NULL);
556
557   if (!argc)
558     {
559       check_rsa_keys ();
560       check_elg_keys ();
561       check_dsa_keys ();
562       check_ecc_keys ();
563       check_nonce ();
564     }
565   else
566     {
567       for (; argc; argc--, argv++)
568         if (!strcmp (*argv, "rsa"))
569           check_rsa_keys ();
570         else if (!strcmp (*argv, "elg"))
571           check_elg_keys ();
572         else if (!strcmp (*argv, "dsa"))
573           check_dsa_keys ();
574         else if (!strcmp (*argv, "ecc"))
575           check_ecc_keys ();
576         else if (!strcmp (*argv, "nonce"))
577           check_nonce ();
578         else
579           usage (1);
580     }
581
582   return error_count? 1:0;
583 }