2003-04-17 Moritz Schulte <moritz@g10code.com>
[libgcrypt.git] / tests / basic.c
1 /* basic.c  -  basic regression tests
2  *      Copyright (C) 2001, 2002, 2003 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 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include "../src/gcrypt.h"
26
27
28 static const char sample_private_key_1[] =
29 "(private-key\n"
30 " (rsa\n"
31 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
32       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
33       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
34       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
35 "  (e #010001#)\n"
36 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
37       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
38       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
39       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
40 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
41       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
42 "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
43       "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
44 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
45       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
46 " )\n"
47 ")\n";
48 static const char sample_public_key_1[] =
49 "(public-key\n"
50 " (rsa\n"
51 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
52       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
53       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
54       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
55 "  (e #010001#)\n"
56 " )\n"
57 ")\n";
58 static const unsigned char sample_grip_key_1[] =
59 "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9"
60 "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39";
61
62
63 static int verbose;
64 static int error_count;
65
66 static void
67 fail ( const char *format, ... )
68 {
69     va_list arg_ptr ;
70
71     va_start( arg_ptr, format ) ;
72     vfprintf (stderr, format, arg_ptr );
73     va_end(arg_ptr);
74     error_count++;
75 }
76
77 static void
78 die ( const char *format, ... )
79 {
80     va_list arg_ptr ;
81
82     va_start( arg_ptr, format ) ;
83     vfprintf (stderr, format, arg_ptr );
84     va_end(arg_ptr);
85     exit (1);
86 }
87
88 #define MAX_DATA_LEN 100
89
90 static void
91 check_cbc_mac_cipher (void)
92 {
93   struct tv {
94     int algo;
95     char key[MAX_DATA_LEN];
96     char plaintext[MAX_DATA_LEN];
97     size_t plaintextlen;
98     char mac[MAX_DATA_LEN];
99   } tv[] = {
100     { GCRY_CIPHER_AES,
101       "chicken teriyaki",
102       "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0,
103       "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" },
104     { GCRY_CIPHER_3DES,
105       "abcdefghABCDEFGH01234567",
106       "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0,
107       "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" },
108     { GCRY_CIPHER_DES,
109       "abcdefgh",
110       "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0,
111       "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" }
112   };
113   GCRY_CIPHER_HD hd;
114   char out[MAX_DATA_LEN];
115   int i;
116
117   for (i = 0; i < sizeof(tv) / sizeof(tv[0]); i++)
118     {
119       hd = gcry_cipher_open (tv[i].algo,
120                              GCRY_CIPHER_MODE_CBC,
121                              GCRY_CIPHER_CBC_MAC);
122       if (!hd) {
123         fail ("cbc-mac algo %d, grcy_open_cipher failed: %s\n",
124               tv[i].algo, gcry_strerror (-1) );
125         return;
126       }
127
128       if (gcry_cipher_setkey (hd, tv[i].key,
129                               gcry_cipher_get_algo_keylen (tv[i].algo))) {
130         fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n",
131               tv[i].algo, gcry_strerror (-1) );
132         gcry_cipher_close (hd);
133         return;
134       }
135
136       if (gcry_cipher_setiv (hd, NULL, 0)) {
137         fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n",
138               tv[i].algo, gcry_strerror (-1) );
139         gcry_cipher_close (hd);
140         return;
141       }
142
143       if ( gcry_cipher_encrypt (hd,
144                                 out, gcry_cipher_get_algo_blklen(tv[i].algo),
145                                 tv[i].plaintext,
146                                 tv[i].plaintextlen ?
147                                 tv[i].plaintextlen :
148                                 strlen(tv[i].plaintext))) {
149         fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n",
150               tv[i].algo, gcry_strerror (-1) );
151         gcry_cipher_close (hd);
152         return;
153       }
154
155 #if 0
156       { int j;
157         for (j=0; j < gcry_cipher_get_algo_blklen(tv[i].algo); j++)
158           printf("\\x%02x", out[j] & 0xFF);
159         printf("\n");
160       }
161 #endif
162
163       if ( memcmp (tv[i].mac, out, gcry_cipher_get_algo_blklen(tv[i].algo)) )
164         fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i);
165
166       gcry_cipher_close (hd);
167     }
168 }
169
170 static void
171 check_aes128_cbc_cts_cipher ()
172 {
173   char key[128/8] = "chicken teriyaki";
174   char plaintext[] = "I would like the General Gau's Chicken, please, and wonton soup.";
175   struct tv {
176     char out[MAX_DATA_LEN];
177     int inlen;
178   } tv[] = {
179     {  "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
180       "\x97", 17 },
181     { "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
182       "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5", 31 },
183     { "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
184       "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", 32 },
185     { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
186       "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
187       "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5", 47 },
188     { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
189       "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
190       "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", 48 },
191     { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
192       "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
193       "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
194       "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", 64 }
195   };
196   GCRY_CIPHER_HD hd;
197   char out[MAX_DATA_LEN];
198   int i;
199
200   hd = gcry_cipher_open (GCRY_CIPHER_AES, 
201                          GCRY_CIPHER_MODE_CBC, 
202                          GCRY_CIPHER_CBC_CTS);
203   if (!hd) {
204     fail ("aes-cbc-cts, grcy_open_cipher failed: %s\n", gcry_strerror (-1) );
205     return;
206   }
207
208   if (gcry_cipher_setkey (hd, key, 128/8)) { 
209     fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n", gcry_strerror (-1) );
210     gcry_cipher_close (hd);
211     return;
212   }
213
214   for (i = 0; i < sizeof(tv) / sizeof(tv[0]); i++)
215     {
216       if (gcry_cipher_setiv (hd, NULL, 0)) { 
217         fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
218               gcry_strerror (-1) );
219         gcry_cipher_close (hd);
220         return;
221       }
222
223       if ( gcry_cipher_encrypt (hd, out, MAX_DATA_LEN, 
224                                 plaintext, tv[i].inlen)) { 
225         fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n",
226               gcry_strerror (-1) );
227         gcry_cipher_close (hd);
228         return;
229       }
230
231       if ( memcmp (tv[i].out, out, tv[i].inlen) )
232         fail ("aes-cbc-cts, encrypt mismatch entry %d\n", i);
233
234       if (gcry_cipher_setiv (hd, NULL, 0)) { 
235         fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
236               gcry_strerror (-1) );
237         gcry_cipher_close (hd);
238         return;
239       }
240       if ( gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0)) { 
241         fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n",
242               gcry_strerror (-1) );
243         gcry_cipher_close (hd);
244         return;
245       }
246
247       if ( memcmp (plaintext, out, tv[i].inlen) )
248         fail ("aes-cbc-cts, decrypt mismatch entry %d\n", i);
249     }
250
251   gcry_cipher_close (hd);
252 }
253
254 static void
255 check_ctr_cipher (void)
256 {
257   struct tv {
258     int algo;
259     char key[MAX_DATA_LEN];
260     char ctr[MAX_DATA_LEN];
261     struct data {
262       char plaintext[MAX_DATA_LEN];
263       int inlen;
264       char out[MAX_DATA_LEN];
265     }  data[MAX_DATA_LEN];
266   } tv[] = {
267     /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
268     { GCRY_CIPHER_AES,
269       "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
270       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
271       {{ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
272          16,
273          "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
274        { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
275          16,
276          "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" },
277        { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
278          16,
279          "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" },
280        { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
281          16,
282          "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
283        {}}
284     },
285     { GCRY_CIPHER_AES192,
286       "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
287       "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
288       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
289       {{ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
290          16,
291          "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" },
292        { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
293          16,
294          "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" },
295        { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
296          16,
297          "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" },
298        { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
299          16,
300          "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" },
301        {}}
302     },
303     { GCRY_CIPHER_AES256,
304       "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
305       "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
306       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
307       {{ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
308          16,
309          "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" },
310        { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
311          16,
312          "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" },
313        { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
314          16,
315          "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" },
316        { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
317          16,
318          "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" },
319        {}}
320     }
321   };
322   GCRY_CIPHER_HD hde, hdd;
323   char out[MAX_DATA_LEN];
324   int i,j;
325
326   for (i = 0; i < sizeof(tv) / sizeof(tv[0]); i++)
327     {
328       hde = gcry_cipher_open (tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
329       hdd = gcry_cipher_open (tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
330       if (!hde || !hdd)
331         {
332           fail ("aes-ctr, grcy_open_cipher failed: %s\n",
333                 gcry_strerror (-1));
334           return;
335         }
336
337       if (gcry_cipher_setkey (hde, tv[i].key,
338                               gcry_cipher_get_algo_keylen(tv[i].algo)) ||
339           gcry_cipher_setkey (hdd, tv[i].key,
340                               gcry_cipher_get_algo_keylen(tv[i].algo)))
341         {
342           fail ("aes-ctr, gcry_cipher_setkey failed: %s\n",
343                 gcry_strerror (-1));
344           gcry_cipher_close (hde);
345           gcry_cipher_close (hdd);
346           return;
347         }
348
349       if (gcry_cipher_setctr (hde, tv[i].ctr,
350                               gcry_cipher_get_algo_blklen(tv[i].algo)) ||
351           gcry_cipher_setctr (hdd, tv[i].ctr,
352                               gcry_cipher_get_algo_blklen(tv[i].algo)))
353         {
354           fail ("aes-ctr, gcry_cipher_setctr failed: %s\n",
355                 gcry_strerror (-1));
356           gcry_cipher_close (hde);
357           gcry_cipher_close (hdd);
358           return;
359         }
360
361       for (j = 0; tv[i].data[j].inlen; j++)
362         {
363           if (gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
364                                    tv[i].data[j].plaintext,
365                                    tv[i].data[j].inlen == -1 ?
366                                    strlen(tv[i].data[j].plaintext) :
367                                    tv[i].data[j].inlen))
368             {
369               fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n",
370                     i, j, gcry_strerror (-1));
371               gcry_cipher_close (hde);
372               gcry_cipher_close (hdd);
373               return;
374             }
375
376           if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
377             fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j);
378
379           if (gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0))
380             {
381               fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n",
382                     i, j, gcry_strerror (-1));
383               gcry_cipher_close (hde);
384               gcry_cipher_close (hdd);
385               return;
386             }
387
388           if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
389             fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j);
390         }
391
392       gcry_cipher_close (hde);
393       gcry_cipher_close (hdd);
394     }
395 }
396
397 static void
398 check_one_cipher (int algo, int mode, int flags)
399 {
400     GCRY_CIPHER_HD hd;
401     char key[32], plain[16], in[16], out[16];
402     int keylen;
403
404     memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32);
405     memcpy (plain, "foobar42FOOBAR17", 16);
406
407     keylen = gcry_cipher_get_algo_keylen (algo);
408     if (keylen < 40/8 || keylen > 32 ) {
409         fail ("algo %d, mode %d, keylength problem (%d)\n",
410               algo, mode, keylen );
411         return;
412     }
413
414     hd = gcry_cipher_open (algo, mode, flags);
415     if (!hd) {
416         fail ("algo %d, mode %d, grcy_open_cipher failed: %s\n",
417               algo, mode, gcry_strerror (-1) );
418         return;
419     }
420
421     
422     if (gcry_cipher_setkey (hd, key, keylen)) { 
423         fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n",
424               algo, mode, gcry_strerror (-1) );
425         gcry_cipher_close (hd);
426         return;
427     }
428     
429     if ( gcry_cipher_encrypt (hd, out, 16, plain, 16)) { 
430         fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
431               algo, mode, gcry_strerror (-1) );
432         gcry_cipher_close (hd);
433         return;
434     }
435
436     gcry_cipher_reset (hd);
437
438     if ( gcry_cipher_decrypt (hd, in, 16, out, 16)) { 
439         fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n",
440               algo, mode, gcry_strerror (-1) );
441         gcry_cipher_close (hd);
442         return;
443     }
444
445     gcry_cipher_close (hd);
446
447     if ( memcmp (plain, in, 16) )
448         fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode);
449 }
450
451
452 static void
453 check_ciphers (void)
454 {
455   static int algos[] = {
456     GCRY_CIPHER_3DES,
457     GCRY_CIPHER_CAST5,
458     GCRY_CIPHER_BLOWFISH,
459     GCRY_CIPHER_AES,
460     GCRY_CIPHER_AES192,
461     GCRY_CIPHER_AES256,
462     GCRY_CIPHER_TWOFISH,
463     GCRY_CIPHER_DES,
464     0
465   };
466   static int algos2[] = {
467     GCRY_CIPHER_ARCFOUR,
468     0
469   };
470   int i;
471
472   for (i=0; algos[i]; i++ ) 
473     {
474       if (verbose)
475         fprintf (stderr, "checking `%s'\n", gcry_cipher_algo_name (algos[i]));
476                  
477       check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0);
478       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0);
479       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0);
480       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
481       check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0);
482     }
483
484   for (i=0; algos2[i]; i++ ) 
485     {
486       if (verbose)
487         fprintf (stderr, "checking `%s'\n", gcry_cipher_algo_name (algos2[i]));
488                  
489       check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0);
490     }
491   /* we have now run all cipher's selftests */
492
493   /* TODO: add some extra encryption to test the higher level functions */
494 }
495
496
497
498 static void
499 check_one_md (int algo, char *data, int len, char *expect)
500 {
501     GCRY_MD_HD hd, hd2;
502     char *p;
503     int mdlen;
504     int i;
505
506     hd = gcry_md_open (algo, 0);
507     if (!hd) {
508         fail ("algo %d, grcy_md_open failed: %s\n",
509               algo, gcry_strerror (-1) );
510         return;
511     }
512
513     mdlen = gcry_md_get_algo_dlen(algo);
514     if (mdlen < 1 || mdlen > 500) {
515         fail ("algo %d, grcy_md_get_algo_dlen failed: %d\n", algo, mdlen);
516         return;
517     }
518
519     if (*data == '!' && !data[1])
520       { /* hash one million times a "a" */
521         char aaa[1000];
522         
523         memset (aaa, 'a', 1000);
524         for (i=0; i < 1000; i++)
525           gcry_md_write (hd, aaa, 1000);
526       }
527     else
528       gcry_md_write (hd, data, len);
529
530     hd2 = gcry_md_copy (hd);
531     if (! hd2)
532       {
533         fail ("algo %d, gcry_md_copy failed: %s\n",
534               algo, gcry_strerror (-1));
535       }
536     
537     gcry_md_close (hd);
538
539     p = gcry_md_read (hd2, algo);
540
541     if ( memcmp (p, expect, mdlen) )
542       {
543         printf("computed: ");
544         for (i=0; i < mdlen; i++)
545           printf("%02x ", p[i] & 0xFF);
546         printf("\nexpected: ");
547         for (i=0; i < mdlen; i++)
548           printf("%02x ", expect[i] & 0xFF);
549         printf("\n");
550
551         fail ("algo %d, digest mismatch\n", algo);
552       }
553
554     gcry_md_close (hd2);
555 }
556
557 static void
558 check_digests ()
559 {
560   static struct algos {
561     int md;
562     char *data;
563     char *expect;
564   } algos[] = {
565     { GCRY_MD_MD4, "",
566       "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" },
567     { GCRY_MD_MD4, "a",
568       "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" },
569     { GCRY_MD_MD4, "message digest",
570       "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" },
571     { GCRY_MD_MD5, "",
572       "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" },
573     { GCRY_MD_MD5, "a", 
574       "\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61" },
575     { GCRY_MD_MD5, "abc",
576       "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" },
577     { GCRY_MD_MD5, "message digest", 
578       "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0"},
579     { GCRY_MD_SHA1, "abc",
580       "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
581       "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"},
582     { GCRY_MD_SHA1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
583       "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
584       "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" },
585     { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */,
586       "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
587       "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" },
588     { GCRY_MD_SHA256, "abc",
589       "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
590       "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
591     { GCRY_MD_SHA256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
592       "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
593       "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
594     { GCRY_MD_SHA256, "!",
595       "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" 
596       "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" },
597     { GCRY_MD_RMD160, "",
598       "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
599       "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" },
600     { GCRY_MD_RMD160, "a",
601       "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae"
602       "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" },
603     { GCRY_MD_RMD160, "abc",
604       "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04"
605       "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" },
606     { GCRY_MD_RMD160, "message digest",
607       "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
608       "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" },
609     { GCRY_MD_CRC32, "",
610       "\x00\x00\x00\x00" },
611     { GCRY_MD_CRC32, "foo",
612       "\x8c\x73\x65\x21" },
613     { GCRY_MD_CRC32_RFC1510, "",
614       "\x00\x00\x00\x00" },
615     { GCRY_MD_CRC32_RFC1510, "foo",
616       "\x73\x32\xbc\x33" }, 
617     { GCRY_MD_CRC32_RFC1510, "test0123456789",
618       "\xb8\x3e\x88\xd6" },
619     { GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY",
620       "\xe3\x41\x80\xf7" },
621 #if 0
622     { GCRY_MD_CRC32_RFC1510, "\x80\x00",
623       "\x3b\x83\x98\x4b" },
624     { GCRY_MD_CRC32_RFC1510, "\x00\x08",
625       "\x0e\xdb\x88\x32" },
626     { GCRY_MD_CRC32_RFC1510, "\x00\x80",
627       "\xed\xb8\x83\x20" },
628 #endif
629     { GCRY_MD_CRC32_RFC1510, "\x80",
630       "\xed\xb8\x83\x20" },
631 #if 0
632     { GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00",
633       "\xed\x59\xb6\x3b" },
634     { GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01",
635       "\x77\x07\x30\x96" },
636 #endif
637     { GCRY_MD_CRC24_RFC2440, "",
638       "\xb7\x04\xce" },
639     { GCRY_MD_CRC24_RFC2440, "foo",
640       "\x4f\xc2\x55" },
641 #if 0
642     { GCRY_MD_TIGER, "",
643       "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76"
644       "\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" },
645     { GCRY_MD_TIGER, "abc",
646       "\xF2\x58\xC1\xE8\x84\x14\xAB\x2A\x52\x7A\xB5\x41"
647       "\xFF\xC5\xB8\xBF\x93\x5F\x7B\x95\x1C\x13\x29\x51" },
648     { GCRY_MD_TIGER, "Tiger",
649       "\x9F\x00\xF5\x99\x07\x23\x00\xDD\x27\x6A\xBB\x38"
650       "\xC8\xEB\x6D\xEC\x37\x79\x0C\x11\x6F\x9D\x2B\xDF" },
651     { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg"
652       "hijklmnopqrstuvwxyz0123456789+-",
653       "\x87\xFB\x2A\x90\x83\x85\x1C\xF7\x47\x0D\x2C\xF8"
654       "\x10\xE6\xDF\x9E\xB5\x86\x44\x50\x34\xA5\xA3\x86" },
655     { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdef"
656       "ghijklmnopqrstuvwxyz+0123456789",
657       "467DB80863EBCE488DF1CD1261655DE957896565975F9197" },
658     { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
659       "by Ross Anderson and Eli Biham",
660       "0C410A042968868A1671DA5A3FD29A725EC1E457D3CDB303" },
661     { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
662       "by Ross Anderson and Eli Biham, proceedings of Fa"
663       "st Software Encryption 3, Cambridge.",
664       "EBF591D5AFA655CE7F22894FF87F54AC89C811B6B0DA3193" },
665     { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
666       "by Ross Anderson and Eli Biham, proceedings of Fa"
667       "st Software Encryption 3, Cambridge, 1996.",
668       "3D9AEB03D1BD1A6357B2774DFD6D5B24DD68151D503974FC" },
669     { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh"
670       "ijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRS"
671       "TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
672       "00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4" },
673 #endif
674     { 0 }
675   };
676   int i;
677
678   for (i=0; algos[i].md; i++ ) 
679     {
680       if (verbose)
681         fprintf (stderr, "checking `%s'\n", gcry_md_algo_name (algos[i].md));
682                  
683       check_one_md (algos[i].md, algos[i].data, strlen(algos[i].data), 
684                     algos[i].expect);
685     }
686
687   /* TODO: test HMAC mode */
688 }
689
690 /* Check that the signature SIG matches the hash HASH. PKEY is the
691    public key used for the verification. BADHASH is a hasvalue which
692    should; result in a bad signature status. */
693 static void
694 verify_one_signature (GcrySexp pkey, GcrySexp hash,
695                       GcrySexp badhash, GcrySexp sig)
696 {
697   int rc;
698
699   rc = gcry_pk_verify (sig, hash, pkey);
700   if (rc)
701     fail ("gcry_pk_verify failed: %s\n", gcry_strerror (rc));
702   rc = gcry_pk_verify (sig, badhash, pkey);
703   if (rc != GCRYERR_BAD_SIGNATURE)
704     fail ("gcry_pk_verify failed to detect a bad signature: %s\n",
705           gcry_strerror (rc));
706 }
707
708
709 /* Test the public key sign function using the private ket SKEY. PKEY
710    is used for verification. */
711 static void
712 check_pubkey_sign (GcrySexp skey, GcrySexp pkey)
713 {
714   int rc;
715   GcrySexp sig, badhash, hash;
716   int dataidx;
717   static const char baddata[] =
718     "(data\n (flags pkcs1)\n"
719     " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n";
720   static struct { const char *data; int expected_rc; } datas[] = {
721     { "(data\n (flags pkcs1)\n"
722       " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
723       0 },
724     { "(data\n (flags )\n"
725       " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
726       GCRYERR_CONFLICT },
727
728     { "(data\n (flags pkcs1)\n"
729       " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n",
730       GCRYERR_INV_MD_ALGO },
731
732     { "(data\n (flags )\n"
733       " (value #11223344556677889900AA#))\n",
734       0 },
735
736     { "(data\n (flags raw)\n"
737       " (value #11223344556677889900AA#))\n",
738       0 },
739
740     { "(data\n (flags pkcs1)\n"
741       " (value #11223344556677889900AA#))\n",
742       GCRYERR_CONFLICT },
743
744     { "(data\n (flags raw foo)\n"
745       " (value #11223344556677889900AA#))\n",
746       GCRYERR_INV_FLAG },
747     
748     { NULL }
749   };
750
751   rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata));
752   if (rc)
753       die ("converting data failed: %s\n", gcry_strerror (rc));
754       
755   for (dataidx=0; datas[dataidx].data; dataidx++)
756     {
757       if (verbose)
758         fprintf (stderr, "signature test %d\n", dataidx);
759
760       rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data,
761                             strlen (datas[dataidx].data));
762       if (rc)
763         die ("converting data failed: %s\n", gcry_strerror (rc));
764   
765       rc = gcry_pk_sign (&sig, hash, skey);
766       if (rc != datas[dataidx].expected_rc)
767         fail ("gcry_pk_sign failed: %s\n", gcry_strerror (rc));
768       
769       if (!rc)
770         verify_one_signature (pkey, hash, badhash, sig);
771
772       gcry_sexp_release (sig); sig= NULL;
773       gcry_sexp_release (hash); hash= NULL;
774     }
775
776   gcry_sexp_release (badhash);
777 }
778
779 /* Run all tests for the public key fucntions. */
780 static void
781 check_pubkey (void)
782 {
783   int rc;
784   GcrySexp skey, pkey;
785   unsigned char grip1[20], grip2[20];
786   
787   rc = gcry_sexp_sscan (&skey, NULL, sample_private_key_1,
788                         strlen (sample_private_key_1));
789   if (!rc)
790     rc = gcry_sexp_sscan (&pkey, NULL, sample_public_key_1,
791                           strlen (sample_public_key_1));
792   if (rc)
793     die ("converting sample key failed: %s\n", gcry_strerror (rc));
794
795   if (!gcry_pk_get_keygrip (pkey, grip1))
796     die ("get keygrip for public RSA key failed\n");
797   if (!gcry_pk_get_keygrip (skey, grip2))
798     die ("get keygrip for private RSA key failed\n");
799   if (memcmp (grip1, grip2, 20))
800     fail ("keygrips for RSA key don't match\n");
801   if (memcmp (grip1, sample_grip_key_1, 20))
802     fail ("wrong keygrip for RSA key\n");
803
804   /* FIXME: we need DSA and ElGamal example keys. */
805
806 /*    for (rc=0; rc < 20; rc++) */
807 /*      printf ("\\x%02x", grip1[rc]); */
808 /*    putchar ('\n'); */
809
810   check_pubkey_sign (skey, pkey);
811
812   gcry_sexp_release (skey);
813   gcry_sexp_release (pkey);
814 }
815
816
817
818 int
819 main (int argc, char **argv)
820 {
821   int debug = 0;
822
823   if (argc > 1 && !strcmp (argv[1], "--verbose"))
824     verbose = 1;
825   else if (argc > 1 && !strcmp (argv[1], "--debug"))
826     verbose = debug = 1;
827
828   if (!gcry_check_version (GCRYPT_VERSION))
829     die ("version mismatch\n");
830   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
831   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
832   if (debug)
833     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
834   check_ciphers ();
835   check_aes128_cbc_cts_cipher ();
836   check_cbc_mac_cipher ();
837   check_ctr_cipher ();
838   check_digests ();
839   check_pubkey ();
840   
841   return error_count? 1:0;
842 }