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