Implement FIPS 186-2 key generation.
[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 static void
355 get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
356 {
357   gcry_sexp_t key_spec, key, pub_key, sec_key;
358   int rc;
359
360   rc = gcry_sexp_new 
361     (&key_spec, "(genkey (dsa (nbits 4:1024)))",  0, 1);
362   if (rc)
363     die ("error creating S-expression: %s\n", gcry_strerror (rc));
364   rc = gcry_pk_genkey (&key, key_spec);
365   gcry_sexp_release (key_spec);
366   if (rc)
367     die ("error generating DSA key: %s\n", gcry_strerror (rc));
368     
369   if (verbose > 1)
370     show_sexp ("generated DSA key:\n", key);
371
372   pub_key = gcry_sexp_find_token (key, "public-key", 0);
373   if (!pub_key)
374     die ("public part missing in key\n");
375
376   sec_key = gcry_sexp_find_token (key, "private-key", 0);
377   if (!sec_key)
378     die ("private part missing in key\n");
379
380   gcry_sexp_release (key);
381   *pkey = pub_key;
382   *skey = sec_key;
383 }
384
385
386 static void
387 get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
388 {
389   gcry_sexp_t key_spec, key, pub_key, sec_key;
390   int rc;
391
392   rc = gcry_sexp_new 
393     (&key_spec, "(genkey (dsa (nbits 4:1024)(use-fips186)))",  0, 1);
394   if (rc)
395     die ("error creating S-expression: %s\n", gcry_strerror (rc));
396   rc = gcry_pk_genkey (&key, key_spec);
397   gcry_sexp_release (key_spec);
398   if (rc)
399     die ("error generating DSA key: %s\n", gcry_strerror (rc));
400     
401   if (verbose > 1)
402     show_sexp ("generated DSA key (fips 186):\n", key);
403
404   pub_key = gcry_sexp_find_token (key, "public-key", 0);
405   if (!pub_key)
406     die ("public part missing in key\n");
407
408   sec_key = gcry_sexp_find_token (key, "private-key", 0);
409   if (!sec_key)
410     die ("private part missing in key\n");
411
412   gcry_sexp_release (key);
413   *pkey = pub_key;
414   *skey = sec_key;
415 }
416
417 static void
418 check_run (void)
419 {
420   gpg_error_t err;
421   gcry_sexp_t pkey, skey;
422   int variant;
423
424   for (variant=0; variant < 3; variant++)
425     {
426       if (verbose)
427         fprintf (stderr, "Checking sample key (%d).\n", variant);
428       get_keys_sample (&pkey, &skey, variant);
429       /* Check gcry_pk_testkey which requires all elements.  */
430       err = gcry_pk_testkey (skey);
431       if ((variant == 0 && err)
432           || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
433           die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
434       /* Run the usual check but expect an error from variant 2.  */
435       check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
436       gcry_sexp_release (pkey);
437       gcry_sexp_release (skey);
438     }
439
440   if (verbose)
441     fprintf (stderr, "Checking generated RSA key.\n");
442   get_keys_new (&pkey, &skey);
443   check_keys (pkey, skey, 800, 0);
444   gcry_sexp_release (pkey);
445   gcry_sexp_release (skey);
446
447   if (verbose)
448     fprintf (stderr, "Checking generated RSA key (X9.31).\n");
449   get_keys_x931_new (&pkey, &skey);
450   check_keys (pkey, skey, 800, 0);
451   gcry_sexp_release (pkey);
452   gcry_sexp_release (skey);
453
454   if (verbose)
455     fprintf (stderr, "Checking generated Elgamal key.\n");
456   get_elg_key_new (&pkey, &skey, 0);
457   check_keys (pkey, skey, 400, 0);
458   gcry_sexp_release (pkey);
459   gcry_sexp_release (skey);
460
461   if (verbose)
462     fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
463   get_elg_key_new (&pkey, &skey, 1);
464   check_keys (pkey, skey, 800, 0);
465   gcry_sexp_release (pkey);
466   gcry_sexp_release (skey);
467
468   if (verbose)
469     fprintf (stderr, "Generating DSA key.\n");
470   get_dsa_key_new (&pkey, &skey);
471   /* Fixme:  Add a check function for DSA keys.  */
472   gcry_sexp_release (pkey);
473   gcry_sexp_release (skey);
474
475   if (verbose)
476     fprintf (stderr, "Generating DSA key (FIPS 186).\n");
477   get_dsa_key_fips186_new (&pkey, &skey);
478   /* Fixme:  Add a check function for DSA keys.  */
479   gcry_sexp_release (pkey);
480   gcry_sexp_release (skey);
481 }
482
483
484
485 static gcry_mpi_t
486 key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
487 {
488   gcry_sexp_t l1, l2;
489   gcry_mpi_t result;
490
491   l1 = gcry_sexp_find_token (sexp, topname, 0);
492   if (!l1)
493     return NULL;
494
495   l2 = gcry_sexp_find_token (l1, name, 0);
496   if (!l2)
497     {
498       gcry_sexp_release (l1);
499       return NULL;
500     }
501
502   result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
503   gcry_sexp_release (l2);
504   gcry_sexp_release (l1);
505   return result;
506 }
507
508
509 static void
510 check_x931_derived_key (int what)
511 {
512   static struct {
513     const char *param;
514     const char *expected_d;
515   } testtable[] = {
516     { /* First example from X9.31 (D.1.1).  */
517       "(genkey\n"
518       "  (rsa\n"
519       "    (nbits 4:1024)\n"
520       "    (rsa-use-e 1:3)\n"
521       "    (derive-parms\n"
522       "      (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
523       "      (Xp2 #192E8AAC41C576C822D93EA433#)\n"
524       "      (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
525       "            769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
526       "            39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
527       "            B98BD984#)\n"
528       "      (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
529       "      (Xq2 #134E4CAA16D2350A21D775C404#)\n"
530       "      (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
531       "            7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
532       "            6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
533       "            321DE34A#))))\n",
534       "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
535       "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
536       "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
537       "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
538       "241D3C4B"
539     },
540     
541     { /* Second example from X9.31 (D.2.1).  */
542       "(genkey\n"
543       "  (rsa\n"
544       "    (nbits 4:1536)\n"
545       "    (rsa-use-e 1:3)\n"
546       "    (derive-parms\n"
547       "      (Xp1 #18272558B61316348297EACA74#)\n"
548       "      (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
549       "      (Xp  #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
550       "            0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
551       "            60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
552       "            318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
553       "            EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
554       "      (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
555       "      (Xq2 #18AB178ECA907D72472F65E480#)\n"
556       "      (Xq  #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
557       "            CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
558       "            B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
559       "            E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
560       "            EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
561       "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
562       "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
563       "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
564       "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
565       "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
566       "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
567       "BBCCB9F65C83"
568       /* Note that this example in X9.31 gives this value for D:
569
570         "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
571         "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
572         "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
573         "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
574         "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
575         "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
576         "EF32E7D9720B" 
577
578         This is a bug in X9.31, obviously introduced by using
579
580            d = e^{-1} mod (p-1)(q-1)
581           
582          instead of using the universal exponent as required by 4.1.3:
583
584            d = e^{-1} mod lcm(p-1,q-1)
585
586          The examples in X9.31 seem to be pretty buggy, see
587          cipher/primegen.c for another bug.  Not only that I had to
588          spend 100 USD for the 66 pages of the document, it also took
589          me several hours to figure out that the bugs are in the
590          document and not in my code.
591        */
592     },  
593
594     { /* First example from NIST RSAVS (B.1.1).  */
595       "(genkey\n"
596       "  (rsa\n"
597       "    (nbits 4:1024)\n"
598       "    (rsa-use-e 1:3)\n"
599       "    (derive-parms\n"
600       "      (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
601       "      (Xp2 #16e5457b8844967ce83cab8c11#)\n"
602       "      (Xp  #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
603       "            ab262da1dcda8194720672a4e02229a0c71f60ae\n"
604       "            c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
605       "            cab44595#)\n"
606       "      (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
607       "      (Xq2 #1f9cca85f185341516d92e82fd#)\n"
608       "      (Xq  #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
609       "            c225655a9310cceac9f4cf1bce653ec916d45788\n"
610       "            f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
611       "            2f389eda#))))\n",
612       "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
613       "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
614       "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
615       "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
616       "dc7e8feb"
617     },
618
619     { /* Second example from NIST RSAVS (B.1.1).  */
620       "(genkey\n"
621       "  (rsa\n"
622       "    (nbits 4:1536)\n"
623       "    (rsa-use-e 1:3)\n"
624       "    (derive-parms\n"
625       "      (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
626       "      (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
627       "      (Xp  #c8c67df894c882045ede26a9008ab09ea0672077\n"
628       "            d7bc71d412511cd93981ddde8f91b967da404056\n"
629       "            c39f105f7f239abdaff92923859920f6299e82b9\n"
630       "            5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
631       "            26974eb7bb1f14843841281b363b9cdb#)\n"
632       "      (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
633       "      (Xq2 #143edd7b22d828913abf24ca4d#)\n"
634       "      (Xq  #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
635       "            b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
636       "            7552195fae8b061077e03920814d8b9cfb5a3958\n"
637       "            b3a82c2a7fc97e55db543948d3396289245336ec\n"
638       "            9e3cb308cc655aebd766340da8921383#))))\n",
639       "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
640       "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
641       "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
642       "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
643       "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
644       "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
645       "2ccf8a84835b"
646     }
647   };
648   gpg_error_t err;
649   gcry_sexp_t key_spec, key, pub_key, sec_key;
650   gcry_mpi_t d_expected, d_have;
651
652   if (what < 0 && what >= sizeof testtable)
653     die ("invalid WHAT value\n");
654
655   err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
656   if (err)
657     die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
658
659   err = gcry_pk_genkey (&key, key_spec);
660   gcry_sexp_release (key_spec);
661   if (err)
662     die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
663     
664   pub_key = gcry_sexp_find_token (key, "public-key", 0);
665   if (!pub_key)
666     die ("public part missing in key [%d]\n", what);
667
668   sec_key = gcry_sexp_find_token (key, "private-key", 0);
669   if (!sec_key)
670     die ("private part missing in key [%d]\n", what);
671
672   err = gcry_mpi_scan 
673     (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
674   if (err)
675     die ("error converting string [%d]\n", what);
676
677   if (verbose > 1)
678     show_sexp ("generated key:\n", key);
679
680   d_have = key_param_from_sexp (sec_key, "rsa", "d");
681   if (!d_have)
682     die ("parameter d not found in RSA secret key [%d]\n", what);
683   if (gcry_mpi_cmp (d_expected, d_have))
684     {
685       show_sexp (NULL, sec_key);
686       die ("parameter d does match expected value [%d]\n", what); 
687     }
688   gcry_mpi_release (d_expected);
689   gcry_mpi_release (d_have);
690
691   gcry_sexp_release (key);
692   gcry_sexp_release (pub_key);
693   gcry_sexp_release (sec_key);
694 }
695
696
697
698
699 int
700 main (int argc, char **argv)
701 {
702   int debug = 0;
703   int i;
704
705   if (argc > 1 && !strcmp (argv[1], "--verbose"))
706     verbose = 1;
707   else if (argc > 1 && !strcmp (argv[1], "--debug"))
708     {
709       verbose = 2;
710       debug = 1;
711     }
712
713   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
714   if (!gcry_check_version (GCRYPT_VERSION))
715     die ("version mismatch\n");
716   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
717   if (debug)
718     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
719   /* No valuable keys are create, so we can speed up our RNG. */
720   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
721
722   for (i=0; i < 2; i++)
723     check_run ();
724
725   for (i=0; i < 4; i++)
726     check_x931_derived_key (i);
727   
728   return 0;
729 }