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