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