Fix for dsa signature verifciation in fipsdrv.
[libgcrypt.git] / tests / pubkey.c
1 /* pubkey.c - Public key encryption/decryption tests
2  *      Copyright (C) 2001, 2002, 2003, 2005 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28
29 #include "../src/gcrypt.h"
30
31 /* Sample RSA keys, taken from basic.c.  */
32
33 static const char sample_private_key_1[] =
34 "(private-key\n"
35 " (openpgp-rsa\n"
36 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
37       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
38       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
39       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
40 "  (e #010001#)\n"
41 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
42       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
43       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
44       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
45 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
46       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
47 "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
48       "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
49 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
50       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
51 " )\n"
52 ")\n";
53
54 /* The same key as above but without p, q and u to test the non CRT case. */
55 static const char sample_private_key_1_1[] =
56 "(private-key\n"
57 " (openpgp-rsa\n"
58 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
59       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
60       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
61       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
62 "  (e #010001#)\n"
63 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
64       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
65       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
66       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
67 " )\n"
68 ")\n";
69
70 /* The same key as above but just without q to test the non CRT case.  This
71    should fail. */
72 static const char sample_private_key_1_2[] =
73 "(private-key\n"
74 " (openpgp-rsa\n"
75 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
76       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
77       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
78       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
79 "  (e #010001#)\n"
80 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
81       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
82       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
83       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
84 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
85       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
86 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
87       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
88 " )\n"
89 ")\n";
90
91 static const char sample_public_key_1[] =
92 "(public-key\n"
93 " (rsa\n"
94 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
95       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
96       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
97       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
98 "  (e #010001#)\n"
99 " )\n"
100 ")\n";
101
102
103 static int verbose;
104
105 static void
106 die (const char *format, ...)
107 {
108   va_list arg_ptr ;
109
110   va_start( arg_ptr, format ) ;
111   vfprintf (stderr, format, arg_ptr );
112   va_end(arg_ptr);
113   exit (1);
114 }
115
116 static void
117 show_sexp (const char *prefix, gcry_sexp_t a)
118 {
119   char *buf;
120   size_t size;
121
122   if (prefix)
123     fputs (prefix, stderr);
124   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
125   buf = gcry_xmalloc (size);
126
127   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
128   fprintf (stderr, "%.*s", (int)size, buf);
129   gcry_free (buf);
130 }
131
132
133 static void
134 check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
135                   gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
136 {
137   gcry_sexp_t plain1, cipher, l;
138   gcry_mpi_t x0, x1;
139   int rc;
140   int have_flags;
141
142   /* Extract data from plaintext.  */
143   l = gcry_sexp_find_token (plain0, "value", 0);
144   x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
145
146   /* Encrypt data.  */
147   rc = gcry_pk_encrypt (&cipher, plain0, pkey);
148   if (rc)
149     die ("encryption failed: %s\n", gcry_strerror (rc));
150
151   l = gcry_sexp_find_token (cipher, "flags", 0);
152   have_flags = !!l;
153   gcry_sexp_release (l);
154
155   /* Decrypt data.  */
156   rc = gcry_pk_decrypt (&plain1, cipher, skey);
157   gcry_sexp_release (cipher);
158   if (rc)
159     {
160       if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
161         return; /* This is the expected failure code.  */
162       die ("decryption failed: %s\n", gcry_strerror (rc));
163     }
164
165   /* Extract decrypted data.  Note that for compatibility reasons, the
166      output of gcry_pk_decrypt depends on whether a flags lists (even
167      if empty) occurs in its input data.  Because we passed the output
168      of encrypt directly to decrypt, such a flag value won't be there
169      as of today.  We check it anyway. */
170   l = gcry_sexp_find_token (plain1, "value", 0);
171   if (l)
172     {
173       if (!have_flags)
174         die ("compatibility mode of pk_decrypt broken\n");
175       gcry_sexp_release (plain1);
176       x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
177       gcry_sexp_release (l);
178     }
179   else
180     {
181       if (have_flags)
182         die ("compatibility mode of pk_decrypt broken\n");
183       x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
184       gcry_sexp_release (plain1);
185     }
186
187   /* Compare.  */
188   if (gcry_mpi_cmp (x0, x1))
189     die ("data corrupted\n");
190 }
191
192 static void
193 check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
194             gpg_err_code_t decrypt_fail_code)
195 {
196   gcry_sexp_t plain;
197   gcry_mpi_t x;
198   int rc;
199   
200   /* Create plain text.  */
201   x = gcry_mpi_new (nbits_data);
202   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
203   
204   rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
205   if (rc)
206     die ("converting data for encryption failed: %s\n",
207          gcry_strerror (rc));
208
209   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
210   gcry_sexp_release (plain);
211   gcry_mpi_release (x);
212
213   /* Create plain text.  */
214   x = gcry_mpi_new (nbits_data);
215   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
216   
217   rc = gcry_sexp_build (&plain, NULL, 
218                         "(data (flags raw no-blinding) (value %m))", x);
219   if (rc)
220     die ("converting data for encryption failed: %s\n",
221          gcry_strerror (rc));
222
223   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
224   gcry_sexp_release (plain);
225 }
226
227 static void
228 get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
229 {
230   gcry_sexp_t pub_key, sec_key;
231   int rc;
232   static const char *secret;
233
234
235   switch (secret_variant)
236     {
237     case 0: secret = sample_private_key_1; break;
238     case 1: secret = sample_private_key_1_1; break;
239     case 2: secret = sample_private_key_1_2; break;
240     default: die ("BUG\n");
241     }
242
243   rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
244                         strlen (sample_public_key_1));
245   if (!rc)
246     rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
247   if (rc)
248     die ("converting sample keys failed: %s\n", gcry_strerror (rc));
249
250   *pkey = pub_key;
251   *skey = sec_key;
252 }
253
254 static void
255 get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
256 {
257   gcry_sexp_t key_spec, key, pub_key, sec_key;
258   int rc;
259   
260   rc = gcry_sexp_new (&key_spec,
261                       "(genkey (rsa (nbits 4:1024)))", 0, 1);
262   if (rc)
263     die ("error creating S-expression: %s\n", gcry_strerror (rc));
264   rc = gcry_pk_genkey (&key, key_spec);
265   gcry_sexp_release (key_spec);
266   if (rc)
267     die ("error generating RSA key: %s\n", gcry_strerror (rc));
268     
269   if (verbose > 1)
270     show_sexp ("generated RSA key:\n", key);
271
272   pub_key = gcry_sexp_find_token (key, "public-key", 0);
273   if (! pub_key)
274     die ("public part missing in key\n");
275
276   sec_key = gcry_sexp_find_token (key, "private-key", 0);
277   if (! sec_key)
278     die ("private part missing in key\n");
279
280   gcry_sexp_release (key);
281   *pkey = pub_key;
282   *skey = sec_key;
283 }
284
285
286 static void
287 get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
288 {
289   gcry_sexp_t key_spec, key, pub_key, sec_key;
290   int rc;
291   
292   rc = gcry_sexp_new (&key_spec,
293                       "(genkey (rsa (nbits 4:1024)(use-x931)))", 0, 1);
294   if (rc)
295     die ("error creating S-expression: %s\n", gcry_strerror (rc));
296   rc = gcry_pk_genkey (&key, key_spec);
297   gcry_sexp_release (key_spec);
298   if (rc)
299     die ("error generating RSA key: %s\n", gcry_strerror (rc));
300     
301   if (verbose > 1)
302     show_sexp ("generated RSA (X9.31) key:\n", key);
303
304   pub_key = gcry_sexp_find_token (key, "public-key", 0);
305   if (!pub_key)
306     die ("public part missing in key\n");
307
308   sec_key = gcry_sexp_find_token (key, "private-key", 0);
309   if (!sec_key)
310     die ("private part missing in key\n");
311
312   gcry_sexp_release (key);
313   *pkey = pub_key;
314   *skey = sec_key;
315 }
316
317
318 static void
319 get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
320 {
321   gcry_sexp_t key_spec, key, pub_key, sec_key;
322   int rc;
323
324   rc = gcry_sexp_new 
325     (&key_spec, 
326      (fixed_x
327       ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
328       : "(genkey (elg (nbits 3:512)))"),
329      0, 1);
330
331   if (rc)
332     die ("error creating S-expression: %s\n", gcry_strerror (rc));
333   rc = gcry_pk_genkey (&key, key_spec);
334   gcry_sexp_release (key_spec);
335   if (rc)
336     die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
337     
338   if (verbose > 1)
339     show_sexp ("generated ELG key:\n", key);
340
341   pub_key = gcry_sexp_find_token (key, "public-key", 0);
342   if (!pub_key)
343     die ("public part missing in key\n");
344
345   sec_key = gcry_sexp_find_token (key, "private-key", 0);
346   if (!sec_key)
347     die ("private part missing in key\n");
348
349   gcry_sexp_release (key);
350   *pkey = pub_key;
351   *skey = sec_key;
352 }
353
354
355 static void
356 get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key)
357 {
358   gcry_sexp_t key_spec, key, pub_key, sec_key;
359   int rc;
360
361   rc = gcry_sexp_new (&key_spec, 
362                       transient_key
363                       ? "(genkey (dsa (nbits 4:1024)(transient-key)))"
364                       : "(genkey (dsa (nbits 4:1024)))",
365                       0, 1);
366   if (rc)
367     die ("error creating S-expression: %s\n", gcry_strerror (rc));
368   rc = gcry_pk_genkey (&key, key_spec);
369   gcry_sexp_release (key_spec);
370   if (rc)
371     die ("error generating DSA key: %s\n", gcry_strerror (rc));
372     
373   if (verbose > 1)
374     show_sexp ("generated DSA key:\n", key);
375
376   pub_key = gcry_sexp_find_token (key, "public-key", 0);
377   if (!pub_key)
378     die ("public part missing in key\n");
379
380   sec_key = gcry_sexp_find_token (key, "private-key", 0);
381   if (!sec_key)
382     die ("private part missing in key\n");
383
384   gcry_sexp_release (key);
385   *pkey = pub_key;
386   *skey = sec_key;
387 }
388
389
390 static void
391 get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
392 {
393   gcry_sexp_t key_spec, key, pub_key, sec_key;
394   int rc;
395
396   rc = gcry_sexp_new 
397     (&key_spec, "(genkey (dsa (nbits 4:1024)(use-fips186)))",  0, 1);
398   if (rc)
399     die ("error creating S-expression: %s\n", gcry_strerror (rc));
400   rc = gcry_pk_genkey (&key, key_spec);
401   gcry_sexp_release (key_spec);
402   if (rc)
403     die ("error generating DSA key: %s\n", gcry_strerror (rc));
404     
405   if (verbose > 1)
406     show_sexp ("generated DSA key (fips 186):\n", key);
407
408   pub_key = gcry_sexp_find_token (key, "public-key", 0);
409   if (!pub_key)
410     die ("public part missing in key\n");
411
412   sec_key = gcry_sexp_find_token (key, "private-key", 0);
413   if (!sec_key)
414     die ("private part missing in key\n");
415
416   gcry_sexp_release (key);
417   *pkey = pub_key;
418   *skey = sec_key;
419 }
420
421
422 static void
423 get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
424 {
425   gcry_sexp_t key_spec, key, pub_key, sec_key;
426   int rc;
427
428   rc = gcry_sexp_new 
429     (&key_spec, 
430      "(genkey (dsa (transient-key)(domain"
431      "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
432      "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
433      "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
434      "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
435      "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
436      "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
437      "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
438      "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
439      "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
440      ")))", 0, 1);
441   if (rc)
442     die ("error creating S-expression: %s\n", gcry_strerror (rc));
443   rc = gcry_pk_genkey (&key, key_spec);
444   gcry_sexp_release (key_spec);
445   if (rc)
446     die ("error generating DSA key: %s\n", gcry_strerror (rc));
447     
448   if (verbose > 1)
449     show_sexp ("generated DSA key:\n", key);
450
451   pub_key = gcry_sexp_find_token (key, "public-key", 0);
452   if (!pub_key)
453     die ("public part missing in key\n");
454
455   sec_key = gcry_sexp_find_token (key, "private-key", 0);
456   if (!sec_key)
457     die ("private part missing in key\n");
458
459   gcry_sexp_release (key);
460   *pkey = pub_key;
461   *skey = sec_key;
462 }
463
464 static void
465 get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
466 {
467   gcry_sexp_t key_spec, key, pub_key, sec_key;
468   int rc;
469
470   rc = gcry_sexp_new 
471     (&key_spec, 
472      "(genkey (dsa (transient-key)(use-fips186)(domain"
473      "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
474      "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
475      "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
476      "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
477      "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
478      "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
479      "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
480      "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
481      "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
482      ")))", 0, 1);
483   if (rc)
484     die ("error creating S-expression: %s\n", gcry_strerror (rc));
485   rc = gcry_pk_genkey (&key, key_spec);
486   gcry_sexp_release (key_spec);
487   if (rc)
488     die ("error generating DSA key: %s\n", gcry_strerror (rc));
489     
490   if (verbose > 1)
491     show_sexp ("generated DSA key:\n", key);
492
493   pub_key = gcry_sexp_find_token (key, "public-key", 0);
494   if (!pub_key)
495     die ("public part missing in key\n");
496
497   sec_key = gcry_sexp_find_token (key, "private-key", 0);
498   if (!sec_key)
499     die ("private part missing in key\n");
500
501   gcry_sexp_release (key);
502   *pkey = pub_key;
503   *skey = sec_key;
504 }
505
506
507 static void
508 get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
509 {
510   gcry_sexp_t key_spec, key, pub_key, sec_key;
511   int rc;
512
513   rc = gcry_sexp_new 
514     (&key_spec,
515      "(genkey"
516      "  (dsa" 
517      "    (nbits 4:1024)"
518      "    (use-fips186)"
519      "    (transient-key)"
520      "    (derive-parms"
521      "      (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))",
522      0, 1);
523   if (rc)
524     die ("error creating S-expression: %s\n", gcry_strerror (rc));
525   rc = gcry_pk_genkey (&key, key_spec);
526   gcry_sexp_release (key_spec);
527   if (rc)
528     die ("error generating DSA key: %s\n", gcry_strerror (rc));
529     
530   if (verbose > 1 || 1)
531     show_sexp ("generated DSA key (fips 186 with seed):\n", key);
532
533   pub_key = gcry_sexp_find_token (key, "public-key", 0);
534   if (!pub_key)
535     die ("public part missing in key\n");
536
537   sec_key = gcry_sexp_find_token (key, "private-key", 0);
538   if (!sec_key)
539     die ("private part missing in key\n");
540
541   gcry_sexp_release (key);
542   *pkey = pub_key;
543   *skey = sec_key;
544 }
545
546
547 static void
548 check_run (void)
549 {
550   gpg_error_t err;
551   gcry_sexp_t pkey, skey;
552   int variant;
553
554   for (variant=0; variant < 3; variant++)
555     {
556       if (verbose)
557         fprintf (stderr, "Checking sample key (%d).\n", variant);
558       get_keys_sample (&pkey, &skey, variant);
559       /* Check gcry_pk_testkey which requires all elements.  */
560       err = gcry_pk_testkey (skey);
561       if ((variant == 0 && err)
562           || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
563           die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
564       /* Run the usual check but expect an error from variant 2.  */
565       check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
566       gcry_sexp_release (pkey);
567       gcry_sexp_release (skey);
568     }
569
570   if (verbose)
571     fprintf (stderr, "Checking generated RSA key.\n");
572   get_keys_new (&pkey, &skey);
573   check_keys (pkey, skey, 800, 0);
574   gcry_sexp_release (pkey);
575   gcry_sexp_release (skey);
576
577   if (verbose)
578     fprintf (stderr, "Checking generated RSA key (X9.31).\n");
579   get_keys_x931_new (&pkey, &skey);
580   check_keys (pkey, skey, 800, 0);
581   gcry_sexp_release (pkey);
582   gcry_sexp_release (skey);
583
584   if (verbose)
585     fprintf (stderr, "Checking generated Elgamal key.\n");
586   get_elg_key_new (&pkey, &skey, 0);
587   check_keys (pkey, skey, 400, 0);
588   gcry_sexp_release (pkey);
589   gcry_sexp_release (skey);
590
591   if (verbose)
592     fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
593   get_elg_key_new (&pkey, &skey, 1);
594   check_keys (pkey, skey, 800, 0);
595   gcry_sexp_release (pkey);
596   gcry_sexp_release (skey);
597
598   if (verbose)
599     fprintf (stderr, "Generating DSA key.\n");
600   get_dsa_key_new (&pkey, &skey, 0);
601   /* Fixme:  Add a check function for DSA keys.  */
602   gcry_sexp_release (pkey);
603   gcry_sexp_release (skey);
604
605   if (!gcry_fips_mode_active ())
606     {
607       if (verbose)
608         fprintf (stderr, "Generating transient DSA key.\n");
609       get_dsa_key_new (&pkey, &skey, 1);
610       /* Fixme:  Add a check function for DSA keys.  */
611       gcry_sexp_release (pkey);
612       gcry_sexp_release (skey);
613     }
614
615   if (verbose)
616     fprintf (stderr, "Generating DSA key (FIPS 186).\n");
617   get_dsa_key_fips186_new (&pkey, &skey);
618   /* Fixme:  Add a check function for DSA keys.  */
619   gcry_sexp_release (pkey);
620   gcry_sexp_release (skey);
621
622   if (verbose)
623     fprintf (stderr, "Generating DSA key with given domain.\n");
624   get_dsa_key_with_domain_new (&pkey, &skey);
625   /* Fixme:  Add a check function for DSA keys.  */
626   gcry_sexp_release (pkey);
627   gcry_sexp_release (skey);
628
629   if (verbose)
630     fprintf (stderr, "Generating DSA key with given domain (FIPS 186).\n");
631   get_dsa_key_fips186_with_domain_new (&pkey, &skey);
632   /* Fixme:  Add a check function for DSA keys.  */
633   gcry_sexp_release (pkey);
634   gcry_sexp_release (skey);
635
636   if (verbose)
637     fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n");
638   get_dsa_key_fips186_with_seed_new (&pkey, &skey);
639   /* Fixme:  Add a check function for DSA keys.  */
640   gcry_sexp_release (pkey);
641   gcry_sexp_release (skey);
642 }
643
644
645
646 static gcry_mpi_t
647 key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
648 {
649   gcry_sexp_t l1, l2;
650   gcry_mpi_t result;
651
652   l1 = gcry_sexp_find_token (sexp, topname, 0);
653   if (!l1)
654     return NULL;
655
656   l2 = gcry_sexp_find_token (l1, name, 0);
657   if (!l2)
658     {
659       gcry_sexp_release (l1);
660       return NULL;
661     }
662
663   result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
664   gcry_sexp_release (l2);
665   gcry_sexp_release (l1);
666   return result;
667 }
668
669
670 static void
671 check_x931_derived_key (int what)
672 {
673   static struct {
674     const char *param;
675     const char *expected_d;
676   } testtable[] = {
677     { /* First example from X9.31 (D.1.1).  */
678       "(genkey\n"
679       "  (rsa\n"
680       "    (nbits 4:1024)\n"
681       "    (rsa-use-e 1:3)\n"
682       "    (derive-parms\n"
683       "      (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
684       "      (Xp2 #192E8AAC41C576C822D93EA433#)\n"
685       "      (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
686       "            769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
687       "            39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
688       "            B98BD984#)\n"
689       "      (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
690       "      (Xq2 #134E4CAA16D2350A21D775C404#)\n"
691       "      (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
692       "            7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
693       "            6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
694       "            321DE34A#))))\n",
695       "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
696       "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
697       "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
698       "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
699       "241D3C4B"
700     },
701     
702     { /* Second example from X9.31 (D.2.1).  */
703       "(genkey\n"
704       "  (rsa\n"
705       "    (nbits 4:1536)\n"
706       "    (rsa-use-e 1:3)\n"
707       "    (derive-parms\n"
708       "      (Xp1 #18272558B61316348297EACA74#)\n"
709       "      (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
710       "      (Xp  #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
711       "            0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
712       "            60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
713       "            318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
714       "            EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
715       "      (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
716       "      (Xq2 #18AB178ECA907D72472F65E480#)\n"
717       "      (Xq  #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
718       "            CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
719       "            B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
720       "            E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
721       "            EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
722       "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
723       "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
724       "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
725       "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
726       "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
727       "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
728       "BBCCB9F65C83"
729       /* Note that this example in X9.31 gives this value for D:
730
731         "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
732         "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
733         "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
734         "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
735         "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
736         "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
737         "EF32E7D9720B" 
738
739         This is a bug in X9.31, obviously introduced by using
740
741            d = e^{-1} mod (p-1)(q-1)
742           
743          instead of using the universal exponent as required by 4.1.3:
744
745            d = e^{-1} mod lcm(p-1,q-1)
746
747          The examples in X9.31 seem to be pretty buggy, see
748          cipher/primegen.c for another bug.  Not only that I had to
749          spend 100 USD for the 66 pages of the document, it also took
750          me several hours to figure out that the bugs are in the
751          document and not in my code.
752        */
753     },  
754
755     { /* First example from NIST RSAVS (B.1.1).  */
756       "(genkey\n"
757       "  (rsa\n"
758       "    (nbits 4:1024)\n"
759       "    (rsa-use-e 1:3)\n"
760       "    (derive-parms\n"
761       "      (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
762       "      (Xp2 #16e5457b8844967ce83cab8c11#)\n"
763       "      (Xp  #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
764       "            ab262da1dcda8194720672a4e02229a0c71f60ae\n"
765       "            c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
766       "            cab44595#)\n"
767       "      (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
768       "      (Xq2 #1f9cca85f185341516d92e82fd#)\n"
769       "      (Xq  #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
770       "            c225655a9310cceac9f4cf1bce653ec916d45788\n"
771       "            f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
772       "            2f389eda#))))\n",
773       "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
774       "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
775       "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
776       "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
777       "dc7e8feb"
778     },
779
780     { /* Second example from NIST RSAVS (B.1.1).  */
781       "(genkey\n"
782       "  (rsa\n"
783       "    (nbits 4:1536)\n"
784       "    (rsa-use-e 1:3)\n"
785       "    (derive-parms\n"
786       "      (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
787       "      (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
788       "      (Xp  #c8c67df894c882045ede26a9008ab09ea0672077\n"
789       "            d7bc71d412511cd93981ddde8f91b967da404056\n"
790       "            c39f105f7f239abdaff92923859920f6299e82b9\n"
791       "            5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
792       "            26974eb7bb1f14843841281b363b9cdb#)\n"
793       "      (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
794       "      (Xq2 #143edd7b22d828913abf24ca4d#)\n"
795       "      (Xq  #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
796       "            b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
797       "            7552195fae8b061077e03920814d8b9cfb5a3958\n"
798       "            b3a82c2a7fc97e55db543948d3396289245336ec\n"
799       "            9e3cb308cc655aebd766340da8921383#))))\n",
800       "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
801       "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
802       "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
803       "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
804       "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
805       "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
806       "2ccf8a84835b"
807     }
808   };
809   gpg_error_t err;
810   gcry_sexp_t key_spec, key, pub_key, sec_key;
811   gcry_mpi_t d_expected, d_have;
812
813   if (what < 0 && what >= sizeof testtable)
814     die ("invalid WHAT value\n");
815
816   err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
817   if (err)
818     die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
819
820   err = gcry_pk_genkey (&key, key_spec);
821   gcry_sexp_release (key_spec);
822   if (err)
823     die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
824     
825   pub_key = gcry_sexp_find_token (key, "public-key", 0);
826   if (!pub_key)
827     die ("public part missing in key [%d]\n", what);
828
829   sec_key = gcry_sexp_find_token (key, "private-key", 0);
830   if (!sec_key)
831     die ("private part missing in key [%d]\n", what);
832
833   err = gcry_mpi_scan 
834     (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
835   if (err)
836     die ("error converting string [%d]\n", what);
837
838   if (verbose > 1)
839     show_sexp ("generated key:\n", key);
840
841   d_have = key_param_from_sexp (sec_key, "rsa", "d");
842   if (!d_have)
843     die ("parameter d not found in RSA secret key [%d]\n", what);
844   if (gcry_mpi_cmp (d_expected, d_have))
845     {
846       show_sexp (NULL, sec_key);
847       die ("parameter d does match expected value [%d]\n", what); 
848     }
849   gcry_mpi_release (d_expected);
850   gcry_mpi_release (d_have);
851
852   gcry_sexp_release (key);
853   gcry_sexp_release (pub_key);
854   gcry_sexp_release (sec_key);
855 }
856
857
858
859
860 int
861 main (int argc, char **argv)
862 {
863   int debug = 0;
864   int i;
865
866   if (argc > 1 && !strcmp (argv[1], "--verbose"))
867     verbose = 1;
868   else if (argc > 1 && !strcmp (argv[1], "--debug"))
869     {
870       verbose = 2;
871       debug = 1;
872     }
873
874   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
875   if (!gcry_check_version (GCRYPT_VERSION))
876     die ("version mismatch\n");
877   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
878   if (debug)
879     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
880   /* No valuable keys are create, so we can speed up our RNG. */
881   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
882
883   for (i=0; i < 2; i++)
884     check_run ();
885
886   for (i=0; i < 4; i++)
887     check_x931_derived_key (i);
888   
889   return 0;
890 }