xref: /freebsd/crypto/krb5/src/lib/crypto/crypto_tests/vectors.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/crypto/crypto_tests/vectors.c */
3 /*
4  * Copyright 2001 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  Furthermore if you modify this software you must label
20  * your software as modified software and not distribute it in such a
21  * fashion that it might be confused with the original M.I.T. software.
22  * M.I.T. makes no representations about the suitability of
23  * this software for any purpose.  It is provided "as is" without express
24  * or implied warranty.
25  */
26 
27 /*
28  * Test vectors for crypto code, matching data submitted for inclusion
29  * with RFC1510bis.
30  *
31  * N.B.: Doesn't compile -- this file uses some routines internal to our
32  * crypto library which are declared "static" and thus aren't accessible
33  * without modifying the other sources.  Additionally, some ciphers have been
34  * removed.
35  */
36 
37 #include <assert.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <ctype.h>
41 #include "crypto_int.h"
42 
43 #define ASIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0]))
44 
45 const char *whoami;
46 
printhex(size_t len,const char * p)47 static void printhex (size_t len, const char *p)
48 {
49     while (len--)
50         printf ("%02x", 0xff & *p++);
51 }
52 
printstringhex(const char * p)53 static void printstringhex (const char *p) { printhex (strlen (p), p); }
54 
printdata(krb5_data * d)55 static void printdata (krb5_data *d) { printhex (d->length, d->data); }
56 
printkey(krb5_keyblock * k)57 static void printkey (krb5_keyblock *k) { printhex (k->length, k->contents); }
58 
test_nfold()59 static void test_nfold ()
60 {
61     int i;
62     static const struct {
63         char *input;
64         int n;
65     } tests[] = {
66         { "012345", 64, },
67         { "password", 56, },
68         { "Rough Consensus, and Running Code", 64, },
69         { "password", 168, },
70         { "MASSACHVSETTS INSTITVTE OF TECHNOLOGY", 192 },
71         { "Q", 168 },
72         { "ba", 168 },
73     };
74     unsigned char outbuf[192/8];
75 
76     for (i = 0; i < ASIZE (tests); i++) {
77         char *p = tests[i].input;
78         assert (tests[i].n / 8 <= sizeof (outbuf));
79         printf ("%d-fold(\"%s\") =\n", tests[i].n, p);
80         printf ("%d-fold(", tests[i].n);
81         printstringhex (p);
82         printf (") =\n\t");
83         krb5int_nfold (8 * strlen (p), p, tests[i].n, outbuf);
84         printhex (tests[i].n / 8U, outbuf);
85         printf ("\n\n");
86     }
87 }
88 
89 #define JURISIC "Juri\305\241i\304\207" /* hi Miro */
90 #define ESZETT "\303\237"
91 #define GCLEF  "\360\235\204\236" /* outside BMP, woo hoo!  */
92 
93 /* Some weak keys:
94    {0x1f,0x1f,0x1f,0x1f,0x0e,0x0e,0x0e,0x0e},
95    {0xe0,0xe0,0xe0,0xe0,0xf1,0xf1,0xf1,0xf1},
96    so try to generate them. */
97 
98 static void
test_mit_des_s2k()99 test_mit_des_s2k ()
100 {
101     static const struct {
102         const char *pass;
103         const char *salt;
104     } pairs[] = {
105         { "password", "ATHENA.MIT.EDUraeburn" },
106         { "potatoe", "WHITEHOUSE.GOVdanny" },
107         { "penny", "EXAMPLE.COMbuckaroo", },
108         { GCLEF, "EXAMPLE.COMpianist" },
109         { ESZETT, "ATHENA.MIT.EDU" JURISIC },
110         /* These two trigger weak-key fixups.  */
111         { "11119999", "AAAAAAAA" },
112         { "NNNN6666", "FFFFAAAA" },
113     };
114     int i;
115 
116     for (i = 0; i < ASIZE (pairs); i++) {
117         const char *p = pairs[i].pass;
118         const char *s = pairs[i].salt;
119         krb5_data pd;
120         krb5_data sd;
121         unsigned char key_contents[60];
122         krb5_keyblock key;
123         krb5_error_code r;
124         char buf[80];
125 
126         key.contents = key_contents;
127 
128         pd.length = strlen (p);
129         pd.data = (char *) p;
130         sd.length = strlen (s);
131         sd.data = (char *) s;
132 
133         assert (strlen (s) + 4 < sizeof (buf));
134         snprintf (buf, sizeof (buf), "\"%s\"", s);
135         printf (  "salt:     %-25s", buf);
136         printhex (strlen(s), s);
137         snprintf (buf, sizeof (buf), "\"%s\"", p);
138         printf ("\npassword: %-25s", buf);
139         printhex (strlen(p), p);
140         printf ("\n");
141         r = krb5int_des_string_to_key (0, &pd, &sd, 0, &key);
142         printf (  "DES key:  %-25s", "");
143         printhex (key.length, key.contents);
144         printf ("\n\n");
145     }
146 }
147 
148 static void
test_s2k(krb5_enctype enctype)149 test_s2k (krb5_enctype enctype)
150 {
151     static const struct {
152         const char *pass;
153         const char *salt;
154     } pairs[] = {
155         { "password", "ATHENA.MIT.EDUraeburn" },
156         { "potatoe", "WHITEHOUSE.GOVdanny" },
157         { "penny", "EXAMPLE.COMbuckaroo", },
158         { ESZETT, "ATHENA.MIT.EDU" JURISIC },
159         { GCLEF, "EXAMPLE.COMpianist" },
160     };
161     int i;
162 
163     for (i = 0; i < ASIZE (pairs); i++) {
164         const char *p = pairs[i].pass;
165         const char *s = pairs[i].salt;
166         krb5_data pd, sd;
167         unsigned char key_contents[60];
168         krb5_keyblock key;
169         krb5_error_code r;
170         char buf[80];
171 
172         pd.length = strlen (p);
173         pd.data = (char *) p;
174         sd.length = strlen (s);
175         sd.data = (char *) s;
176         key.contents = key_contents;
177 
178         assert (strlen (s) + 4 < sizeof (buf));
179         snprintf (buf, sizeof(buf), "\"%s\"", s);
180         printf (  "salt:\t%s\n\t", buf);
181         printhex (strlen(s), s);
182         snprintf (buf, sizeof(buf), "\"%s\"", p);
183         printf ("\npasswd:\t%s\n\t", buf);
184         printhex (strlen(p), p);
185         printf ("\n");
186         r = krb5_c_string_to_key (0, enctype, &pd, &sd, &key);
187         printf (  "key:\t");
188         printhex (key.length, key.contents);
189         printf ("\n\n");
190     }
191 }
192 
test_des3_s2k()193 static void test_des3_s2k () { test_s2k (ENCTYPE_DES3_CBC_SHA1); }
194 
195 static void
keyToData(krb5_keyblock * k,krb5_data * d)196 keyToData (krb5_keyblock *k, krb5_data *d)
197 {
198     d->length = k->length;
199     d->data = k->contents;
200 }
201 
check_error(int r,int line)202 void check_error (int r, int line) {
203     if (r != 0) {
204         fprintf (stderr, "%s:%d: %s\n", __FILE__, line,
205                  error_message (r));
206         exit (1);
207     }
208 }
209 #define CHECK check_error(r, __LINE__)
210 
211 extern struct krb5_enc_provider krb5int_enc_des3;
212 struct krb5_enc_provider *enc = &krb5int_enc_des3;
213 extern struct krb5_enc_provider krb5int_enc_aes128, krb5int_enc_aes256;
214 
DK(krb5_keyblock * out,krb5_keyblock * in,const krb5_data * usage)215 void DK (krb5_keyblock *out, krb5_keyblock *in, const krb5_data *usage) {
216     krb5_error_code r;
217     r = krb5int_derive_key (enc, in, out, usage, DERIVE_RFC3961);
218     CHECK;
219 }
220 
DR(krb5_data * out,krb5_keyblock * in,const krb5_data * usage)221 void DR (krb5_data *out, krb5_keyblock *in, const krb5_data *usage) {
222     krb5_error_code r;
223     r = krb5int_derive_random (enc, in, out, usage, DERIVE_RFC3961);
224     CHECK;
225 }
226 
227 #define KEYBYTES  21
228 #define KEYLENGTH 24
229 
test_dr_dk()230 void test_dr_dk ()
231 {
232     static const struct {
233         unsigned char keydata[KEYLENGTH];
234         int usage_len;
235         unsigned char usage[8];
236     } derive_tests[] = {
237         {
238             {
239                 0xdc, 0xe0, 0x6b, 0x1f, 0x64, 0xc8, 0x57, 0xa1,
240                 0x1c, 0x3d, 0xb5, 0x7c, 0x51, 0x89, 0x9b, 0x2c,
241                 0xc1, 0x79, 0x10, 0x08, 0xce, 0x97, 0x3b, 0x92,
242             },
243             5, { 0x00, 0x00, 0x00, 0x01, 0x55 },
244         },
245         {
246             {
247                 0x5e, 0x13, 0xd3, 0x1c, 0x70, 0xef, 0x76, 0x57,
248                 0x46, 0x57, 0x85, 0x31, 0xcb, 0x51, 0xc1, 0x5b,
249                 0xf1, 0x1c, 0xa8, 0x2c, 0x97, 0xce, 0xe9, 0xf2,
250             },
251             5, { 0x00, 0x00, 0x00, 0x01, 0xaa },
252         },
253         {
254             {
255                 0x98, 0xe6, 0xfd, 0x8a, 0x04, 0xa4, 0xb6, 0x85,
256                 0x9b, 0x75, 0xa1, 0x76, 0x54, 0x0b, 0x97, 0x52,
257                 0xba, 0xd3, 0xec, 0xd6, 0x10, 0xa2, 0x52, 0xbc,
258             },
259             5, { 0x00, 0x00, 0x00, 0x01, 0x55 },
260         },
261         {
262             {
263                 0x62, 0x2a, 0xec, 0x25, 0xa2, 0xfe, 0x2c, 0xad,
264                 0x70, 0x94, 0x68, 0x0b, 0x7c, 0x64, 0x94, 0x02,
265                 0x80, 0x08, 0x4c, 0x1a, 0x7c, 0xec, 0x92, 0xb5,
266             },
267             5, { 0x00, 0x00, 0x00, 0x01, 0xaa },
268         },
269         {
270             {
271                 0xd3, 0xf8, 0x29, 0x8c, 0xcb, 0x16, 0x64, 0x38,
272                 0xdc, 0xb9, 0xb9, 0x3e, 0xe5, 0xa7, 0x62, 0x92,
273                 0x86, 0xa4, 0x91, 0xf8, 0x38, 0xf8, 0x02, 0xfb,
274             },
275             8, { 'k', 'e', 'r', 'b', 'e', 'r', 'o', 's' },
276         },
277         {
278             {
279                 0xb5, 0x5e, 0x98, 0x34, 0x67, 0xe5, 0x51, 0xb3,
280                 0xe5, 0xd0, 0xe5, 0xb6, 0xc8, 0x0d, 0x45, 0x76,
281                 0x94, 0x23, 0xa8, 0x73, 0xdc, 0x62, 0xb3, 0x0e,
282             },
283             7, { 'c', 'o', 'm', 'b', 'i', 'n', 'e', },
284         },
285         {
286             {
287                 0xc1, 0x08, 0x16, 0x49, 0xad, 0xa7, 0x43, 0x62,
288                 0xe6, 0xa1, 0x45, 0x9d, 0x01, 0xdf, 0xd3, 0x0d,
289                 0x67, 0xc2, 0x23, 0x4c, 0x94, 0x07, 0x04, 0xda,
290             },
291             5, { 0x00, 0x00, 0x00, 0x01, 0x55 },
292         },
293         {
294             {
295                 0x5d, 0x15, 0x4a, 0xf2, 0x38, 0xf4, 0x67, 0x13,
296                 0x15, 0x57, 0x19, 0xd5, 0x5e, 0x2f, 0x1f, 0x79,
297                 0x0d, 0xd6, 0x61, 0xf2, 0x79, 0xa7, 0x91, 0x7c,
298             },
299             5, { 0x00, 0x00, 0x00, 0x01, 0xaa },
300         },
301         {
302             {
303                 0x79, 0x85, 0x62, 0xe0, 0x49, 0x85, 0x2f, 0x57,
304                 0xdc, 0x8c, 0x34, 0x3b, 0xa1, 0x7f, 0x2c, 0xa1,
305                 0xd9, 0x73, 0x94, 0xef, 0xc8, 0xad, 0xc4, 0x43,
306             },
307             5, { 0x00, 0x00, 0x00, 0x01, 0x55 },
308         },
309         {
310             {
311                 0x26, 0xdc, 0xe3, 0x34, 0xb5, 0x45, 0x29, 0x2f,
312                 0x2f, 0xea, 0xb9, 0xa8, 0x70, 0x1a, 0x89, 0xa4,
313                 0xb9, 0x9e, 0xb9, 0x94, 0x2c, 0xec, 0xd0, 0x16,
314             },
315             5, { 0x00, 0x00, 0x00, 0x01, 0xaa },
316         },
317     };
318     int i;
319 
320     for (i = 0; i < ASIZE(derive_tests); i++) {
321 #define D (derive_tests[i])
322         krb5_keyblock key;
323         krb5_data usage;
324 
325         unsigned char drData[KEYBYTES];
326         krb5_data dr;
327         unsigned char dkData[KEYLENGTH];
328         krb5_keyblock dk;
329 
330         key.length = KEYLENGTH, key.contents = D.keydata;
331         usage.length = D.usage_len, usage.data = D.usage;
332         dr.length = KEYBYTES, dr.data = drData;
333         dk.length = KEYLENGTH, dk.contents = dkData;
334 
335         printf ("key:\t"); printkey (&key); printf ("\n");
336         printf ("usage:\t"); printdata (&usage); printf ("\n");
337         DR (&dr, &key, &usage);
338         printf ("DR:\t"); printdata (&dr); printf ("\n");
339         DK (&dk, &key, &usage);
340         printf ("DK:\t"); printkey (&dk); printf ("\n\n");
341     }
342 }
343 
344 
printd(const char * descr,krb5_data * d)345 static void printd (const char *descr, krb5_data *d) {
346     int i, j;
347     const int r = 16;
348 
349     printf("%s:", descr);
350 
351     for (i = 0; i < d->length; i += r) {
352         printf("\n  %04x: ", i);
353         for (j = i; j < i + r && j < d->length; j++)
354             printf(" %02x", 0xff & d->data[j]);
355         for (; j < i + r; j++)
356             printf("   ");
357         printf("   ");
358         for (j = i; j < i + r && j < d->length; j++) {
359             int c = 0xff & d->data[j];
360             printf("%c", isprint(c) ? c : '.');
361         }
362     }
363     printf("\n");
364 }
printk(const char * descr,krb5_keyblock * k)365 static void printk(const char *descr, krb5_keyblock *k) {
366     krb5_data d;
367     d.data = k->contents;
368     d.length = k->length;
369     printd(descr, &d);
370 }
371 
372 
373 static void
test_pbkdf2()374 test_pbkdf2()
375 {
376     static struct {
377         int count;
378         char *pass;
379         char *salt;
380     } test[] = {
381         { 1, "password", "ATHENA.MIT.EDUraeburn" },
382         { 2, "password", "ATHENA.MIT.EDUraeburn" },
383         { 1200, "password", "ATHENA.MIT.EDUraeburn" },
384         { 5, "password", "\x12\x34\x56\x78\x78\x56\x34\x12" },
385         { 1200,
386           "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
387           "pass phrase equals block size" },
388         { 1200,
389           "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
390           "pass phrase exceeds block size" },
391         { 50, "\xf0\x9d\x84\x9e", "EXAMPLE.COMpianist" },
392     };
393     unsigned char x[100];
394     unsigned char x2[100];
395     int j;
396     krb5_error_code err;
397     krb5_data d;
398     krb5_keyblock k, dk;
399     krb5_data usage, pass, salt;
400 
401     d.data = x;
402     dk.contents = x2;
403 
404     usage.data = "kerberos";
405     usage.length = 8;
406 
407     for (j = 0; j < sizeof(test)/sizeof(test[0]); j++) {
408         printf("pkbdf2(count=%d, pass=\"%s\", salt=",
409                test[j].count, test[j].pass);
410         if (isprint(test[j].salt[0]))
411             printf("\"%s\")\n", test[j].salt);
412         else {
413             char *s = test[j].salt;
414             printf("0x");
415             while (*s)
416                 printf("%02X", 0xff & *s++);
417             printf(")\n");
418         }
419 
420         d.length = 16;
421         pass.data = test[j].pass;
422         pass.length = strlen(pass.data);
423         salt.data = test[j].salt;
424         salt.length = strlen(salt.data);
425         err = krb5int_pbkdf2_hmac_sha1 (&d, test[j].count, &pass, &salt);
426         printd("128-bit PBKDF2 output", &d);
427         enc = &krb5int_enc_aes128;
428         k.contents = d.data;
429         k.length = d.length;
430         dk.length = d.length;
431         DK (&dk, &k, &usage);
432         printk("128-bit AES key",&dk);
433 
434         d.length = 32;
435         err = krb5int_pbkdf2_hmac_sha1 (&d, test[j].count, &pass, &salt);
436         printd("256-bit PBKDF2 output", &d);
437         enc = &krb5int_enc_aes256;
438         k.contents = d.data;
439         k.length = d.length;
440         dk.length = d.length;
441         DK (&dk, &k, &usage);
442         printk("256-bit AES key", &dk);
443 
444         printf("\n");
445     }
446 }
447 
main(int argc,char ** argv)448 int main (int argc, char **argv)
449 {
450     whoami = argv[0];
451     test_nfold ();
452     test_pbkdf2();
453     return 0;
454 }
455