Allow speicification of domain parameters for DSA 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
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 check_run (void)
509 {
510   gpg_error_t err;
511   gcry_sexp_t pkey, skey;
512   int variant;
513
514   for (variant=0; variant < 3; variant++)
515     {
516       if (verbose)
517         fprintf (stderr, "Checking sample key (%d).\n", variant);
518       get_keys_sample (&pkey, &skey, variant);
519       /* Check gcry_pk_testkey which requires all elements.  */
520       err = gcry_pk_testkey (skey);
521       if ((variant == 0 && err)
522           || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
523           die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
524       /* Run the usual check but expect an error from variant 2.  */
525       check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
526       gcry_sexp_release (pkey);
527       gcry_sexp_release (skey);
528     }
529
530   if (verbose)
531     fprintf (stderr, "Checking generated RSA key.\n");
532   get_keys_new (&pkey, &skey);
533   check_keys (pkey, skey, 800, 0);
534   gcry_sexp_release (pkey);
535   gcry_sexp_release (skey);
536
537   if (verbose)
538     fprintf (stderr, "Checking generated RSA key (X9.31).\n");
539   get_keys_x931_new (&pkey, &skey);
540   check_keys (pkey, skey, 800, 0);
541   gcry_sexp_release (pkey);
542   gcry_sexp_release (skey);
543
544   if (verbose)
545     fprintf (stderr, "Checking generated Elgamal key.\n");
546   get_elg_key_new (&pkey, &skey, 0);
547   check_keys (pkey, skey, 400, 0);
548   gcry_sexp_release (pkey);
549   gcry_sexp_release (skey);
550
551   if (verbose)
552     fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
553   get_elg_key_new (&pkey, &skey, 1);
554   check_keys (pkey, skey, 800, 0);
555   gcry_sexp_release (pkey);
556   gcry_sexp_release (skey);
557
558   if (verbose)
559     fprintf (stderr, "Generating DSA key.\n");
560   get_dsa_key_new (&pkey, &skey, 0);
561   /* Fixme:  Add a check function for DSA keys.  */
562   gcry_sexp_release (pkey);
563   gcry_sexp_release (skey);
564
565   if (!gcry_fips_mode_active ())
566     {
567       if (verbose)
568         fprintf (stderr, "Generating transient DSA key.\n");
569       get_dsa_key_new (&pkey, &skey, 1);
570       /* Fixme:  Add a check function for DSA keys.  */
571       gcry_sexp_release (pkey);
572       gcry_sexp_release (skey);
573     }
574
575   if (verbose)
576     fprintf (stderr, "Generating DSA key (FIPS 186).\n");
577   get_dsa_key_fips186_new (&pkey, &skey);
578   /* Fixme:  Add a check function for DSA keys.  */
579   gcry_sexp_release (pkey);
580   gcry_sexp_release (skey);
581
582   if (verbose)
583     fprintf (stderr, "Generating DSA key with given domain.\n");
584   get_dsa_key_with_domain_new (&pkey, &skey);
585   /* Fixme:  Add a check function for DSA keys.  */
586   gcry_sexp_release (pkey);
587   gcry_sexp_release (skey);
588
589   if (verbose)
590     fprintf (stderr, "Generating DSA key with given domain (FIPS 186).\n");
591   get_dsa_key_fips186_with_domain_new (&pkey, &skey);
592   /* Fixme:  Add a check function for DSA keys.  */
593   gcry_sexp_release (pkey);
594   gcry_sexp_release (skey);
595 }
596
597
598
599 static gcry_mpi_t
600 key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
601 {
602   gcry_sexp_t l1, l2;
603   gcry_mpi_t result;
604
605   l1 = gcry_sexp_find_token (sexp, topname, 0);
606   if (!l1)
607     return NULL;
608
609   l2 = gcry_sexp_find_token (l1, name, 0);
610   if (!l2)
611     {
612       gcry_sexp_release (l1);
613       return NULL;
614     }
615
616   result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
617   gcry_sexp_release (l2);
618   gcry_sexp_release (l1);
619   return result;
620 }
621
622
623 static void
624 check_x931_derived_key (int what)
625 {
626   static struct {
627     const char *param;
628     const char *expected_d;
629   } testtable[] = {
630     { /* First example from X9.31 (D.1.1).  */
631       "(genkey\n"
632       "  (rsa\n"
633       "    (nbits 4:1024)\n"
634       "    (rsa-use-e 1:3)\n"
635       "    (derive-parms\n"
636       "      (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
637       "      (Xp2 #192E8AAC41C576C822D93EA433#)\n"
638       "      (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
639       "            769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
640       "            39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
641       "            B98BD984#)\n"
642       "      (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
643       "      (Xq2 #134E4CAA16D2350A21D775C404#)\n"
644       "      (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
645       "            7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
646       "            6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
647       "            321DE34A#))))\n",
648       "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
649       "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
650       "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
651       "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
652       "241D3C4B"
653     },
654     
655     { /* Second example from X9.31 (D.2.1).  */
656       "(genkey\n"
657       "  (rsa\n"
658       "    (nbits 4:1536)\n"
659       "    (rsa-use-e 1:3)\n"
660       "    (derive-parms\n"
661       "      (Xp1 #18272558B61316348297EACA74#)\n"
662       "      (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
663       "      (Xp  #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
664       "            0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
665       "            60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
666       "            318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
667       "            EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
668       "      (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
669       "      (Xq2 #18AB178ECA907D72472F65E480#)\n"
670       "      (Xq  #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
671       "            CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
672       "            B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
673       "            E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
674       "            EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
675       "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
676       "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
677       "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
678       "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
679       "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
680       "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
681       "BBCCB9F65C83"
682       /* Note that this example in X9.31 gives this value for D:
683
684         "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
685         "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
686         "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
687         "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
688         "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
689         "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
690         "EF32E7D9720B" 
691
692         This is a bug in X9.31, obviously introduced by using
693
694            d = e^{-1} mod (p-1)(q-1)
695           
696          instead of using the universal exponent as required by 4.1.3:
697
698            d = e^{-1} mod lcm(p-1,q-1)
699
700          The examples in X9.31 seem to be pretty buggy, see
701          cipher/primegen.c for another bug.  Not only that I had to
702          spend 100 USD for the 66 pages of the document, it also took
703          me several hours to figure out that the bugs are in the
704          document and not in my code.
705        */
706     },  
707
708     { /* First example from NIST RSAVS (B.1.1).  */
709       "(genkey\n"
710       "  (rsa\n"
711       "    (nbits 4:1024)\n"
712       "    (rsa-use-e 1:3)\n"
713       "    (derive-parms\n"
714       "      (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
715       "      (Xp2 #16e5457b8844967ce83cab8c11#)\n"
716       "      (Xp  #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
717       "            ab262da1dcda8194720672a4e02229a0c71f60ae\n"
718       "            c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
719       "            cab44595#)\n"
720       "      (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
721       "      (Xq2 #1f9cca85f185341516d92e82fd#)\n"
722       "      (Xq  #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
723       "            c225655a9310cceac9f4cf1bce653ec916d45788\n"
724       "            f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
725       "            2f389eda#))))\n",
726       "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
727       "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
728       "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
729       "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
730       "dc7e8feb"
731     },
732
733     { /* Second example from NIST RSAVS (B.1.1).  */
734       "(genkey\n"
735       "  (rsa\n"
736       "    (nbits 4:1536)\n"
737       "    (rsa-use-e 1:3)\n"
738       "    (derive-parms\n"
739       "      (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
740       "      (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
741       "      (Xp  #c8c67df894c882045ede26a9008ab09ea0672077\n"
742       "            d7bc71d412511cd93981ddde8f91b967da404056\n"
743       "            c39f105f7f239abdaff92923859920f6299e82b9\n"
744       "            5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
745       "            26974eb7bb1f14843841281b363b9cdb#)\n"
746       "      (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
747       "      (Xq2 #143edd7b22d828913abf24ca4d#)\n"
748       "      (Xq  #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
749       "            b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
750       "            7552195fae8b061077e03920814d8b9cfb5a3958\n"
751       "            b3a82c2a7fc97e55db543948d3396289245336ec\n"
752       "            9e3cb308cc655aebd766340da8921383#))))\n",
753       "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
754       "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
755       "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
756       "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
757       "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
758       "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
759       "2ccf8a84835b"
760     }
761   };
762   gpg_error_t err;
763   gcry_sexp_t key_spec, key, pub_key, sec_key;
764   gcry_mpi_t d_expected, d_have;
765
766   if (what < 0 && what >= sizeof testtable)
767     die ("invalid WHAT value\n");
768
769   err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
770   if (err)
771     die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
772
773   err = gcry_pk_genkey (&key, key_spec);
774   gcry_sexp_release (key_spec);
775   if (err)
776     die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
777     
778   pub_key = gcry_sexp_find_token (key, "public-key", 0);
779   if (!pub_key)
780     die ("public part missing in key [%d]\n", what);
781
782   sec_key = gcry_sexp_find_token (key, "private-key", 0);
783   if (!sec_key)
784     die ("private part missing in key [%d]\n", what);
785
786   err = gcry_mpi_scan 
787     (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
788   if (err)
789     die ("error converting string [%d]\n", what);
790
791   if (verbose > 1)
792     show_sexp ("generated key:\n", key);
793
794   d_have = key_param_from_sexp (sec_key, "rsa", "d");
795   if (!d_have)
796     die ("parameter d not found in RSA secret key [%d]\n", what);
797   if (gcry_mpi_cmp (d_expected, d_have))
798     {
799       show_sexp (NULL, sec_key);
800       die ("parameter d does match expected value [%d]\n", what); 
801     }
802   gcry_mpi_release (d_expected);
803   gcry_mpi_release (d_have);
804
805   gcry_sexp_release (key);
806   gcry_sexp_release (pub_key);
807   gcry_sexp_release (sec_key);
808 }
809
810
811
812
813 int
814 main (int argc, char **argv)
815 {
816   int debug = 0;
817   int i;
818
819   if (argc > 1 && !strcmp (argv[1], "--verbose"))
820     verbose = 1;
821   else if (argc > 1 && !strcmp (argv[1], "--debug"))
822     {
823       verbose = 2;
824       debug = 1;
825     }
826
827   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
828   if (!gcry_check_version (GCRYPT_VERSION))
829     die ("version mismatch\n");
830   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
831   if (debug)
832     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
833   /* No valuable keys are create, so we can speed up our RNG. */
834   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
835
836   for (i=0; i < 2; i++)
837     check_run ();
838
839   for (i=0; i < 4; i++)
840     check_x931_derived_key (i);
841   
842   return 0;
843 }