tests: Use common code for all tests.
[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 #define PGM "pubkey"
30 #include "t-common.h"
31
32
33 /* Sample RSA keys, taken from basic.c.  */
34
35 static const char sample_private_key_1[] =
36 "(private-key\n"
37 " (openpgp-rsa\n"
38 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
39       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
40       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
41       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
42 "  (e #010001#)\n"
43 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
44       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
45       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
46       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
47 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
48       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
49 "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
50       "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
51 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
52       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
53 " )\n"
54 ")\n";
55
56 /* The same key as above but without p, q and u to test the non CRT case. */
57 static const char sample_private_key_1_1[] =
58 "(private-key\n"
59 " (openpgp-rsa\n"
60 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
61       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
62       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
63       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
64 "  (e #010001#)\n"
65 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
66       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
67       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
68       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
69 " )\n"
70 ")\n";
71
72 /* The same key as above but just without q to test the non CRT case.  This
73    should fail. */
74 static const char sample_private_key_1_2[] =
75 "(private-key\n"
76 " (openpgp-rsa\n"
77 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
78       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
79       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
80       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
81 "  (e #010001#)\n"
82 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
83       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
84       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
85       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
86 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
87       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
88 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
89       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
90 " )\n"
91 ")\n";
92
93 static const char sample_public_key_1[] =
94 "(public-key\n"
95 " (rsa\n"
96 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
97       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
98       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
99       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
100 "  (e #010001#)\n"
101 " )\n"
102 ")\n";
103
104
105 static void
106 show_sexp (const char *prefix, gcry_sexp_t a)
107 {
108   char *buf;
109   size_t size;
110
111   if (prefix)
112     fputs (prefix, stderr);
113   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
114   buf = gcry_xmalloc (size);
115
116   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
117   fprintf (stderr, "%.*s", (int)size, buf);
118   gcry_free (buf);
119 }
120
121 /* from ../cipher/pubkey-util.c */
122 static gpg_err_code_t
123 _gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
124 {
125   char buf[50];
126   const char *s;
127   size_t n;
128
129   *r_nbits = 0;
130
131   list = gcry_sexp_find_token (list, "nbits", 0);
132   if (!list)
133     return 0; /* No NBITS found.  */
134
135   s = gcry_sexp_nth_data (list, 1, &n);
136   if (!s || n >= DIM (buf) - 1 )
137     {
138       /* NBITS given without a cdr.  */
139       gcry_sexp_release (list);
140       return GPG_ERR_INV_OBJ;
141     }
142   memcpy (buf, s, n);
143   buf[n] = 0;
144   *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
145   gcry_sexp_release (list);
146   return 0;
147 }
148
149 /* Convert STRING consisting of hex characters into its binary
150    representation and return it as an allocated buffer. The valid
151    length of the buffer is returned at R_LENGTH.  The string is
152    delimited by end of string.  The function returns NULL on
153    error.  */
154 static void *
155 data_from_hex (const char *string, size_t *r_length)
156 {
157   const char *s;
158   unsigned char *buffer;
159   size_t length;
160
161   buffer = gcry_xmalloc (strlen(string)/2+1);
162   length = 0;
163   for (s=string; *s; s +=2 )
164     {
165       if (!hexdigitp (s) || !hexdigitp (s+1))
166         die ("error parsing hex string `%s'\n", string);
167       ((unsigned char*)buffer)[length++] = xtoi_2 (s);
168     }
169   *r_length = length;
170   return buffer;
171 }
172
173
174 static void
175 extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
176 {
177   gcry_sexp_t l1;
178   const void *a;
179   size_t alen;
180   void *b;
181   size_t blen;
182
183   l1 = gcry_sexp_find_token (sexp, name, 0);
184   a = gcry_sexp_nth_data (l1, 1, &alen);
185   b = data_from_hex (expected, &blen);
186   if (!a)
187     fail ("parameter \"%s\" missing in key\n", name);
188   else if ( alen != blen || memcmp (a, b, alen) )
189     {
190       fail ("parameter \"%s\" does not match expected value\n", name);
191       if (verbose)
192         {
193           info ("expected: %s\n", expected);
194           show_sexp ("sexp: ", sexp);
195         }
196     }
197   gcry_free (b);
198   gcry_sexp_release (l1);
199 }
200
201
202 static void
203 check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
204                   gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
205 {
206   gcry_sexp_t plain1, cipher, l;
207   gcry_mpi_t x0, x1;
208   int rc;
209   int have_flags;
210
211   /* Extract data from plaintext.  */
212   l = gcry_sexp_find_token (plain0, "value", 0);
213   x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
214   gcry_sexp_release (l);
215
216   /* Encrypt data.  */
217   rc = gcry_pk_encrypt (&cipher, plain0, pkey);
218   if (rc)
219     die ("encryption failed: %s\n", gcry_strerror (rc));
220
221   l = gcry_sexp_find_token (cipher, "flags", 0);
222   have_flags = !!l;
223   gcry_sexp_release (l);
224
225   /* Decrypt data.  */
226   rc = gcry_pk_decrypt (&plain1, cipher, skey);
227   gcry_sexp_release (cipher);
228   if (rc)
229     {
230       if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
231         {
232           gcry_mpi_release (x0);
233           return; /* This is the expected failure code.  */
234         }
235       die ("decryption failed: %s\n", gcry_strerror (rc));
236     }
237
238   /* Extract decrypted data.  Note that for compatibility reasons, the
239      output of gcry_pk_decrypt depends on whether a flags lists (even
240      if empty) occurs in its input data.  Because we passed the output
241      of encrypt directly to decrypt, such a flag value won't be there
242      as of today.  We check it anyway. */
243   l = gcry_sexp_find_token (plain1, "value", 0);
244   if (l)
245     {
246       if (!have_flags)
247         die ("compatibility mode of pk_decrypt broken\n");
248       gcry_sexp_release (plain1);
249       x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
250       gcry_sexp_release (l);
251     }
252   else
253     {
254       if (have_flags)
255         die ("compatibility mode of pk_decrypt broken\n");
256       x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
257       gcry_sexp_release (plain1);
258     }
259
260   /* Compare.  */
261   if (gcry_mpi_cmp (x0, x1))
262     die ("data corrupted\n");
263   gcry_mpi_release (x0);
264   gcry_mpi_release (x1);
265 }
266
267 static void
268 check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
269             gpg_err_code_t decrypt_fail_code)
270 {
271   gcry_sexp_t plain;
272   gcry_mpi_t x;
273   int rc;
274
275   /* Create plain text.  */
276   x = gcry_mpi_new (nbits_data);
277   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
278
279   rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
280   if (rc)
281     die ("converting data for encryption failed: %s\n",
282          gcry_strerror (rc));
283
284   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
285   gcry_sexp_release (plain);
286   gcry_mpi_release (x);
287
288   /* Create plain text.  */
289   x = gcry_mpi_new (nbits_data);
290   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
291
292   rc = gcry_sexp_build (&plain, NULL,
293                         "(data (flags raw no-blinding) (value %m))", x);
294   gcry_mpi_release (x);
295   if (rc)
296     die ("converting data for encryption failed: %s\n",
297          gcry_strerror (rc));
298
299   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
300   gcry_sexp_release (plain);
301 }
302
303 static void
304 get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
305 {
306   gcry_sexp_t pub_key, sec_key;
307   int rc;
308   static const char *secret;
309
310
311   switch (secret_variant)
312     {
313     case 0: secret = sample_private_key_1; break;
314     case 1: secret = sample_private_key_1_1; break;
315     case 2: secret = sample_private_key_1_2; break;
316     default: die ("BUG\n");
317     }
318
319   rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
320                         strlen (sample_public_key_1));
321   if (!rc)
322     rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
323   if (rc)
324     die ("converting sample keys failed: %s\n", gcry_strerror (rc));
325
326   *pkey = pub_key;
327   *skey = sec_key;
328 }
329
330 static void
331 get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
332 {
333   gcry_sexp_t key_spec, key, pub_key, sec_key;
334   int rc;
335
336   rc = gcry_sexp_new (&key_spec,
337                       "(genkey (rsa (nbits 4:2048)))", 0, 1);
338   if (rc)
339     die ("error creating S-expression: %s\n", gcry_strerror (rc));
340   rc = gcry_pk_genkey (&key, key_spec);
341   gcry_sexp_release (key_spec);
342   if (rc)
343     die ("error generating RSA key: %s\n", gcry_strerror (rc));
344
345   if (verbose > 1)
346     show_sexp ("generated RSA key:\n", key);
347
348   pub_key = gcry_sexp_find_token (key, "public-key", 0);
349   if (! pub_key)
350     die ("public part missing in key\n");
351
352   sec_key = gcry_sexp_find_token (key, "private-key", 0);
353   if (! sec_key)
354     die ("private part missing in key\n");
355
356   gcry_sexp_release (key);
357   *pkey = pub_key;
358   *skey = sec_key;
359 }
360
361
362 static void
363 get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
364 {
365   gcry_sexp_t key_spec, key, pub_key, sec_key;
366   int rc;
367
368   rc = gcry_sexp_new (&key_spec,
369                       "(genkey (rsa (nbits 4:2048)(use-x931)))", 0, 1);
370   if (rc)
371     die ("error creating S-expression: %s\n", gcry_strerror (rc));
372   rc = gcry_pk_genkey (&key, key_spec);
373   gcry_sexp_release (key_spec);
374   if (rc)
375     die ("error generating RSA key: %s\n", gcry_strerror (rc));
376
377   if (verbose > 1)
378     show_sexp ("generated RSA (X9.31) key:\n", key);
379
380   pub_key = gcry_sexp_find_token (key, "public-key", 0);
381   if (!pub_key)
382     die ("public part missing in key\n");
383
384   sec_key = gcry_sexp_find_token (key, "private-key", 0);
385   if (!sec_key)
386     die ("private part missing in key\n");
387
388   gcry_sexp_release (key);
389   *pkey = pub_key;
390   *skey = sec_key;
391 }
392
393
394 static void
395 get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
396 {
397   gcry_sexp_t key_spec, key, pub_key, sec_key;
398   int rc;
399
400   rc = gcry_sexp_new
401     (&key_spec,
402      (fixed_x
403       ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
404       : "(genkey (elg (nbits 3:512)))"),
405      0, 1);
406
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 Elgamal key: %s\n", gcry_strerror (rc));
413
414   if (verbose > 1)
415     show_sexp ("generated ELG key:\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_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key)
433 {
434   gcry_sexp_t key_spec, key, pub_key, sec_key;
435   int rc;
436
437   rc = gcry_sexp_new (&key_spec,
438                       transient_key
439                       ? "(genkey (dsa (nbits 4:2048)(transient-key)))"
440                       : "(genkey (dsa (nbits 4:2048)))",
441                       0, 1);
442   if (rc)
443     die ("error creating S-expression: %s\n", gcry_strerror (rc));
444   rc = gcry_pk_genkey (&key, key_spec);
445   gcry_sexp_release (key_spec);
446   if (rc)
447     die ("error generating DSA key: %s\n", gcry_strerror (rc));
448
449   if (verbose > 1)
450     show_sexp ("generated DSA key:\n", key);
451
452   pub_key = gcry_sexp_find_token (key, "public-key", 0);
453   if (!pub_key)
454     die ("public part missing in key\n");
455
456   sec_key = gcry_sexp_find_token (key, "private-key", 0);
457   if (!sec_key)
458     die ("private part missing in key\n");
459
460   gcry_sexp_release (key);
461   *pkey = pub_key;
462   *skey = sec_key;
463 }
464
465
466 static void
467 get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
468 {
469   gcry_sexp_t key_spec, key, pub_key, sec_key;
470   int rc;
471
472   rc = gcry_sexp_new
473     (&key_spec, "(genkey (dsa (nbits 4:2048)(use-fips186)))",  0, 1);
474   if (rc)
475     die ("error creating S-expression: %s\n", gcry_strerror (rc));
476   rc = gcry_pk_genkey (&key, key_spec);
477   gcry_sexp_release (key_spec);
478   if (rc)
479     die ("error generating DSA key: %s\n", gcry_strerror (rc));
480
481   if (verbose > 1)
482     show_sexp ("generated DSA key (fips 186):\n", key);
483
484   pub_key = gcry_sexp_find_token (key, "public-key", 0);
485   if (!pub_key)
486     die ("public part missing in key\n");
487
488   sec_key = gcry_sexp_find_token (key, "private-key", 0);
489   if (!sec_key)
490     die ("private part missing in key\n");
491
492   gcry_sexp_release (key);
493   *pkey = pub_key;
494   *skey = sec_key;
495 }
496
497
498 static void
499 get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
500 {
501   gcry_sexp_t key_spec, key, pub_key, sec_key;
502   int rc;
503
504   rc = gcry_sexp_new
505     (&key_spec,
506      "(genkey (dsa (transient-key)(domain"
507      "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
508      "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
509      "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
510      "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
511      "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
512      "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
513      "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
514      "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
515      "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
516      ")))", 0, 1);
517   if (rc)
518     die ("error creating S-expression: %s\n", gcry_strerror (rc));
519   rc = gcry_pk_genkey (&key, key_spec);
520   gcry_sexp_release (key_spec);
521   if (rc)
522     die ("error generating DSA key: %s\n", gcry_strerror (rc));
523
524   if (verbose > 1)
525     show_sexp ("generated DSA key:\n", key);
526
527   pub_key = gcry_sexp_find_token (key, "public-key", 0);
528   if (!pub_key)
529     die ("public part missing in key\n");
530
531   sec_key = gcry_sexp_find_token (key, "private-key", 0);
532   if (!sec_key)
533     die ("private part missing in key\n");
534
535   gcry_sexp_release (key);
536   *pkey = pub_key;
537   *skey = sec_key;
538 }
539
540 #if 0
541 static void
542 get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
543 {
544   gcry_sexp_t key_spec, key, pub_key, sec_key;
545   int rc;
546
547   rc = gcry_sexp_new
548     (&key_spec,
549      "(genkey (dsa (transient-key)(use-fips186)(domain"
550      "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
551      "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
552      "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
553      "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
554      "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
555      "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
556      "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
557      "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
558      "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
559      ")))", 0, 1);
560   if (rc)
561     die ("error creating S-expression: %s\n", gcry_strerror (rc));
562   rc = gcry_pk_genkey (&key, key_spec);
563   gcry_sexp_release (key_spec);
564   if (rc)
565     die ("error generating DSA key: %s\n", gcry_strerror (rc));
566
567   if (verbose > 1)
568     show_sexp ("generated DSA key:\n", key);
569
570   pub_key = gcry_sexp_find_token (key, "public-key", 0);
571   if (!pub_key)
572     die ("public part missing in key\n");
573
574   sec_key = gcry_sexp_find_token (key, "private-key", 0);
575   if (!sec_key)
576     die ("private part missing in key\n");
577
578   gcry_sexp_release (key);
579   *pkey = pub_key;
580   *skey = sec_key;
581 }
582 #endif /*0*/
583
584 static void
585 get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
586 {
587   gcry_sexp_t key_spec, key, pub_key, sec_key;
588   int rc;
589
590   rc = gcry_sexp_new
591     (&key_spec,
592      "(genkey"
593      "  (dsa"
594      "    (nbits 4:2048)"
595      "    (use-fips186)"
596      "    (transient-key)"
597      "    (derive-parms"
598      "      (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))",
599      0, 1);
600   if (rc)
601     die ("error creating S-expression: %s\n", gcry_strerror (rc));
602   rc = gcry_pk_genkey (&key, key_spec);
603   gcry_sexp_release (key_spec);
604   if (rc)
605     die ("error generating DSA key: %s\n", gcry_strerror (rc));
606
607   if (verbose > 1)
608     show_sexp ("generated DSA key (fips 186 with seed):\n", key);
609
610   pub_key = gcry_sexp_find_token (key, "public-key", 0);
611   if (!pub_key)
612     die ("public part missing in key\n");
613
614   sec_key = gcry_sexp_find_token (key, "private-key", 0);
615   if (!sec_key)
616     die ("private part missing in key\n");
617
618   gcry_sexp_release (key);
619   *pkey = pub_key;
620   *skey = sec_key;
621 }
622
623
624 static void
625 check_run (void)
626 {
627   gpg_error_t err;
628   gcry_sexp_t pkey, skey;
629   int variant;
630
631   for (variant=0; variant < 3; variant++)
632     {
633       if (verbose)
634         fprintf (stderr, "Checking sample key (%d).\n", variant);
635       get_keys_sample (&pkey, &skey, variant);
636       /* Check gcry_pk_testkey which requires all elements.  */
637       err = gcry_pk_testkey (skey);
638       if ((variant == 0 && err)
639           || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
640           die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
641       /* Run the usual check but expect an error from variant 2.  */
642       check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
643       gcry_sexp_release (pkey);
644       gcry_sexp_release (skey);
645     }
646
647   if (verbose)
648     fprintf (stderr, "Checking generated RSA key.\n");
649   get_keys_new (&pkey, &skey);
650   check_keys (pkey, skey, 800, 0);
651   gcry_sexp_release (pkey);
652   gcry_sexp_release (skey);
653
654   if (verbose)
655     fprintf (stderr, "Checking generated RSA key (X9.31).\n");
656   get_keys_x931_new (&pkey, &skey);
657   check_keys (pkey, skey, 800, 0);
658   gcry_sexp_release (pkey);
659   gcry_sexp_release (skey);
660
661   if (verbose)
662     fprintf (stderr, "Checking generated Elgamal key.\n");
663   get_elg_key_new (&pkey, &skey, 0);
664   check_keys (pkey, skey, 400, 0);
665   gcry_sexp_release (pkey);
666   gcry_sexp_release (skey);
667
668   if (verbose)
669     fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
670   get_elg_key_new (&pkey, &skey, 1);
671   check_keys (pkey, skey, 800, 0);
672   gcry_sexp_release (pkey);
673   gcry_sexp_release (skey);
674
675   if (verbose)
676     fprintf (stderr, "Generating DSA key.\n");
677   get_dsa_key_new (&pkey, &skey, 0);
678   /* Fixme:  Add a check function for DSA keys.  */
679   gcry_sexp_release (pkey);
680   gcry_sexp_release (skey);
681
682   if (!gcry_fips_mode_active ())
683     {
684       if (verbose)
685         fprintf (stderr, "Generating transient DSA key.\n");
686       get_dsa_key_new (&pkey, &skey, 1);
687       /* Fixme:  Add a check function for DSA keys.  */
688       gcry_sexp_release (pkey);
689       gcry_sexp_release (skey);
690     }
691
692   if (verbose)
693     fprintf (stderr, "Generating DSA key (FIPS 186).\n");
694   get_dsa_key_fips186_new (&pkey, &skey);
695   /* Fixme:  Add a check function for DSA keys.  */
696   gcry_sexp_release (pkey);
697   gcry_sexp_release (skey);
698
699   if (verbose)
700     fprintf (stderr, "Generating DSA key with given domain.\n");
701   get_dsa_key_with_domain_new (&pkey, &skey);
702   /* Fixme:  Add a check function for DSA keys.  */
703   gcry_sexp_release (pkey);
704   gcry_sexp_release (skey);
705
706   /* We need new test vectors for get_dsa_key_fips186_with_domain_new.  */
707   if (verbose)
708     fprintf (stderr, "Generating DSA key with given domain (FIPS 186)"
709              " - skipped.\n");
710   /* get_dsa_key_fips186_with_domain_new (&pkey, &skey); */
711   /* /\* Fixme:  Add a check function for DSA keys.  *\/ */
712   /* gcry_sexp_release (pkey); */
713   /* gcry_sexp_release (skey); */
714
715   if (verbose)
716     fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n");
717   get_dsa_key_fips186_with_seed_new (&pkey, &skey);
718   /* Fixme:  Add a check function for DSA keys.  */
719   gcry_sexp_release (pkey);
720   gcry_sexp_release (skey);
721 }
722
723
724
725 static gcry_mpi_t
726 key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
727 {
728   gcry_sexp_t l1, l2;
729   gcry_mpi_t result;
730
731   l1 = gcry_sexp_find_token (sexp, topname, 0);
732   if (!l1)
733     return NULL;
734
735   l2 = gcry_sexp_find_token (l1, name, 0);
736   if (!l2)
737     {
738       gcry_sexp_release (l1);
739       return NULL;
740     }
741
742   result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
743   gcry_sexp_release (l2);
744   gcry_sexp_release (l1);
745   return result;
746 }
747
748
749 static void
750 check_x931_derived_key (int what)
751 {
752   static struct {
753     const char *param;
754     const char *expected_d;
755   } testtable[] = {
756     { /* First example from X9.31 (D.1.1).  */
757       "(genkey\n"
758       "  (rsa\n"
759       "    (nbits 4:1024)\n"
760       "    (rsa-use-e 1:3)\n"
761       "    (derive-parms\n"
762       "      (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
763       "      (Xp2 #192E8AAC41C576C822D93EA433#)\n"
764       "      (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
765       "            769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
766       "            39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
767       "            B98BD984#)\n"
768       "      (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
769       "      (Xq2 #134E4CAA16D2350A21D775C404#)\n"
770       "      (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
771       "            7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
772       "            6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
773       "            321DE34A#))))\n",
774       "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
775       "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
776       "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
777       "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
778       "241D3C4B"
779     },
780
781     { /* Second example from X9.31 (D.2.1).  */
782       "(genkey\n"
783       "  (rsa\n"
784       "    (nbits 4:1536)\n"
785       "    (rsa-use-e 1:3)\n"
786       "    (derive-parms\n"
787       "      (Xp1 #18272558B61316348297EACA74#)\n"
788       "      (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
789       "      (Xp  #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
790       "            0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
791       "            60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
792       "            318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
793       "            EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
794       "      (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
795       "      (Xq2 #18AB178ECA907D72472F65E480#)\n"
796       "      (Xq  #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
797       "            CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
798       "            B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
799       "            E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
800       "            EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
801       "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
802       "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
803       "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
804       "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
805       "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
806       "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
807       "BBCCB9F65C83"
808       /* Note that this example in X9.31 gives this value for D:
809
810         "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
811         "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
812         "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
813         "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
814         "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
815         "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
816         "EF32E7D9720B"
817
818         This is a bug in X9.31, obviously introduced by using
819
820            d = e^{-1} mod (p-1)(q-1)
821
822          instead of using the universal exponent as required by 4.1.3:
823
824            d = e^{-1} mod lcm(p-1,q-1)
825
826          The examples in X9.31 seem to be pretty buggy, see
827          cipher/primegen.c for another bug.  Not only that I had to
828          spend 100 USD for the 66 pages of the document, it also took
829          me several hours to figure out that the bugs are in the
830          document and not in my code.
831        */
832     },
833
834     { /* First example from NIST RSAVS (B.1.1).  */
835       "(genkey\n"
836       "  (rsa\n"
837       "    (nbits 4:1024)\n"
838       "    (rsa-use-e 1:3)\n"
839       "    (derive-parms\n"
840       "      (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
841       "      (Xp2 #16e5457b8844967ce83cab8c11#)\n"
842       "      (Xp  #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
843       "            ab262da1dcda8194720672a4e02229a0c71f60ae\n"
844       "            c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
845       "            cab44595#)\n"
846       "      (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
847       "      (Xq2 #1f9cca85f185341516d92e82fd#)\n"
848       "      (Xq  #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
849       "            c225655a9310cceac9f4cf1bce653ec916d45788\n"
850       "            f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
851       "            2f389eda#))))\n",
852       "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
853       "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
854       "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
855       "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
856       "dc7e8feb"
857     },
858
859     { /* Second example from NIST RSAVS (B.1.1).  */
860       "(genkey\n"
861       "  (rsa\n"
862       "    (nbits 4:1536)\n"
863       "    (rsa-use-e 1:3)\n"
864       "    (derive-parms\n"
865       "      (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
866       "      (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
867       "      (Xp  #c8c67df894c882045ede26a9008ab09ea0672077\n"
868       "            d7bc71d412511cd93981ddde8f91b967da404056\n"
869       "            c39f105f7f239abdaff92923859920f6299e82b9\n"
870       "            5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
871       "            26974eb7bb1f14843841281b363b9cdb#)\n"
872       "      (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
873       "      (Xq2 #143edd7b22d828913abf24ca4d#)\n"
874       "      (Xq  #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
875       "            b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
876       "            7552195fae8b061077e03920814d8b9cfb5a3958\n"
877       "            b3a82c2a7fc97e55db543948d3396289245336ec\n"
878       "            9e3cb308cc655aebd766340da8921383#))))\n",
879       "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
880       "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
881       "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
882       "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
883       "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
884       "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
885       "2ccf8a84835b"
886     }
887   };
888   gpg_error_t err;
889   gcry_sexp_t key_spec = NULL, key = NULL, pub_key = NULL, sec_key = NULL;
890   gcry_mpi_t d_expected = NULL, d_have = NULL;
891
892   if (what < 0 && what >= sizeof testtable)
893     die ("invalid WHAT value\n");
894
895   err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
896   if (err)
897     die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
898
899   {
900     unsigned nbits;
901     err = _gcry_pk_util_get_nbits(key_spec, &nbits);
902     if (err)
903       die ("nbits not found\n");
904     if (gcry_fips_mode_active() && nbits < 2048)
905       {
906         info("RSA key test with %d bits skipped in fips mode\n", nbits);
907         goto leave;
908       }
909   }
910
911   err = gcry_pk_genkey (&key, key_spec);
912   gcry_sexp_release (key_spec);
913   if (err)
914     {
915       fail ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
916       goto leave;
917     }
918
919   pub_key = gcry_sexp_find_token (key, "public-key", 0);
920   if (!pub_key)
921     die ("public part missing in key [%d]\n", what);
922
923   sec_key = gcry_sexp_find_token (key, "private-key", 0);
924   if (!sec_key)
925     die ("private part missing in key [%d]\n", what);
926
927   err = gcry_mpi_scan
928     (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
929   if (err)
930     die ("error converting string [%d]\n", what);
931
932   if (verbose > 1)
933     show_sexp ("generated key:\n", key);
934
935   d_have = key_param_from_sexp (sec_key, "rsa", "d");
936   if (!d_have)
937     die ("parameter d not found in RSA secret key [%d]\n", what);
938   if (gcry_mpi_cmp (d_expected, d_have))
939     {
940       show_sexp (NULL, sec_key);
941       die ("parameter d does match expected value [%d]\n", what);
942     }
943 leave:
944   gcry_mpi_release (d_expected);
945   gcry_mpi_release (d_have);
946
947   gcry_sexp_release (key);
948   gcry_sexp_release (pub_key);
949   gcry_sexp_release (sec_key);
950 }
951
952
953
954 static void
955 check_ecc_sample_key (void)
956 {
957   static const char ecc_private_key[] =
958     "(private-key\n"
959     " (ecdsa\n"
960     "  (curve \"NIST P-256\")\n"
961     "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
962     "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n"
963     "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
964     "))";
965   static const char ecc_private_key_wo_q[] =
966     "(private-key\n"
967     " (ecdsa\n"
968     "  (curve \"NIST P-256\")\n"
969     "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
970     "))";
971   static const char ecc_public_key[] =
972     "(public-key\n"
973     " (ecdsa\n"
974     "  (curve \"NIST P-256\")\n"
975     "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
976     "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)"
977     "))";
978   static const char hash_string[] =
979     "(data (flags raw)\n"
980     " (value #00112233445566778899AABBCCDDEEFF"
981     /* */    "000102030405060708090A0B0C0D0E0F#))";
982   static const char hash2_string[] =
983     "(data (flags raw)\n"
984     " (hash sha1 #00112233445566778899AABBCCDDEEFF"
985     /* */    "000102030405060708090A0B0C0D0E0F"
986     /* */    "000102030405060708090A0B0C0D0E0F"
987     /* */    "00112233445566778899AABBCCDDEEFF#))";
988   /* hash2, but longer than curve length, so it will be truncated */
989   static const char hash3_string[] =
990     "(data (flags raw)\n"
991     " (hash sha1 #00112233445566778899AABBCCDDEEFF"
992     /* */    "000102030405060708090A0B0C0D0E0F"
993     /* */    "000102030405060708090A0B0C0D0E0F"
994     /* */    "00112233445566778899AABBCCDDEEFF"
995     /* */    "000102030405060708090A0B0C0D0E0F#))";
996
997   gpg_error_t err;
998   gcry_sexp_t key, hash, hash2, hash3, sig, sig2;
999
1000   if (verbose)
1001     fprintf (stderr, "Checking sample ECC key.\n");
1002
1003   if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
1004     die ("line %d: %s", __LINE__, gpg_strerror (err));
1005
1006   if ((err = gcry_sexp_new (&hash2, hash2_string, 0, 1)))
1007     die ("line %d: %s", __LINE__, gpg_strerror (err));
1008
1009   if ((err = gcry_sexp_new (&hash3, hash3_string, 0, 1)))
1010     die ("line %d: %s", __LINE__, gpg_strerror (err));
1011
1012   if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
1013     die ("line %d: %s", __LINE__, gpg_strerror (err));
1014
1015   if ((err = gcry_pk_sign (&sig, hash, key)))
1016     die ("gcry_pk_sign failed: %s", gpg_strerror (err));
1017
1018   gcry_sexp_release (key);
1019   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1020     die ("line %d: %s", __LINE__, gpg_strerror (err));
1021
1022   if ((err = gcry_pk_verify (sig, hash, key)))
1023     die ("gcry_pk_verify failed: %s", gpg_strerror (err));
1024
1025   /* Verify hash truncation */
1026   gcry_sexp_release (key);
1027   if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
1028     die ("line %d: %s", __LINE__, gpg_strerror (err));
1029
1030   if ((err = gcry_pk_sign (&sig2, hash2, key)))
1031     die ("gcry_pk_sign failed: %s", gpg_strerror (err));
1032
1033   gcry_sexp_release (sig);
1034   if ((err = gcry_pk_sign (&sig, hash3, key)))
1035     die ("gcry_pk_sign failed: %s", gpg_strerror (err));
1036
1037   gcry_sexp_release (key);
1038   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1039     die ("line %d: %s", __LINE__, gpg_strerror (err));
1040
1041   if ((err = gcry_pk_verify (sig, hash2, key)))
1042     die ("gcry_pk_verify failed: %s", gpg_strerror (err));
1043
1044   if ((err = gcry_pk_verify (sig2, hash3, key)))
1045     die ("gcry_pk_verify failed: %s", gpg_strerror (err));
1046
1047   /* Now try signing without the Q parameter.  */
1048
1049   gcry_sexp_release (key);
1050   if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
1051     die ("line %d: %s", __LINE__, gpg_strerror (err));
1052
1053   gcry_sexp_release (sig);
1054   if ((err = gcry_pk_sign (&sig, hash, key)))
1055     die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err));
1056
1057   gcry_sexp_release (key);
1058   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1059     die ("line %d: %s", __LINE__, gpg_strerror (err));
1060
1061   if ((err = gcry_pk_verify (sig, hash, key)))
1062     die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err));
1063
1064   gcry_sexp_release (sig);
1065   gcry_sexp_release (sig2);
1066   gcry_sexp_release (key);
1067   gcry_sexp_release (hash);
1068   gcry_sexp_release (hash2);
1069   gcry_sexp_release (hash3);
1070 }
1071
1072
1073 static void
1074 check_ed25519ecdsa_sample_key (void)
1075 {
1076   static const char ecc_private_key[] =
1077     "(private-key\n"
1078     " (ecc\n"
1079     "  (curve \"Ed25519\")\n"
1080     "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
1081     "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
1082     "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
1083     "))";
1084   static const char ecc_private_key_wo_q[] =
1085     "(private-key\n"
1086     " (ecc\n"
1087     "  (curve \"Ed25519\")\n"
1088     "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
1089     "))";
1090   static const char ecc_public_key[] =
1091     "(public-key\n"
1092     " (ecc\n"
1093     "  (curve \"Ed25519\")\n"
1094     "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
1095     "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
1096     "))";
1097   static const char ecc_public_key_comp[] =
1098     "(public-key\n"
1099     " (ecc\n"
1100     "  (curve \"Ed25519\")\n"
1101     "  (q #047b57c2c1d3ded93332b52d588dd45863478b658387413a718779c0dd1a6d95#)"
1102     "))";
1103   static const char hash_string[] =
1104     "(data (flags rfc6979)\n"
1105     " (hash sha256 #00112233445566778899AABBCCDDEEFF"
1106     /* */          "000102030405060708090A0B0C0D0E0F#))";
1107
1108   gpg_error_t err;
1109   gcry_sexp_t key, hash, sig;
1110
1111   if (verbose)
1112     fprintf (stderr, "Checking sample Ed25519/ECDSA key.\n");
1113
1114   /* Sign.  */
1115   if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
1116     die ("line %d: %s", __LINE__, gpg_strerror (err));
1117   if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
1118     die ("line %d: %s", __LINE__, gpg_strerror (err));
1119   if ((err = gcry_pk_sign (&sig, hash, key)))
1120     die ("gcry_pk_sign failed: %s", gpg_strerror (err));
1121
1122   /* Verify.  */
1123   gcry_sexp_release (key);
1124   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1125     die ("line %d: %s", __LINE__, gpg_strerror (err));
1126   if ((err = gcry_pk_verify (sig, hash, key)))
1127     die ("gcry_pk_verify failed: %s", gpg_strerror (err));
1128
1129   /* Verify again using a compressed public key.  */
1130   gcry_sexp_release (key);
1131   if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
1132     die ("line %d: %s", __LINE__, gpg_strerror (err));
1133   if ((err = gcry_pk_verify (sig, hash, key)))
1134     die ("gcry_pk_verify failed (comp): %s", gpg_strerror (err));
1135
1136   /* Sign without a Q parameter.  */
1137   gcry_sexp_release (key);
1138   if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
1139     die ("line %d: %s", __LINE__, gpg_strerror (err));
1140   gcry_sexp_release (sig);
1141   if ((err = gcry_pk_sign (&sig, hash, key)))
1142     die ("gcry_pk_sign w/o Q failed: %s", gpg_strerror (err));
1143
1144   /* Verify.  */
1145   gcry_sexp_release (key);
1146   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1147     die ("line %d: %s", __LINE__, gpg_strerror (err));
1148   if ((err = gcry_pk_verify (sig, hash, key)))
1149     die ("gcry_pk_verify signed w/o Q failed: %s", gpg_strerror (err));
1150
1151   /* Verify again using a compressed public key.  */
1152   gcry_sexp_release (key);
1153   if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
1154     die ("line %d: %s", __LINE__, gpg_strerror (err));
1155   if ((err = gcry_pk_verify (sig, hash, key)))
1156     die ("gcry_pk_verify signed w/o Q failed (comp): %s", gpg_strerror (err));
1157
1158   extract_cmp_data (sig, "r", ("a63123a783ef29b8276e08987daca4"
1159                                "655d0179e22199bf63691fd88eb64e15"));
1160   extract_cmp_data (sig, "s", ("0d9b45c696ab90b96b08812b485df185"
1161                                "623ddaf5d02fa65ca5056cb6bd0f16f1"));
1162
1163   gcry_sexp_release (sig);
1164   gcry_sexp_release (key);
1165   gcry_sexp_release (hash);
1166 }
1167
1168
1169 int
1170 main (int argc, char **argv)
1171 {
1172   int i;
1173
1174   if (argc > 1 && !strcmp (argv[1], "--verbose"))
1175     verbose = 1;
1176   else if (argc > 1 && !strcmp (argv[1], "--debug"))
1177     {
1178       verbose = 2;
1179       debug = 1;
1180     }
1181
1182   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1183   if (!gcry_check_version (GCRYPT_VERSION))
1184     die ("version mismatch\n");
1185   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1186   if (debug)
1187     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
1188   /* No valuable keys are create, so we can speed up our RNG. */
1189   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1190
1191   for (i=0; i < 2; i++)
1192     check_run ();
1193
1194   for (i=0; i < 4; i++)
1195     check_x931_derived_key (i);
1196
1197   check_ecc_sample_key ();
1198   if (!gcry_fips_mode_active ())
1199     check_ed25519ecdsa_sample_key ();
1200
1201   return !!error_count;
1202 }