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