random: Fix possible AIX problem with sysconf in rndunix.
[libgcrypt.git] / tests / t-kdf.c
1 /* t-kdf.c -  KDF regression tests
2  * Copyright (C) 2011 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 #include <assert.h>
29
30 #include "../src/gcrypt-int.h"
31 #include "stopwatch.h"
32
33
34 #ifndef DIM
35 # define DIM(v)              (sizeof(v)/sizeof((v)[0]))
36 #endif
37
38 /* Program option flags.  */
39 static int verbose;
40 static int debug;
41 static int error_count;
42
43 static void
44 fail (const char *format, ...)
45 {
46   va_list arg_ptr;
47
48   va_start (arg_ptr, format);
49   vfprintf (stderr, format, arg_ptr);
50   va_end (arg_ptr);
51   error_count++;
52 }
53
54 static void
55 die (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   exit (1);
63 }
64
65
66 static void
67 dummy_consumer (volatile char *buffer, size_t buflen)
68 {
69   (void)buffer;
70   (void)buflen;
71 }
72
73
74 static void
75 bench_s2k (unsigned long s2kcount)
76 {
77   gpg_error_t err;
78   const char passphrase[] = "123456789abcdef0";
79   char keybuf[128/8];
80   unsigned int repetitions = 10;
81   unsigned int count;
82   const char *elapsed;
83   int pass = 0;
84
85  again:
86   start_timer ();
87   for (count = 0; count < repetitions; count++)
88     {
89       err = gcry_kdf_derive (passphrase, strlen (passphrase),
90                              GCRY_KDF_ITERSALTED_S2K,
91                              GCRY_MD_SHA1, "saltsalt", 8, s2kcount,
92                              sizeof keybuf, keybuf);
93       if (err)
94         die ("gcry_kdf_derive failed: %s\n", gpg_strerror (err));
95       dummy_consumer (keybuf, sizeof keybuf);
96     }
97   stop_timer ();
98
99   elapsed = elapsed_time (repetitions);
100   if (!pass++)
101     {
102       if (!atoi (elapsed))
103         {
104           repetitions = 10000;
105           goto again;
106         }
107       else if (atoi (elapsed) < 10)
108         {
109           repetitions = 100;
110           goto again;
111         }
112     }
113
114   printf ("%s\n", elapsed);
115 }
116
117
118 static void
119 check_openpgp (void)
120 {
121   /* Test vectors manually created with gpg 1.4 derived code: In
122      passphrase.c:hash_passpharse, add this code to the end of the
123      function:
124
125        ===8<===
126        printf ("{\n"
127                "  \"");
128        for (i=0; i < pwlen; i++)
129          {
130            if (i && !(i%16))
131              printf ("\"\n  \"");
132            printf ("\\x%02x", ((const unsigned char *)pw)[i]);
133          }
134        printf ("\", %d,\n", pwlen);
135
136        printf ("  %s, %s,\n",
137                s2k->mode == 0? "GCRY_KDF_SIMPLE_S2K":
138                s2k->mode == 1? "GCRY_KDF_SALTED_S2K":
139                s2k->mode == 3? "GCRY_KDF_ITERSALTED_S2K":"?",
140                s2k->hash_algo == DIGEST_ALGO_MD5   ? "GCRY_MD_MD5" :
141                s2k->hash_algo == DIGEST_ALGO_SHA1  ? "GCRY_MD_SHA1" :
142                s2k->hash_algo == DIGEST_ALGO_RMD160? "GCRY_MD_RMD160" :
143                s2k->hash_algo == DIGEST_ALGO_SHA256? "GCRY_MD_SHA256" :
144                s2k->hash_algo == DIGEST_ALGO_SHA384? "GCRY_MD_SHA384" :
145                s2k->hash_algo == DIGEST_ALGO_SHA512? "GCRY_MD_SHA512" :
146                s2k->hash_algo == DIGEST_ALGO_SHA224? "GCRY_MD_SHA224" : "?");
147
148        if (s2k->mode == 0)
149          printf ("  NULL, 0,\n");
150        else
151          {
152            printf ("  \"");
153            for (i=0; i < 8; i++)
154              printf ("\\x%02x", (unsigned int)s2k->salt[i]);
155            printf ("\", %d,\n", 8);
156          }
157
158        if (s2k->mode == 3)
159          printf ("  %lu,\n", (unsigned long)S2K_DECODE_COUNT(s2k->count));
160        else
161          printf ("  0,\n");
162
163        printf ("  %d,\n", (int)dek->keylen);
164
165        printf ("  \"");
166        for (i=0; i < dek->keylen; i++)
167          {
168            if (i && !(i%16))
169              printf ("\"\n  \"");
170            printf ("\\x%02x", ((unsigned char *)dek->key)[i]);
171          }
172        printf ("\"\n},\n");
173        ===>8===
174
175      Then prepare a file x.inp with utf8 encoding:
176
177        ===8<===
178        0 aes    md5 1024 a
179        0 aes    md5 1024 ab
180        0 aes    md5 1024 abc
181        0 aes    md5 1024 abcd
182        0 aes    md5 1024 abcde
183        0 aes    md5 1024 abcdef
184        0 aes    md5 1024 abcdefg
185        0 aes    md5 1024 abcdefgh
186        0 aes    md5 1024 abcdefghi
187        0 aes    md5 1024 abcdefghijklmno
188        0 aes    md5 1024 abcdefghijklmnop
189        0 aes    md5 1024 abcdefghijklmnopq
190        0 aes    md5 1024 Long_sentence_used_as_passphrase
191        0 aes    md5 1024 With_utf8_umlauts:äüÖß
192        0 aes    sha1 1024 a
193        0 aes    sha1 1024 ab
194        0 aes    sha1 1024 abc
195        0 aes    sha1 1024 abcd
196        0 aes    sha1 1024 abcde
197        0 aes    sha1 1024 abcdef
198        0 aes    sha1 1024 abcdefg
199        0 aes    sha1 1024 abcdefgh
200        0 aes    sha1 1024 abcdefghi
201        0 aes    sha1 1024 abcdefghijklmno
202        0 aes    sha1 1024 abcdefghijklmnop
203        0 aes    sha1 1024 abcdefghijklmnopq
204        0 aes    sha1 1024 abcdefghijklmnopqr
205        0 aes    sha1 1024 abcdefghijklmnopqrs
206        0 aes    sha1 1024 abcdefghijklmnopqrst
207        0 aes    sha1 1024 abcdefghijklmnopqrstu
208        0 aes    sha1 1024 Long_sentence_used_as_passphrase
209        0 aes256 sha1 1024 Long_sentence_used_as_passphrase
210        0 aes    sha1 1024 With_utf8_umlauts:äüÖß
211        3 aes    sha1 1024 a
212        3 aes    sha1 1024 ab
213        3 aes    sha1 1024 abc
214        3 aes    sha1 1024 abcd
215        3 aes    sha1 1024 abcde
216        3 aes    sha1 1024 abcdef
217        3 aes    sha1 1024 abcdefg
218        3 aes    sha1 1024 abcdefgh
219        3 aes    sha1 1024 abcdefghi
220        3 aes    sha1 1024 abcdefghijklmno
221        3 aes    sha1 1024 abcdefghijklmnop
222        3 aes    sha1 1024 abcdefghijklmnopq
223        3 aes    sha1 1024 abcdefghijklmnopqr
224        3 aes    sha1 1024 abcdefghijklmnopqrs
225        3 aes    sha1 1024 abcdefghijklmnopqrst
226        3 aes    sha1 1024 abcdefghijklmnopqrstu
227        3 aes    sha1 1024 With_utf8_umlauts:äüÖß
228        3 aes    sha1 1024 Long_sentence_used_as_passphrase
229        3 aes    sha1 10240 Long_sentence_used_as_passphrase
230        3 aes    sha1 102400 Long_sentence_used_as_passphrase
231        3 aes192 sha1 1024 a
232        3 aes192 sha1 1024 abcdefg
233        3 aes192 sha1 1024 abcdefghi
234        3 aes192 sha1 1024 abcdefghi
235        3 aes192 sha1 1024 Long_sentence_used_as_passphrase
236        3 aes256 sha1 1024 a
237        3 aes256 sha1 1024 abcdefg
238        3 aes256 sha1 1024 abcdefghi
239        3 aes256 sha1 1024 abcdefghi
240        3 aes256 sha1 1024 Long_sentence_used_as_passphrase
241        0 aes    sha256 1024 Long_sentence_used_as_passphrase
242        1 aes    sha256 1024 Long_sentence_used_as_passphrase
243        3 aes    sha256 1024 Long_sentence_used_as_passphrase
244        3 aes    sha256 10240 Long_sentence_used_as_passphrase
245        3 aes    sha384 1024 Long_sentence_used_as_passphrase
246        3 aes    sha512 1024 Long_sentence_used_as_passphrase
247        3 aes256 sha512 1024 Long_sentence_used_as_passphrase
248        3 3des   sha512 1024 Long_sentence_used_as_passphrase
249        ===>8===
250
251     and finally using a proper utf-8 enabled shell, run:
252
253        cat x.inp | while read mode cipher digest count pass dummy; do \
254          ./gpg </dev/null -o /dev/null -c  --passphrase "$pass" \
255            --s2k-mode $mode --s2k-digest $digest --s2k-count $count \
256            --cipher-algo $cipher ; done >x.out
257   */
258   static struct {
259     const char *p;   /* Passphrase.  */
260     size_t plen;     /* Length of P. */
261     int algo;
262     int hashalgo;
263     const char *salt;
264     size_t saltlen;
265     unsigned long c; /* Iterations.  */
266     int dklen;       /* Requested key length.  */
267     const char *dk;  /* Derived key.  */
268     int disabled;
269   } tv[] = {
270     {
271       "\x61", 1,
272       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
273       NULL, 0,
274       0,
275       16,
276       "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61"
277     },
278     {
279       "\x61\x62", 2,
280       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
281       NULL, 0,
282       0,
283       16,
284       "\x18\x7e\xf4\x43\x61\x22\xd1\xcc\x2f\x40\xdc\x2b\x92\xf0\xeb\xa0"
285     },
286     {
287       "\x61\x62\x63", 3,
288       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
289       NULL, 0,
290       0,
291       16,
292       "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72"
293     },
294     {
295       "\x61\x62\x63\x64", 4,
296       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
297       NULL, 0,
298       0,
299       16,
300       "\xe2\xfc\x71\x4c\x47\x27\xee\x93\x95\xf3\x24\xcd\x2e\x7f\x33\x1f"
301     },
302     {
303       "\x61\x62\x63\x64\x65", 5,
304       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
305       NULL, 0,
306       0,
307       16,
308       "\xab\x56\xb4\xd9\x2b\x40\x71\x3a\xcc\x5a\xf8\x99\x85\xd4\xb7\x86"
309     },
310     {
311       "\x61\x62\x63\x64\x65\x66", 6,
312       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
313       NULL, 0,
314       0,
315       16,
316       "\xe8\x0b\x50\x17\x09\x89\x50\xfc\x58\xaa\xd8\x3c\x8c\x14\x97\x8e"
317     },
318     {
319       "\x61\x62\x63\x64\x65\x66\x67", 7,
320       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
321       NULL, 0,
322       0,
323       16,
324       "\x7a\xc6\x6c\x0f\x14\x8d\xe9\x51\x9b\x8b\xd2\x64\x31\x2c\x4d\x64"
325     },
326     {
327       "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
328       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
329       NULL, 0,
330       0,
331       16,
332       "\xe8\xdc\x40\x81\xb1\x34\x34\xb4\x51\x89\xa7\x20\xb7\x7b\x68\x18"
333     },
334     {
335       "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
336       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
337       NULL, 0,
338       0,
339       16,
340       "\x8a\xa9\x9b\x1f\x43\x9f\xf7\x12\x93\xe9\x53\x57\xba\xc6\xfd\x94"
341     },
342     {
343       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
344       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
345       NULL, 0,
346       0,
347       16,
348       "\x8a\x73\x19\xdb\xf6\x54\x4a\x74\x22\xc9\xe2\x54\x52\x58\x0e\xa5"
349     },
350     {
351       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
352       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
353       NULL, 0,
354       0,
355       16,
356       "\x1d\x64\xdc\xe2\x39\xc4\x43\x7b\x77\x36\x04\x1d\xb0\x89\xe1\xb9"
357     },
358     {
359       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
360       "\x71", 17,
361       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
362       NULL, 0,
363       0,
364       16,
365       "\x9a\x8d\x98\x45\xa6\xb4\xd8\x2d\xfc\xb2\xc2\xe3\x51\x62\xc8\x30"
366     },
367     {
368       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
369       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
370       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
371       NULL, 0,
372       0,
373       16,
374       "\x35\x2a\xf0\xfc\xdf\xe9\xbb\x62\x16\xfc\x99\x9d\x8d\x58\x05\xcb"
375     },
376     {
377       "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
378       "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
379       GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
380       NULL, 0,
381       0,
382       16,
383       "\x21\xa4\xeb\xd8\xfd\xf0\x59\x25\xd1\x32\x31\xdb\xe7\xf2\x13\x5d"
384     },
385     {
386       "\x61", 1,
387       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
388       NULL, 0,
389       0,
390       16,
391       "\x86\xf7\xe4\x37\xfa\xa5\xa7\xfc\xe1\x5d\x1d\xdc\xb9\xea\xea\xea"
392     },
393     {
394       "\x61\x62", 2,
395       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
396       NULL, 0,
397       0,
398       16,
399       "\xda\x23\x61\x4e\x02\x46\x9a\x0d\x7c\x7b\xd1\xbd\xab\x5c\x9c\x47"
400     },
401     {
402       "\x61\x62\x63", 3,
403       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
404       NULL, 0,
405       0,
406       16,
407       "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c"
408     },
409     {
410       "\x61\x62\x63\x64", 4,
411       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
412       NULL, 0,
413       0,
414       16,
415       "\x81\xfe\x8b\xfe\x87\x57\x6c\x3e\xcb\x22\x42\x6f\x8e\x57\x84\x73"
416     },
417     {
418       "\x61\x62\x63\x64\x65", 5,
419       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
420       NULL, 0,
421       0,
422       16,
423       "\x03\xde\x6c\x57\x0b\xfe\x24\xbf\xc3\x28\xcc\xd7\xca\x46\xb7\x6e"
424     },
425     {
426       "\x61\x62\x63\x64\x65\x66", 6,
427       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
428       NULL, 0,
429       0,
430       16,
431       "\x1f\x8a\xc1\x0f\x23\xc5\xb5\xbc\x11\x67\xbd\xa8\x4b\x83\x3e\x5c"
432     },
433     {
434       "\x61\x62\x63\x64\x65\x66\x67", 7,
435       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
436       NULL, 0,
437       0,
438       16,
439       "\x2f\xb5\xe1\x34\x19\xfc\x89\x24\x68\x65\xe7\xa3\x24\xf4\x76\xec"
440     },
441     {
442       "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
443       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
444       NULL, 0,
445       0,
446       16,
447       "\x42\x5a\xf1\x2a\x07\x43\x50\x2b\x32\x2e\x93\xa0\x15\xbc\xf8\x68"
448     },
449     {
450       "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
451       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
452       NULL, 0,
453       0,
454       16,
455       "\xc6\x3b\x19\xf1\xe4\xc8\xb5\xf7\x6b\x25\xc4\x9b\x8b\x87\xf5\x7d"
456     },
457     {
458       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
459       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
460       NULL, 0,
461       0,
462       16,
463       "\x29\x38\xdc\xc2\xe3\xaa\x77\x98\x7c\x7e\x5d\x4a\x0f\x26\x96\x67"
464     },
465     {
466       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
467       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
468       NULL, 0,
469       0,
470       16,
471       "\x14\xf3\x99\x52\x88\xac\xd1\x89\xe6\xe5\x0a\x7a\xf4\x7e\xe7\x09"
472     },
473     {
474       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
475       "\x71", 17,
476       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
477       NULL, 0,
478       0,
479       16,
480       "\xd8\x3d\x62\x1f\xcd\x2d\x4d\x29\x85\x54\x70\x43\xa7\xa5\xfd\x4d"
481     },
482     {
483       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
484       "\x71\x72", 18,
485       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
486       NULL, 0,
487       0,
488       16,
489       "\xe3\x81\xfe\x42\xc5\x7e\x48\xa0\x82\x17\x86\x41\xef\xfd\x1c\xb9"
490     },
491     {
492       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
493       "\x71\x72\x73", 19,
494       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
495       NULL, 0,
496       0,
497       16,
498       "\x89\x3e\x69\xff\x01\x09\xf3\x45\x9c\x42\x43\x01\x3b\x3d\xe8\xb1"
499     },
500     {
501       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
502       "\x71\x72\x73\x74", 20,
503       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
504       NULL, 0,
505       0,
506       16,
507       "\x14\xa2\x3a\xd7\x0f\x2a\x5d\xd7\x25\x57\x5d\xe6\xc4\x3e\x1c\xdd"
508     },
509     {
510       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
511       "\x71\x72\x73\x74\x75", 21,
512       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
513       NULL, 0,
514       0,
515       16,
516       "\xec\xa9\x86\xb9\x5d\x58\x7f\x34\xd7\x1c\xa7\x75\x2a\x4e\x00\x10"
517     },
518     {
519       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
520       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
521       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
522       NULL, 0,
523       0,
524       16,
525       "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f"
526     },
527     {
528       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
529       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
530       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
531       NULL, 0,
532       0,
533       32,
534       "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f"
535       "\xc3\x7b\x3a\xb2\xef\x4d\x68\xaa\x9c\xd7\xe4\x88\xee\xd1\x5e\x70"
536     },
537     {
538       "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
539       "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
540       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
541       NULL, 0,
542       0,
543       16,
544       "\xe0\x4e\x1e\xe3\xad\x0b\x49\x7c\x7a\x5f\x37\x3b\x4d\x90\x3c\x2e"
545     },
546     {
547       "\x61", 1,
548       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
549       "\x6d\x47\xe3\x68\x5d\x2c\x36\x16", 8,
550       1024,
551       16,
552       "\x41\x9f\x48\x6e\xbf\xe6\xdd\x05\x9a\x72\x23\x17\x44\xd8\xd3\xf3"
553     },
554     {
555       "\x61\x62", 2,
556       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
557       "\x7c\x34\x78\xfb\x28\x2d\x25\xc7", 8,
558       1024,
559       16,
560       "\x0a\x9d\x09\x06\x43\x3d\x4f\xf9\x87\xd6\xf7\x48\x90\xde\xd1\x1c"
561     },
562     {
563       "\x61\x62\x63", 3,
564       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
565       "\xc3\x16\x37\x2e\x27\xf6\x9f\x6f", 8,
566       1024,
567       16,
568       "\xf8\x27\xa0\x07\xc6\xcb\xdd\xf1\xfe\x5c\x88\x3a\xfc\xcd\x84\x4d"
569     },
570     {
571       "\x61\x62\x63\x64", 4,
572       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
573       "\xf0\x0c\x73\x38\xb7\xc3\xd5\x14", 8,
574       1024,
575       16,
576       "\x9b\x5f\x26\xba\x52\x3b\xcd\xd9\xa5\x2a\xef\x3c\x03\x4d\xd1\x52"
577     },
578     {
579       "\x61\x62\x63\x64\x65", 5,
580       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
581       "\xe1\x7d\xa2\x36\x09\x59\xee\xc5", 8,
582       1024,
583       16,
584       "\x94\x9d\x5b\x1a\x5a\x66\x8c\xfa\x8f\x6f\x22\xaf\x8b\x60\x9f\xaf"
585     },
586     {
587       "\x61\x62\x63\x64\x65\x66", 6,
588       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
589       "\xaf\xa7\x0c\x68\xdf\x7e\xaa\x27", 8,
590       1024,
591       16,
592       "\xe5\x38\xf4\x39\x62\x27\xcd\xcc\x91\x37\x7f\x1b\xdc\x58\x64\x27"
593     },
594     {
595       "\x61\x62\x63\x64\x65\x66\x67", 7,
596       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
597       "\x40\x57\xb2\x9d\x5f\xbb\x11\x4f", 8,
598       1024,
599       16,
600       "\xad\xa2\x33\xd9\xdd\xe0\xfb\x94\x8e\xcc\xec\xcc\xb3\xa8\x3a\x9e"
601     },
602     {
603       "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
604       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
605       "\x38\xf5\x65\xc5\x0f\x8c\x19\x61", 8,
606       1024,
607       16,
608       "\xa0\xb0\x3e\x29\x76\xe6\x8f\xa0\xd8\x34\x8f\xa4\x2d\xfd\x65\xee"
609     },
610     {
611       "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
612       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
613       "\xc3\xb7\x99\xcc\xda\x2d\x05\x7b", 8,
614       1024,
615       16,
616       "\x27\x21\xc8\x99\x5f\xcf\x20\xeb\xf2\xd9\xff\x6a\x69\xff\xad\xe8"
617     },
618     {
619       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
620       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
621       "\x7d\xd8\x68\x8a\x1c\xc5\x47\x22", 8,
622       1024,
623       16,
624       "\x0f\x96\x7a\x12\x23\x54\xf6\x92\x61\x67\x07\xb4\x68\x17\xb8\xaa"
625     },
626     {
627       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
628       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
629       "\x8a\x95\xd4\x88\x0b\xb8\xe9\x9d", 8,
630       1024,
631       16,
632       "\xcc\xe4\xc8\x82\x53\x32\xf1\x93\x5a\x00\xd4\x7f\xd4\x46\xfa\x07"
633     },
634     {
635       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
636       "\x71", 17,
637       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
638       "\xb5\x22\x48\xa6\xc4\xad\x74\x67", 8,
639       1024,
640       16,
641       "\x0c\xe3\xe0\xee\x3d\x8f\x35\xd2\x35\x14\x14\x29\x0c\xf1\xe3\x34"
642     },
643     {
644       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
645       "\x71\x72", 18,
646       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
647       "\xac\x9f\x04\x63\x83\x0e\x3c\x95", 8,
648       1024,
649       16,
650       "\x49\x0a\x04\x68\xa8\x2a\x43\x6f\xb9\x73\x94\xb4\x85\x9a\xaa\x0e"
651     },
652     {
653       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
654       "\x71\x72\x73", 19,
655       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
656       "\x03\x6f\x60\x30\x3a\x19\x61\x0d", 8,
657       1024,
658       16,
659       "\x15\xe5\x9b\xbf\x1c\xf0\xbe\x74\x95\x1a\xb2\xc4\xda\x09\xcd\x99"
660     },
661     {
662       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
663       "\x71\x72\x73\x74", 20,
664       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
665       "\x51\x40\xa5\x57\xf5\x28\xfd\x03", 8,
666       1024,
667       16,
668       "\xa6\xf2\x7e\x6b\x30\x4d\x8d\x67\xd4\xa2\x7f\xa2\x57\x27\xab\x96"
669     },
670     {
671       "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
672       "\x71\x72\x73\x74\x75", 21,
673       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
674       "\x4c\xf1\x10\x11\x04\x70\xd3\x6e", 8,
675       1024,
676       16,
677       "\x2c\x50\x79\x8d\x83\x23\xac\xd6\x22\x29\x37\xaf\x15\x0d\xdd\x8f"
678     },
679     {
680       "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
681       "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
682       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
683       "\xfe\x3a\x25\xcb\x78\xef\xe1\x21", 8,
684       1024,
685       16,
686       "\x2a\xb0\x53\x08\xf3\x2f\xd4\x6e\xeb\x01\x49\x5d\x87\xf6\x27\xf6"
687     },
688     {
689       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
690       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
691       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
692       "\x04\x97\xd0\x02\x6a\x44\x2d\xde", 8,
693       1024,
694       16,
695       "\x57\xf5\x70\x41\xa0\x9b\x8c\x09\xca\x74\xa9\x22\xa5\x82\x2d\x17"
696     },
697     {
698       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
699       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
700       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
701       "\xdd\xf3\x31\x7c\xce\xf4\x81\x26", 8,
702       10240,
703       16,
704       "\xc3\xdd\x01\x6d\xaf\xf6\x58\xc8\xd7\x79\xb4\x40\x00\xb5\xe8\x0b"
705     },
706     {
707       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
708       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
709       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
710       "\x95\xd6\x72\x4e\xfb\xe1\xc3\x1a", 8,
711       102400,
712       16,
713       "\xf2\x3f\x36\x7f\xb4\x6a\xd0\x3a\x31\x9e\x65\x11\x8e\x2b\x99\x9b"
714     },
715     {
716       "\x61", 1,
717       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
718       "\x6d\x69\x15\x18\xe4\x13\x42\x82", 8,
719       1024,
720       24,
721       "\x28\x0c\x7e\xf2\x31\xf6\x1c\x6b\x5c\xef\x6a\xd5\x22\x64\x97\x91"
722       "\xe3\x5e\x37\xfd\x50\xe2\xfc\x6c"
723     },
724     {
725       "\x61\x62\x63\x64\x65\x66\x67", 7,
726       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
727       "\x9b\x76\x5e\x81\xde\x13\xdf\x15", 8,
728       1024,
729       24,
730       "\x91\x1b\xa1\xc1\x7b\x4f\xc3\xb1\x80\x61\x26\x08\xbe\x53\xe6\x50"
731       "\x40\x6f\x28\xed\xc6\xe6\x67\x55"
732     },
733     {
734       "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
735       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
736       "\x7a\xac\xcc\x6e\x15\x56\xbd\xa1", 8,
737       1024,
738       24,
739       "\xfa\x7e\x20\x07\xb6\x47\xb0\x09\x46\xb8\x38\xfb\xa1\xaf\xf7\x75"
740       "\x2a\xfa\x77\x14\x06\x54\xcb\x34"
741     },
742     {
743       "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
744       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
745       "\x1c\x68\xf8\xfb\x98\xf7\x8c\x39", 8,
746       1024,
747       24,
748       "\xcb\x1e\x86\xf5\xe0\xe4\xfb\xbf\x71\x34\x99\x24\xf4\x39\x8c\xc2"
749       "\x8e\x25\x1c\x4c\x96\x47\x22\xe8"
750     },
751     {
752       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
753       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
754       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
755       "\x10\xa9\x4e\xc1\xa5\xec\x17\x52", 8,
756       1024,
757       24,
758       "\x0f\x83\xa2\x77\x92\xbb\xe4\x58\x68\xc5\xf2\x14\x6e\x6e\x2e\x6b"
759       "\x98\x17\x70\x92\x07\x44\xe0\x51"
760     },
761     {
762       "\x61", 1,
763       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
764       "\xef\x8f\x37\x61\x8f\xab\xae\x4f", 8,
765       1024,
766       32,
767       "\x6d\x65\xae\x86\x23\x91\x39\x98\xec\x1c\x23\x44\xb6\x0d\xad\x32"
768       "\x54\x46\xc7\x23\x26\xbb\xdf\x4b\x54\x6e\xd4\xc2\xfa\xc6\x17\x17"
769     },
770     {
771       "\x61\x62\x63\x64\x65\x66\x67", 7,
772       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
773       "\xaa\xfb\xd9\x06\x7d\x7c\x40\xaf", 8,
774       1024,
775       32,
776       "\x7d\x10\x54\x13\x3c\x43\x7a\xb3\x54\x1f\x38\xd4\x8f\x70\x0a\x09"
777       "\xe2\xfa\xab\x97\x9a\x70\x16\xef\x66\x68\xca\x34\x2e\xce\xfa\x1f"
778     },
779     {
780       "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
781       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
782       "\x58\x03\x4f\x56\x8b\x97\xd4\x98", 8,
783       1024,
784       32,
785       "\xf7\x40\xb1\x25\x86\x0d\x35\x8f\x9f\x91\x2d\xce\x04\xee\x5a\x04"
786       "\x9d\xbd\x44\x23\x4c\xa6\xbb\xab\xb0\xd0\x56\x82\xa9\xda\x47\x16"
787     },
788     {
789       "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
790       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
791       "\x5d\x41\x3d\xa3\xa7\xfc\x5d\x0c", 8,
792       1024,
793       32,
794       "\x4c\x7a\x86\xed\x81\x8a\x94\x99\x7d\x4a\xc4\xf7\x1c\xf8\x08\xdb"
795       "\x09\x35\xd9\xa3\x2d\x22\xde\x32\x2d\x74\x38\xe5\xc8\xf2\x50\x6e"
796     },
797     {
798       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
799       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
800       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
801       "\xca\xa7\xdc\x59\xce\x31\xe7\x49", 8,
802       1024,
803       32,
804       "\x67\xe9\xd6\x29\x49\x1c\xb6\xa0\x85\xe8\xf9\x8b\x85\x47\x3a\x7e"
805       "\xa7\xee\x89\x52\x6f\x19\x00\x53\x93\x07\x0a\x8b\xb9\xa8\x86\x94"
806     },
807     {
808       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
809       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
810       GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA256,
811       NULL, 0,
812       0,
813       16,
814       "\x88\x36\x78\x6b\xd9\x5a\x62\xff\x47\xd3\xfb\x79\xc9\x08\x70\x56"
815     },
816     {
817       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
818       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
819       GCRY_KDF_SALTED_S2K, GCRY_MD_SHA256,
820       "\x05\x8b\xfe\x31\xaa\xf3\x29\x11", 8,
821       0,
822       16,
823       "\xb2\x42\xfe\x5e\x09\x02\xd9\x62\xb9\x35\xf3\xa8\x43\x80\x9f\xb1"
824     },
825     {
826       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
827       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
828       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256,
829       "\xd3\x4a\xea\xc9\x97\x1b\xcc\x83", 8,
830       1024,
831       16,
832       "\x35\x37\x99\x62\x07\x26\x68\x23\x05\x47\xb2\xa0\x0b\x2b\x2b\x8d"
833     },
834     {
835       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
836       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
837       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256,
838       "\x5e\x71\xbd\x00\x5f\x96\xc4\x23", 8,
839       10240,
840       16,
841       "\xa1\x6a\xee\xba\xde\x73\x25\x25\xd1\xab\xa0\xc5\x7e\xc6\x39\xa7"
842     },
843     {
844       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
845       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
846       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA384,
847       "\xc3\x08\xeb\x17\x62\x08\x89\xef", 8,
848       1024,
849       16,
850       "\x9b\x7f\x0c\x81\x6f\x71\x59\x9b\xd5\xf6\xbf\x3a\x86\x20\x16\x33"
851     },
852     {
853       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
854       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
855       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
856       "\xe6\x7d\x13\x6b\x39\xe3\x44\x05", 8,
857       1024,
858       16,
859       "\xc8\xcd\x4b\xa4\xf3\xf1\xd5\xb0\x59\x06\xf0\xbb\x89\x34\x6a\xad"
860     },
861     {
862       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
863       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
864       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
865       "\xed\x7d\x30\x47\xe4\xc3\xf8\xb6", 8,
866       1024,
867       32,
868       "\x89\x7a\xef\x70\x97\xe7\x10\xdb\x75\xcc\x20\x22\xab\x7b\xf3\x05"
869       "\x4b\xb6\x2e\x17\x11\x9f\xd6\xeb\xbf\xdf\x4d\x70\x59\xf0\xf9\xe5"
870     },
871     {
872       "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
873       "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
874       GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
875       "\xbb\x1a\x45\x30\x68\x62\x6d\x63", 8,
876       1024,
877       24,
878       "\xde\x5c\xb8\xd5\x75\xf6\xad\x69\x5b\xc9\xf6\x2f\xba\xeb\xfb\x36"
879       "\x34\xf2\xb8\xee\x3b\x37\x21\xb7"
880     }
881   };
882   int tvidx;
883   gpg_error_t err;
884   unsigned char outbuf[32];
885   int i;
886
887   for (tvidx=0; tvidx < DIM(tv); tvidx++)
888     {
889       if (tv[tvidx].disabled)
890         continue;
891       if (verbose)
892         fprintf (stderr, "checking S2K test vector %d\n", tvidx);
893       assert (tv[tvidx].dklen <= sizeof outbuf);
894       err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
895                              tv[tvidx].algo, tv[tvidx].hashalgo,
896                              tv[tvidx].salt, tv[tvidx].saltlen,
897                              tv[tvidx].c, tv[tvidx].dklen, outbuf);
898       if (err)
899         fail ("s2k test %d failed: %s\n", tvidx, gpg_strerror (err));
900       else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
901         {
902           fail ("s2k test %d failed: mismatch\n", tvidx);
903           fputs ("got:", stderr);
904           for (i=0; i < tv[tvidx].dklen; i++)
905             fprintf (stderr, " %02x", outbuf[i]);
906           putc ('\n', stderr);
907         }
908     }
909 }
910
911
912 static void
913 check_pbkdf2 (void)
914 {
915   /* Test vectors are from RFC-6070.  */
916   static struct {
917     const char *p;   /* Passphrase.  */
918     size_t plen;     /* Length of P. */
919     const char *salt;
920     size_t saltlen;
921     int hashalgo;
922     unsigned long c; /* Iterations.  */
923     int dklen;       /* Requested key length.  */
924     const char *dk;  /* Derived key.  */
925     int disabled;
926   } tv[] = {
927     {
928       "password", 8,
929       "salt", 4,
930       GCRY_MD_SHA1,
931       1,
932       20,
933       "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
934       "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"
935     },
936     {
937       "password", 8,
938       "salt", 4,
939       GCRY_MD_SHA1,
940       2,
941       20,
942       "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
943       "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"
944     },
945     {
946       "password", 8,
947       "salt", 4,
948       GCRY_MD_SHA1,
949       4096,
950       20,
951       "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
952       "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1"
953     },
954     {
955       "password", 8,
956       "salt", 4,
957       GCRY_MD_SHA1,
958       16777216,
959       20,
960       "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
961       "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84",
962       1 /* This test takes too long.  */
963     },
964     {
965       "passwordPASSWORDpassword", 24,
966       "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
967       GCRY_MD_SHA1,
968       4096,
969       25,
970       "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8"
971       "\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96"
972       "\x4c\xf2\xf0\x70\x38"
973     },
974     {
975       "pass\0word", 9,
976       "sa\0lt", 5,
977       GCRY_MD_SHA1,
978       4096,
979       16,
980       "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37"
981       "\xd7\xf0\x34\x25\xe0\xc3"
982     },
983     { /* empty password test, not in RFC-6070 */
984       "", 0,
985       "salt", 4,
986       GCRY_MD_SHA1,
987       2,
988       20,
989       "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2"
990       "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97"
991     },
992     {
993       "password", 8,
994       "salt", 4,
995       GCRY_MD_GOSTR3411_CP,
996       1,
997       32,
998       "\x73\x14\xe7\xc0\x4f\xb2\xe6\x62\xc5\x43\x67\x42\x53\xf6\x8b\xd0"
999       "\xb7\x34\x45\xd0\x7f\x24\x1b\xed\x87\x28\x82\xda\x21\x66\x2d\x58"
1000     },
1001     {
1002       "password", 8,
1003       "salt", 4,
1004       GCRY_MD_GOSTR3411_CP,
1005       2,
1006       32,
1007       "\x99\x0d\xfa\x2b\xd9\x65\x63\x9b\xa4\x8b\x07\xb7\x92\x77\x5d\xf7"
1008       "\x9f\x2d\xb3\x4f\xef\x25\xf2\x74\x37\x88\x72\xfe\xd7\xed\x1b\xb3"
1009     },
1010     {
1011       "password", 8,
1012       "salt", 4,
1013       GCRY_MD_GOSTR3411_CP,
1014       4096,
1015       32,
1016       "\x1f\x18\x29\xa9\x4b\xdf\xf5\xbe\x10\xd0\xae\xb3\x6a\xf4\x98\xe7"
1017       "\xa9\x74\x67\xf3\xb3\x11\x16\xa5\xa7\xc1\xaf\xff\x9d\xea\xda\xfe"
1018     },
1019     /* { -- takes too long (4-5 min) to calculate
1020       "password", 8,
1021       "salt", 4,
1022       GCRY_MD_GOSTR3411_CP,
1023       16777216,
1024       32,
1025       "\xa5\x7a\xe5\xa6\x08\x83\x96\xd1\x20\x85\x0c\x5c\x09\xde\x0a\x52"
1026       "\x51\x00\x93\x8a\x59\xb1\xb5\xc3\xf7\x81\x09\x10\xd0\x5f\xcd\x97"
1027     }, */
1028     {
1029       "passwordPASSWORDpassword", 24,
1030       "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
1031       GCRY_MD_GOSTR3411_CP,
1032       4096,
1033       40,
1034       "\x78\x83\x58\xc6\x9c\xb2\xdb\xe2\x51\xa7\xbb\x17\xd5\xf4\x24\x1f"
1035       "\x26\x5a\x79\x2a\x35\xbe\xcd\xe8\xd5\x6f\x32\x6b\x49\xc8\x50\x47"
1036       "\xb7\x63\x8a\xcb\x47\x64\xb1\xfd"
1037     },
1038     {
1039       "pass\0word", 9,
1040       "sa\0lt", 5,
1041       GCRY_MD_GOSTR3411_CP,
1042       4096,
1043       20,
1044       "\x43\xe0\x6c\x55\x90\xb0\x8c\x02\x25\x24"
1045       "\x23\x73\x12\x7e\xdf\x9c\x8e\x9c\x32\x91"
1046     }
1047   };
1048   int tvidx;
1049   gpg_error_t err;
1050   unsigned char outbuf[40];
1051   int i;
1052
1053   for (tvidx=0; tvidx < DIM(tv); tvidx++)
1054     {
1055       if (tv[tvidx].disabled)
1056         continue;
1057       if (verbose)
1058         fprintf (stderr, "checking PBKDF2 test vector %d algo %d\n", tvidx,
1059                  tv[tvidx].hashalgo);
1060       assert (tv[tvidx].dklen <= sizeof outbuf);
1061       err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
1062                              GCRY_KDF_PBKDF2, tv[tvidx].hashalgo,
1063                              tv[tvidx].salt, tv[tvidx].saltlen,
1064                              tv[tvidx].c, tv[tvidx].dklen, outbuf);
1065       if (err)
1066         fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err));
1067       else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
1068         {
1069           fail ("pbkdf2 test %d failed: mismatch\n", tvidx);
1070           fputs ("got:", stderr);
1071           for (i=0; i < tv[tvidx].dklen; i++)
1072             fprintf (stderr, " %02x", outbuf[i]);
1073           putc ('\n', stderr);
1074         }
1075     }
1076 }
1077
1078
1079 static void
1080 check_scrypt (void)
1081 {
1082   /* Test vectors are from draft-josefsson-scrypt-kdf-01.  */
1083   static struct {
1084     const char *p;        /* Passphrase.  */
1085     size_t plen;          /* Length of P. */
1086     const char *salt;
1087     size_t saltlen;
1088     int parm_n;           /* CPU/memory cost.  */
1089     int parm_r;           /* blocksize */
1090     unsigned long parm_p; /* parallelization. */
1091     int dklen;            /* Requested key length.  */
1092     const char *dk;       /* Derived key.  */
1093     int disabled;
1094   } tv[] = {
1095     {
1096       "", 0,
1097       "", 0,
1098       16,
1099       1,
1100       1,
1101       64,
1102       "\x77\xd6\x57\x62\x38\x65\x7b\x20\x3b\x19\xca\x42\xc1\x8a\x04\x97"
1103       "\xf1\x6b\x48\x44\xe3\x07\x4a\xe8\xdf\xdf\xfa\x3f\xed\xe2\x14\x42"
1104       "\xfc\xd0\x06\x9d\xed\x09\x48\xf8\x32\x6a\x75\x3a\x0f\xc8\x1f\x17"
1105       "\xe8\xd3\xe0\xfb\x2e\x0d\x36\x28\xcf\x35\xe2\x0c\x38\xd1\x89\x06"
1106     },
1107     {
1108       "password", 8,
1109       "NaCl", 4,
1110       1024,
1111       8,
1112       16,
1113       64,
1114       "\xfd\xba\xbe\x1c\x9d\x34\x72\x00\x78\x56\xe7\x19\x0d\x01\xe9\xfe"
1115       "\x7c\x6a\xd7\xcb\xc8\x23\x78\x30\xe7\x73\x76\x63\x4b\x37\x31\x62"
1116       "\x2e\xaf\x30\xd9\x2e\x22\xa3\x88\x6f\xf1\x09\x27\x9d\x98\x30\xda"
1117       "\xc7\x27\xaf\xb9\x4a\x83\xee\x6d\x83\x60\xcb\xdf\xa2\xcc\x06\x40"
1118     },
1119     {
1120       "pleaseletmein", 13,
1121       "SodiumChloride", 14,
1122       16384,
1123       8,
1124       1,
1125       64,
1126       "\x70\x23\xbd\xcb\x3a\xfd\x73\x48\x46\x1c\x06\xcd\x81\xfd\x38\xeb"
1127       "\xfd\xa8\xfb\xba\x90\x4f\x8e\x3e\xa9\xb5\x43\xf6\x54\x5d\xa1\xf2"
1128       "\xd5\x43\x29\x55\x61\x3f\x0f\xcf\x62\xd4\x97\x05\x24\x2a\x9a\xf9"
1129       "\xe6\x1e\x85\xdc\x0d\x65\x1e\x40\xdf\xcf\x01\x7b\x45\x57\x58\x87"
1130     },
1131     {
1132       "pleaseletmein", 13,
1133       "SodiumChloride", 14,
1134       1048576,
1135       8,
1136       1,
1137       64,
1138       "\x21\x01\xcb\x9b\x6a\x51\x1a\xae\xad\xdb\xbe\x09\xcf\x70\xf8\x81"
1139       "\xec\x56\x8d\x57\x4a\x2f\xfd\x4d\xab\xe5\xee\x98\x20\xad\xaa\x47"
1140       "\x8e\x56\xfd\x8f\x4b\xa5\xd0\x9f\xfa\x1c\x6d\x92\x7c\x40\xf4\xc3"
1141       "\x37\x30\x40\x49\xe8\xa9\x52\xfb\xcb\xf4\x5c\x6f\xa7\x7a\x41\xa4",
1142       2 /* Only in debug mode.  */
1143     }
1144   };
1145   int tvidx;
1146   gpg_error_t err;
1147   unsigned char outbuf[64];
1148   int i;
1149
1150   for (tvidx=0; tvidx < DIM(tv); tvidx++)
1151     {
1152       if (tv[tvidx].disabled && !(tv[tvidx].disabled == 2 && debug))
1153         continue;
1154       if (verbose)
1155         fprintf (stderr, "checking SCRYPT test vector %d\n", tvidx);
1156       assert (tv[tvidx].dklen <= sizeof outbuf);
1157       err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
1158                              tv[tvidx].parm_r == 1 ? 41 : GCRY_KDF_SCRYPT,
1159                              tv[tvidx].parm_n,
1160                              tv[tvidx].salt, tv[tvidx].saltlen,
1161                              tv[tvidx].parm_p, tv[tvidx].dklen, outbuf);
1162       if (err)
1163         fail ("scrypt test %d failed: %s\n", tvidx, gpg_strerror (err));
1164       else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
1165         {
1166           fail ("scrypt test %d failed: mismatch\n", tvidx);
1167           fputs ("got:", stderr);
1168           for (i=0; i < tv[tvidx].dklen; i++)
1169             fprintf (stderr, " %02x", outbuf[i]);
1170           putc ('\n', stderr);
1171         }
1172     }
1173 }
1174
1175
1176 int
1177 main (int argc, char **argv)
1178 {
1179   int last_argc = -1;
1180   unsigned long s2kcount = 0;
1181
1182   if (argc)
1183     { argc--; argv++; }
1184
1185   while (argc && last_argc != argc )
1186     {
1187       last_argc = argc;
1188       if (!strcmp (*argv, "--"))
1189         {
1190           argc--; argv++;
1191           break;
1192         }
1193       else if (!strcmp (*argv, "--help"))
1194         {
1195           fputs ("usage: t-kdf [options]"
1196                  "Options:\n"
1197                  " --verbose    print timinigs etc.\n"
1198                  " --debug      flyswatter\n"
1199                  " --s2k        print the time needed for S2K\n",
1200                  stdout);
1201           exit (0);
1202         }
1203       else if (!strcmp (*argv, "--verbose"))
1204         {
1205           verbose++;
1206           argc--; argv++;
1207         }
1208       else if (!strcmp (*argv, "--debug"))
1209         {
1210           verbose += 2;
1211           debug++;
1212           argc--; argv++;
1213         }
1214       else if (!strcmp (*argv, "--s2k"))
1215         {
1216           s2kcount = 1;
1217           argc--; argv++;
1218         }
1219       else if (!strncmp (*argv, "--", 2))
1220         die ("unknown option '%s'\n", *argv);
1221     }
1222
1223   if (s2kcount)
1224     {
1225       if (argc != 1)
1226         die ("usage: t-kdf --s2k S2KCOUNT\n", stderr );
1227       s2kcount = strtoul (*argv, NULL, 10);
1228       if (!s2kcount)
1229         die ("t-kdf: S2KCOUNT must be positive\n", stderr );
1230     }
1231
1232   if (!gcry_check_version (GCRYPT_VERSION))
1233     die ("version mismatch\n");
1234
1235   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1236   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1237   if (debug)
1238     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
1239
1240   if (s2kcount)
1241     bench_s2k (s2kcount);
1242   else
1243     {
1244       check_openpgp ();
1245       check_pbkdf2 ();
1246       check_scrypt ();
1247     }
1248
1249   return error_count ? 1 : 0;
1250 }