ChangeLog:
[libgcrypt.git] / tests / basic.c
1 /* basic.c  -  basic regression 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28
29 #include "../src/gcrypt.h"
30
31 typedef struct test_spec_pubkey_key
32 {
33   const char *secret;
34   const char *public;
35   const char *grip;
36 }
37 test_spec_pubkey_key_t;
38
39 typedef struct test_spec_pubkey
40 {
41   int id;
42   int flags;
43   test_spec_pubkey_key_t key;
44 }
45 test_spec_pubkey_t;
46
47 #define FLAG_CRYPT (1 << 0)
48 #define FLAG_SIGN  (1 << 1)
49 #define FLAG_GRIP  (1 << 2)
50
51 static int verbose;
52 static int error_count;
53
54 static void
55 fail (const char *format, ...)
56 {
57   va_list arg_ptr;
58
59   va_start (arg_ptr, format);
60   vfprintf (stderr, format, arg_ptr);
61   va_end (arg_ptr);
62   error_count++;
63 }
64
65 static void
66 die (const char *format, ...)
67 {
68   va_list arg_ptr;
69
70   va_start (arg_ptr, format);
71   vfprintf (stderr, format, arg_ptr);
72   va_end (arg_ptr);
73   exit (1);
74 }
75
76 #define MAX_DATA_LEN 100
77
78 void
79 progress_handler (void *cb_data, const char *what, int printchar,
80                   int current, int total)
81 {
82   putchar (printchar);
83 }
84
85 static void
86 check_cbc_mac_cipher (void)
87 {
88   struct tv
89   {
90     int algo;
91     char key[MAX_DATA_LEN];
92     char plaintext[MAX_DATA_LEN];
93     size_t plaintextlen;
94     char mac[MAX_DATA_LEN];
95   }
96   tv[] =
97     {
98       { GCRY_CIPHER_AES,
99         "chicken teriyaki",
100         "This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
101         0, "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" },
102       { GCRY_CIPHER_3DES,
103         "abcdefghABCDEFGH01234567",
104         "This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
105         0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" },
106       { GCRY_CIPHER_DES,
107         "abcdefgh",
108         "This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
109         0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" }
110     };
111   gcry_cipher_hd_t hd;
112   char out[MAX_DATA_LEN];
113   int i, blklen, keylen;
114   gcry_error_t err = 0;
115
116   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
117     {
118       err = gcry_cipher_open (&hd,
119                               tv[i].algo,
120                               GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
121       if (!hd)
122         {
123           fail ("cbc-mac algo %d, grcy_open_cipher failed: %s\n",
124                 tv[i].algo, gpg_strerror (err));
125           return;
126         }
127
128       blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
129       if (!blklen)
130         {
131           fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n",
132                  tv[i].algo);
133           gcry_cipher_close (hd);
134           return;
135         }
136
137       keylen = gcry_cipher_get_algo_keylen (tv[i].algo);
138       if (!keylen)
139         {
140           fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n",
141                 tv[i].algo);
142           return;
143         }
144
145       err = gcry_cipher_setkey (hd, tv[i].key, keylen);
146       if (err)
147         {
148           fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n",
149                 tv[i].algo, gpg_strerror (err));
150           gcry_cipher_close (hd);
151           return;
152         }
153
154       err = gcry_cipher_setiv (hd, NULL, 0);
155       if (err)
156         {
157           fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n",
158                 tv[i].algo, gpg_strerror (err));
159           gcry_cipher_close (hd);
160           return;
161         }
162
163       err = gcry_cipher_encrypt (hd,
164                                  out, blklen,
165                                  tv[i].plaintext,
166                                  tv[i].plaintextlen ?
167                                  tv[i].plaintextlen :
168                                  strlen (tv[i].plaintext));
169       if (err)
170         {
171           fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n",
172                 tv[i].algo, gpg_strerror (err));
173           gcry_cipher_close (hd);
174           return;
175         }
176
177 #if 0
178       {
179         int j;
180         for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++)
181           printf ("\\x%02x", out[j] & 0xFF);
182         printf ("\n");
183       }
184 #endif
185
186       if (memcmp (tv[i].mac, out, blklen))
187         fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i);
188
189       gcry_cipher_close (hd);
190     }
191 }
192
193 static void
194 check_aes128_cbc_cts_cipher (void)
195 {
196   char key[128 / 8] = "chicken teriyaki";
197   char plaintext[] =
198     "I would like the General Gau's Chicken, please, and wonton soup.";
199   struct tv
200   {
201     char out[MAX_DATA_LEN];
202     int inlen;
203   } tv[] =
204     {
205       { "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
206         "\x97",
207         17 },
208       { "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
209         "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5",
210         31 },
211       { "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
212         "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
213         32 },
214       { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
215         "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
216         "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5",
217         47 },
218       { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
219         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
220         "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
221         48 },
222       { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
223         "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
224         "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
225         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
226         64 },
227     };
228   gcry_cipher_hd_t hd;
229   char out[MAX_DATA_LEN];
230   int i;
231   gcry_error_t err = 0;
232
233   err = gcry_cipher_open (&hd,
234                           GCRY_CIPHER_AES,
235                           GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
236   if (err)
237     {
238       fail ("aes-cbc-cts, grcy_open_cipher failed: %s\n", gpg_strerror (err));
239       return;
240     }
241
242   err = gcry_cipher_setkey (hd, key, 128 / 8);
243   if (err)
244     {
245       fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n",
246             gpg_strerror (err));
247       gcry_cipher_close (hd);
248       return;
249     }
250
251   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
252     {
253       err = gcry_cipher_setiv (hd, NULL, 0);
254       if (err)
255         {
256           fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
257                 gpg_strerror (err));
258           gcry_cipher_close (hd);
259           return;
260         }
261
262       err = gcry_cipher_encrypt (hd, out, MAX_DATA_LEN,
263                                  plaintext, tv[i].inlen);
264       if (err)
265         {
266           fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n",
267                 gpg_strerror (err));
268           gcry_cipher_close (hd);
269           return;
270         }
271
272       if (memcmp (tv[i].out, out, tv[i].inlen))
273         fail ("aes-cbc-cts, encrypt mismatch entry %d\n", i);
274
275       err = gcry_cipher_setiv (hd, NULL, 0);
276       if (err)
277         {
278           fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
279                 gpg_strerror (err));
280           gcry_cipher_close (hd);
281           return;
282         }
283       err = gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0);
284       if (err)
285         {
286           fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n",
287                 gpg_strerror (err));
288           gcry_cipher_close (hd);
289           return;
290         }
291
292       if (memcmp (plaintext, out, tv[i].inlen))
293         fail ("aes-cbc-cts, decrypt mismatch entry %d\n", i);
294     }
295
296   gcry_cipher_close (hd);
297 }
298
299 static void
300 check_ctr_cipher (void)
301 {
302   struct tv
303   {
304     int algo;
305     char key[MAX_DATA_LEN];
306     char ctr[MAX_DATA_LEN];
307     struct data
308     {
309       char plaintext[MAX_DATA_LEN];
310       int inlen;
311       char out[MAX_DATA_LEN];
312     }
313     data[MAX_DATA_LEN];
314   } tv[] =
315     {
316       /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
317       { GCRY_CIPHER_AES,
318         "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
319         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
320         { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
321             16,
322             "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
323           { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
324             16,
325             "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" },
326           { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
327             16,
328             "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" },
329           { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
330             16,
331             "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
332         }
333       },
334       { GCRY_CIPHER_AES192,
335         "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
336         "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
337         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
338         { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
339             16,
340             "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" },
341           { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
342             16,
343             "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" },
344           { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
345             16,
346             "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" },
347           { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
348             16,
349             "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" },
350         }
351       },
352       { GCRY_CIPHER_AES256,
353         "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
354         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
355         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
356         { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
357             16,
358             "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" },
359           { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
360             16,
361             "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" },
362           { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
363             16,
364             "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" },
365           { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
366             16,
367             "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" }
368         }
369       }
370     };
371   gcry_cipher_hd_t hde, hdd;
372   char out[MAX_DATA_LEN];
373   int i, j, keylen, blklen;
374   gcry_error_t err = 0;
375
376   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
377     {
378       err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
379       if (!err)
380         err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
381       if (err)
382         {
383           fail ("aes-ctr, grcy_open_cipher failed: %s\n", gpg_strerror (err));
384           return;
385         }
386
387       keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
388       if (!keylen)
389         {
390           fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n");
391           return;
392         }
393
394       err = gcry_cipher_setkey (hde, tv[i].key, keylen);
395       if (!err)
396         err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
397       if (err)
398         {
399           fail ("aes-ctr, gcry_cipher_setkey failed: %s\n",
400                 gpg_strerror (err));
401           gcry_cipher_close (hde);
402           gcry_cipher_close (hdd);
403           return;
404         }
405
406       blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
407       if (!blklen)
408         {
409           fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n");
410           return;
411         }
412
413       err = gcry_cipher_setctr (hde, tv[i].ctr, blklen);
414       if (!err)
415         err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen);
416       if (err)
417         {
418           fail ("aes-ctr, gcry_cipher_setctr failed: %s\n",
419                 gpg_strerror (err));
420           gcry_cipher_close (hde);
421           gcry_cipher_close (hdd);
422           return;
423         }
424
425       for (j = 0; tv[i].data[j].inlen; j++)
426         {
427           err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
428                                      tv[i].data[j].plaintext,
429                                      tv[i].data[j].inlen == -1 ?
430                                      strlen (tv[i].data[j].plaintext) :
431                                      tv[i].data[j].inlen);
432           if (err)
433             {
434               fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n",
435                     i, j, gpg_strerror (err));
436               gcry_cipher_close (hde);
437               gcry_cipher_close (hdd);
438               return;
439             }
440
441           if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
442             fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j);
443
444           err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
445           if (err)
446             {
447               fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n",
448                     i, j, gpg_strerror (err));
449               gcry_cipher_close (hde);
450               gcry_cipher_close (hdd);
451               return;
452             }
453
454           if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
455             fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j);
456         }
457
458       gcry_cipher_close (hde);
459       gcry_cipher_close (hdd);
460     }
461 }
462
463 static void
464 check_one_cipher (int algo, int mode, int flags)
465 {
466   gcry_cipher_hd_t hd;
467   char key[32], plain[16], in[16], out[16];
468   int keylen;
469   gcry_error_t err = 0;
470
471   memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32);
472   memcpy (plain, "foobar42FOOBAR17", 16);
473
474   keylen = gcry_cipher_get_algo_keylen (algo);
475   if (!keylen)
476     {
477       fail ("algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n",
478             algo, mode);
479       return;
480     }
481
482   if (keylen < 40 / 8 || keylen > 32)
483     {
484       fail ("algo %d, mode %d, keylength problem (%d)\n", algo, mode, keylen);
485       return;
486     }
487
488   err = gcry_cipher_open (&hd, algo, mode, flags);
489   if (err)
490     {
491       fail ("algo %d, mode %d, grcy_open_cipher failed: %s\n",
492             algo, mode, gpg_strerror (err));
493       return;
494     }
495
496   err = gcry_cipher_setkey (hd, key, keylen);
497   if (err)
498     {
499       fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n",
500             algo, mode, gpg_strerror (err));
501       gcry_cipher_close (hd);
502       return;
503     }
504
505   err = gcry_cipher_encrypt (hd, out, 16, plain, 16);
506   if (err)
507     {
508       fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
509             algo, mode, gpg_strerror (err));
510       gcry_cipher_close (hd);
511       return;
512     }
513
514   gcry_cipher_reset (hd);
515
516   err = gcry_cipher_decrypt (hd, in, 16, out, 16);
517   if (err)
518     {
519       fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n",
520             algo, mode, gpg_strerror (err));
521       gcry_cipher_close (hd);
522       return;
523     }
524
525   gcry_cipher_close (hd);
526
527   if (memcmp (plain, in, 16))
528     fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode);
529 }
530
531
532 static void
533 check_ciphers (void)
534 {
535   static int algos[] = {
536     GCRY_CIPHER_3DES,
537     GCRY_CIPHER_CAST5,
538     GCRY_CIPHER_BLOWFISH,
539     GCRY_CIPHER_AES,
540     GCRY_CIPHER_AES192,
541     GCRY_CIPHER_AES256,
542     GCRY_CIPHER_TWOFISH,
543     GCRY_CIPHER_TWOFISH128,
544     GCRY_CIPHER_DES,
545     GCRY_CIPHER_SERPENT128,
546     GCRY_CIPHER_SERPENT192,
547     GCRY_CIPHER_SERPENT256,
548     0
549   };
550   static int algos2[] = {
551     GCRY_CIPHER_ARCFOUR,
552     0
553   };
554   int i;
555
556   for (i = 0; algos[i]; i++)
557     {
558       if (verbose)
559         fprintf (stderr, "checking `%s' [%i]\n",
560                  gcry_cipher_algo_name (algos[i]),
561                  gcry_cipher_map_name (gcry_cipher_algo_name (algos[i])));
562
563       check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0);
564       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0);
565       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0);
566       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
567       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0);
568     }
569
570   for (i = 0; algos2[i]; i++)
571     {
572       if (verbose)
573         fprintf (stderr, "checking `%s'\n",
574                  gcry_cipher_algo_name (algos2[i]));
575
576       check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0);
577     }
578   /* we have now run all cipher's selftests */
579
580   /* TODO: add some extra encryption to test the higher level functions */
581 }
582
583
584
585 static void
586 check_one_md (int algo, char *data, int len, char *expect)
587 {
588   gcry_md_hd_t hd, hd2;
589   char *p;
590   int mdlen;
591   int i;
592   gcry_error_t err = 0;
593
594   err = gcry_md_open (&hd, algo, 0);
595   if (err)
596     {
597       fail ("algo %d, grcy_md_open failed: %s\n", algo, gpg_strerror (err));
598       return;
599     }
600
601   mdlen = gcry_md_get_algo_dlen (algo);
602   if (mdlen < 1 || mdlen > 500)
603     {
604       fail ("algo %d, grcy_md_get_algo_dlen failed: %d\n", algo, mdlen);
605       return;
606     }
607
608   if (*data == '!' && !data[1])
609     {                           /* hash one million times a "a" */
610       char aaa[1000];
611
612       memset (aaa, 'a', 1000);
613       for (i = 0; i < 1000; i++)
614         gcry_md_write (hd, aaa, 1000);
615     }
616   else
617     gcry_md_write (hd, data, len);
618
619   err = gcry_md_copy (&hd2, hd);
620   if (err)
621     {
622       fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err));
623     }
624
625   gcry_md_close (hd);
626
627   p = gcry_md_read (hd2, algo);
628
629   if (memcmp (p, expect, mdlen))
630     {
631       printf ("computed: ");
632       for (i = 0; i < mdlen; i++)
633         printf ("%02x ", p[i] & 0xFF);
634       printf ("\nexpected: ");
635       for (i = 0; i < mdlen; i++)
636         printf ("%02x ", expect[i] & 0xFF);
637       printf ("\n");
638
639       fail ("algo %d, digest mismatch\n", algo);
640     }
641
642   gcry_md_close (hd2);
643 }
644
645 static void
646 check_digests (void)
647 {
648   static struct algos
649   {
650     int md;
651     char *data;
652     char *expect;
653   } algos[] =
654     {
655       { GCRY_MD_MD4, "",
656         "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" },
657       { GCRY_MD_MD4, "a",
658         "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" },
659       { GCRY_MD_MD4, "message digest",
660         "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" },
661       { GCRY_MD_MD5, "",
662         "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" },
663       { GCRY_MD_MD5, "a",
664         "\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61" },
665       { GCRY_MD_MD5, "abc",
666         "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" },
667       { GCRY_MD_MD5, "message digest",
668         "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" },
669       { GCRY_MD_SHA1, "abc",
670         "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
671         "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" },
672       { GCRY_MD_SHA1,
673         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
674         "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
675         "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" },
676       { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ ,
677         "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
678         "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" },
679       { GCRY_MD_SHA256, "abc",
680         "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
681         "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
682       { GCRY_MD_SHA256,
683         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
684         "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
685         "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
686       { GCRY_MD_SHA256, "!",
687         "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
688         "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" },
689       { GCRY_MD_SHA384, "abc",
690         "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
691         "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
692         "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7" },
693       { GCRY_MD_SHA512, "abc",
694         "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
695         "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
696         "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
697         "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" },
698       { GCRY_MD_RMD160, "",
699         "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
700         "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" },
701       { GCRY_MD_RMD160, "a",
702         "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae"
703         "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" },
704       { GCRY_MD_RMD160, "abc",
705         "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04"
706         "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" },
707       { GCRY_MD_RMD160, "message digest",
708         "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
709         "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" },
710       { GCRY_MD_CRC32, "", "\x00\x00\x00\x00" },
711       { GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" },
712       { GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" },
713       { GCRY_MD_CRC32_RFC1510, "foo", "\x73\x32\xbc\x33" },
714       { GCRY_MD_CRC32_RFC1510, "test0123456789", "\xb8\x3e\x88\xd6" },
715       { GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY",
716         "\xe3\x41\x80\xf7" },
717 #if 0
718       { GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b" },
719       { GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32" },
720       { GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20" },
721 #endif
722       { GCRY_MD_CRC32_RFC1510, "\x80", "\xed\xb8\x83\x20" },
723 #if 0
724       { GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b" },
725       { GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96" },
726 #endif
727       { GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" },
728       { GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" },
729       { GCRY_MD_TIGER, "",
730         "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76"
731         "\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" },
732       { GCRY_MD_TIGER, "abc",
733         "\xF2\x58\xC1\xE8\x84\x14\xAB\x2A\x52\x7A\xB5\x41"
734         "\xFF\xC5\xB8\xBF\x93\x5F\x7B\x95\x1C\x13\x29\x51" },
735       { GCRY_MD_TIGER, "Tiger",
736         "\x9F\x00\xF5\x99\x07\x23\x00\xDD\x27\x6A\xBB\x38"
737         "\xC8\xEB\x6D\xEC\x37\x79\x0C\x11\x6F\x9D\x2B\xDF" },
738       { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg"
739         "hijklmnopqrstuvwxyz0123456789+-",
740         "\x87\xFB\x2A\x90\x83\x85\x1C\xF7\x47\x0D\x2C\xF8"
741         "\x10\xE6\xDF\x9E\xB5\x86\x44\x50\x34\xA5\xA3\x86" },
742       { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdef"
743         "ghijklmnopqrstuvwxyz+0123456789",
744         "\x46\x7D\xB8\x08\x63\xEB\xCE\x48\x8D\xF1\xCD\x12"
745         "\x61\x65\x5D\xE9\x57\x89\x65\x65\x97\x5F\x91\x97" },
746 #if 0
747       { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
748         "by Ross Anderson and Eli Biham",
749         "0C410A042968868A1671DA5A3FD29A725EC1E457D3CDB303" },
750       { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
751         "by Ross Anderson and Eli Biham, proceedings of Fa"
752         "st Software Encryption 3, Cambridge.",
753         "EBF591D5AFA655CE7F22894FF87F54AC89C811B6B0DA3193" },
754       { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
755         "by Ross Anderson and Eli Biham, proceedings of Fa"
756         "st Software Encryption 3, Cambridge, 1996.",
757         "3D9AEB03D1BD1A6357B2774DFD6D5B24DD68151D503974FC" },
758       { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh"
759         "ijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRS"
760         "TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
761         "00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4" },
762 #endif
763       { GCRY_MD_WHIRLPOOL, "",
764         "\x19\xFA\x61\xD7\x55\x22\xA4\x66\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
765         "\xC5\x30\x23\x21\x30\xD4\x07\xF8\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
766         "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB\xCF\x88\xE3\xE0\x3C\x4F\x07\x57"
767         "\xEA\x89\x64\xE5\x9B\x63\xD9\x37\x08\xB1\x38\xCC\x42\xA6\x6E\xB3" },
768       { GCRY_MD_WHIRLPOOL, "a",
769         "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
770         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42"
771         "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59"
772         "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" },
773       { GCRY_MD_WHIRLPOOL, "a",
774         "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
775         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42"
776         "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59"
777         "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" },
778       { GCRY_MD_WHIRLPOOL,
779         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
780         "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
781         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
782         "\x08\xEB\xA2\x66\x29\x12\x9D\x8F\xB7\xCB\x57\x21\x1B\x92\x81\xA6"
783         "\x55\x17\xCC\x87\x9D\x7B\x96\x21\x42\xC6\x5F\x5A\x7A\xF0\x14\x67" },
784       { GCRY_MD_WHIRLPOOL,
785         "!",
786         "\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D"
787         "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5"
788         "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD"
789         "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" },
790       { 0 },
791     };
792   int i;
793
794   for (i = 0; algos[i].md; i++)
795     {
796       if (verbose)
797         fprintf (stderr, "checking `%s'\n", gcry_md_algo_name (algos[i].md));
798
799       check_one_md (algos[i].md, algos[i].data, strlen (algos[i].data),
800                     algos[i].expect);
801     }
802
803   /* TODO: test HMAC mode */
804 }
805
806 /* Check that the signature SIG matches the hash HASH. PKEY is the
807    public key used for the verification. BADHASH is a hasvalue which
808    should; result in a bad signature status. */
809 static void
810 verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash,
811                       gcry_sexp_t badhash, gcry_sexp_t sig)
812 {
813   gcry_error_t rc;
814
815   rc = gcry_pk_verify (sig, hash, pkey);
816   if (rc)
817     fail ("gcry_pk_verify failed: %s\n", gpg_strerror (rc));
818   rc = gcry_pk_verify (sig, badhash, pkey);
819   if (gcry_err_code (rc) != GPG_ERR_BAD_SIGNATURE)
820     fail ("gcry_pk_verify failed to detect a bad signature: %s\n",
821           gpg_strerror (rc));
822 }
823
824
825 /* Test the public key sign function using the private ket SKEY. PKEY
826    is used for verification. */
827 static void
828 check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey)
829 {
830   gcry_error_t rc;
831   gcry_sexp_t sig, badhash, hash;
832   int dataidx;
833   static const char baddata[] =
834     "(data\n (flags pkcs1)\n"
835     " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n";
836   static struct
837   {
838     const char *data;
839     int expected_rc;
840   } datas[] =
841     {
842       { "(data\n (flags pkcs1)\n"
843         " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
844         0 },
845       { "(data\n (flags )\n"
846         " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
847         GPG_ERR_CONFLICT },
848       { "(data\n (flags pkcs1)\n"
849         " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n",
850         GPG_ERR_DIGEST_ALGO },
851       { "(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
852         0 },
853       { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n",
854         0 },
855       { "(data\n (flags pkcs1)\n"
856         " (value #11223344556677889900AA#))\n",
857         GPG_ERR_CONFLICT },
858       { "(data\n (flags raw foo)\n"
859         " (value #11223344556677889900AA#))\n",
860         GPG_ERR_INV_FLAG },
861       { NULL }
862     };
863
864   rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata));
865   if (rc)
866     die ("converting data failed: %s\n", gpg_strerror (rc));
867
868   for (dataidx = 0; datas[dataidx].data; dataidx++)
869     {
870       if (verbose)
871         fprintf (stderr, "signature test %d\n", dataidx);
872
873       rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data,
874                             strlen (datas[dataidx].data));
875       if (rc)
876         die ("converting data failed: %s\n", gpg_strerror (rc));
877
878       rc = gcry_pk_sign (&sig, hash, skey);
879       if (gcry_err_code (rc) != datas[dataidx].expected_rc)
880         fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc));
881
882       if (!rc)
883         verify_one_signature (pkey, hash, badhash, sig);
884
885       gcry_sexp_release (sig);
886       sig = NULL;
887       gcry_sexp_release (hash);
888       hash = NULL;
889     }
890
891   gcry_sexp_release (badhash);
892 }
893
894 static void
895 check_pubkey_grip (int n, const unsigned char *grip,
896                    gcry_sexp_t skey, gcry_sexp_t pkey)
897 {
898   unsigned char sgrip[20], pgrip[20];
899
900   if (!gcry_pk_get_keygrip (skey, sgrip))
901     die ("get keygrip for private RSA key failed\n");
902   if (!gcry_pk_get_keygrip (pkey, pgrip))
903     die ("[%i] get keygrip for public RSA key failed\n", n);
904   if (memcmp (sgrip, pgrip, 20))
905     fail ("[%i] keygrips don't match\n", n);
906   if (memcmp (sgrip, grip, 20))
907     fail ("wrong keygrip for RSA key\n");
908 }
909
910 static void
911 do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey,
912                      const unsigned char *grip, int flags)
913 {
914  if (flags & FLAG_SIGN)
915     check_pubkey_sign (n, skey, pkey);
916  if (grip && (flags & FLAG_GRIP))
917    check_pubkey_grip (n, grip, skey, pkey);
918 }
919
920 static void
921 check_one_pubkey (int n, test_spec_pubkey_t spec)
922 {
923   gcry_error_t err = GPG_ERR_NO_ERROR;
924   gcry_sexp_t skey, pkey;
925
926   err = gcry_sexp_sscan (&skey, NULL, spec.key.secret,
927                          strlen (spec.key.secret));
928   if (!err)
929     err = gcry_sexp_sscan (&pkey, NULL, spec.key.public,
930                            strlen (spec.key.public));
931   if (err)
932     die ("converting sample key failed: %s\n", gpg_strerror (err));
933
934   do_check_one_pubkey (n, skey, pkey, spec.key.grip, spec.flags);
935  
936   gcry_sexp_release (skey);
937   gcry_sexp_release (pkey);
938 }
939
940 static void
941 get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
942 {
943   gcry_sexp_t key_spec, key, pub_key, sec_key;
944   int rc;
945   
946   rc = gcry_sexp_new (&key_spec,
947                       "(genkey (rsa (nbits 4:1024)))", 0, 1);
948   if (rc)
949     die ("error creating S-expression: %s\n", gpg_strerror (rc));
950   rc = gcry_pk_genkey (&key, key_spec);
951   gcry_sexp_release (key_spec);
952   if (rc)
953     die ("error generating RSA key: %s\n", gpg_strerror (rc));
954     
955   pub_key = gcry_sexp_find_token (key, "public-key", 0);
956   if (! pub_key)
957     die ("public part missing in key\n");
958
959   sec_key = gcry_sexp_find_token (key, "private-key", 0);
960   if (! sec_key)
961     die ("private part missing in key\n");
962
963   gcry_sexp_release (key);
964   *pkey = pub_key;
965   *skey = sec_key;
966 }
967
968 static void
969 check_one_pubkey_new (int n)
970 {
971   gcry_sexp_t skey, pkey;
972
973   get_keys_new (&pkey, &skey);
974   do_check_one_pubkey (n, skey, pkey, NULL, FLAG_SIGN | FLAG_CRYPT);
975 }
976
977 /* Run all tests for the public key fucntions. */
978 static void
979 check_pubkey (void)
980 {
981   test_spec_pubkey_t pubkeys[] =
982     {
983       {
984         GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN,
985
986         { "(private-key\n"
987           " (rsa\n"
988           "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
989           "      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
990           "      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
991           "      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
992           "  (e #010001#)\n"
993           "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
994           "      7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
995           "      C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
996           "      C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
997           "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
998           "      fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
999           "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
1000           "      35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
1001           "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
1002           "      ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))\n",
1003
1004           "(public-key\n"
1005           " (rsa\n"
1006           "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
1007           "      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
1008           "      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
1009           "      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
1010           "  (e #010001#)))\n",
1011
1012           "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9"
1013           "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"}
1014       },
1015       {
1016         GCRY_PK_DSA, FLAG_SIGN,
1017
1018         { "(private-key\n"
1019           " (DSA\n"
1020           "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
1021           "      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
1022           "      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
1023           "      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n"
1024           "  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
1025           "  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
1026           "      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
1027           "      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
1028           "      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n"
1029           "  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
1030           "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
1031           "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
1032           "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)\n"
1033           "  (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))\n",
1034
1035           "(public-key\n"
1036           " (DSA\n"
1037           "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
1038           "      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
1039           "      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
1040           "      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n"
1041           "  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
1042           "  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
1043           "      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
1044           "      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
1045           "      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n"
1046           "  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
1047           "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
1048           "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
1049           "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))\n",
1050
1051           "\xc6\x39\x83\x1a\x43\xe5\x05\x5d\xc6\xd8"
1052           "\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" }
1053       },
1054       {
1055         GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT,
1056
1057         { "(private-key\n"
1058           " (ELG\n"
1059           "  (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
1060           "      F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
1061           "      B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
1062           "      6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n"
1063           "  (g #05#)\n"
1064           "  (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
1065           "      E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
1066           "      D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
1067           "      56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)\n"
1068           "  (x #03C28900087B38DABF4A0AB98ACEA39BB674D6557096C01D72E31C16BDD32214#)))\n",
1069
1070           "(public-key\n"
1071           " (ELG\n"
1072           "  (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
1073           "      F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
1074           "      B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
1075           "      6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n"
1076           "  (g #05#)\n"
1077           "  (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
1078           "      E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
1079           "      D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
1080           "      56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)))\n",
1081
1082           "\xa7\x99\x61\xeb\x88\x83\xd2\xf4\x05\xc8"
1083           "\x4f\xba\x06\xf8\x78\x09\xbc\x1e\x20\xe5" }
1084       },
1085     };
1086   int i;
1087
1088   for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++)
1089     if (pubkeys[i].id)
1090       check_one_pubkey (i, pubkeys[i]);
1091
1092   check_one_pubkey_new (i);
1093 }
1094
1095 int
1096 main (int argc, char **argv)
1097 {
1098   int debug = 0;
1099
1100   if (argc > 1 && !strcmp (argv[1], "--verbose"))
1101     verbose = 1;
1102   else if (argc > 1 && !strcmp (argv[1], "--debug"))
1103     verbose = debug = 1;
1104
1105   if (!gcry_check_version (GCRYPT_VERSION))
1106     die ("version mismatch\n");
1107
1108   gcry_set_progress_handler (progress_handler, NULL);
1109   
1110   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1111   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1112   if (debug)
1113     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
1114   check_ciphers ();
1115   check_aes128_cbc_cts_cipher ();
1116   check_cbc_mac_cipher ();
1117   check_ctr_cipher ();
1118   check_digests ();
1119   check_pubkey ();
1120
1121   return error_count ? 1 : 0;
1122 }