1c0bac10e75c3279d5fa4e903a562e163f3a5528
[strongswan.git] / src / libstrongswan / tests / suites / test_chunk.c
1 /*
2 * Copyright (C) 2013 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17
18 #include "test_suite.h"
19
20 #include <utils/chunk.h>
21
22 /*******************************************************************************
23 * utilities
24 */
25
26 static void assert_chunk_empty(chunk_t chunk)
27 {
28 ck_assert(chunk.len == 0 && chunk.ptr == NULL);
29 }
30
31 /*******************************************************************************
32 * equals
33 */
34
35 START_TEST(test_chunk_equals)
36 {
37 chunk_t chunk = chunk_from_str("chunk");
38 chunk_t chunk_a, chunk_b;
39
40 chunk_a = chunk_empty;
41 chunk_b = chunk_empty;
42 ck_assert(!chunk_equals(chunk_a, chunk_b));
43
44 chunk_a = chunk;
45 ck_assert(!chunk_equals(chunk_a, chunk_b));
46 chunk_b = chunk;
47 ck_assert(chunk_equals(chunk_a, chunk_b));
48
49 chunk_b = chunk_from_str("asdf");
50 ck_assert(!chunk_equals(chunk_a, chunk_b));
51
52 chunk_b = chunk_from_str("chunk");
53 ck_assert(chunk_equals(chunk_a, chunk_b));
54 }
55 END_TEST
56
57 /*******************************************************************************
58 * chunk_compare test
59 */
60
61 static struct {
62 int result;
63 chunk_t a;
64 chunk_t b;
65 } compare_data[] = {
66 { 0, { NULL, 0 }, { NULL, 0 }},
67 { 0, chunk_from_chars(0x00), chunk_from_chars(0x00)},
68 {-1, chunk_from_chars(0x00), chunk_from_chars(0x01)},
69 { 1, chunk_from_chars(0x01), chunk_from_chars(0x00)},
70 { 0, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x00)},
71 {-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
72 { 1, chunk_from_chars(0x00, 0x01), chunk_from_chars(0x00, 0x00)},
73 {-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x01, 0x00)},
74 { 1, chunk_from_chars(0x01, 0x00), chunk_from_chars(0x00, 0x00)},
75 {-1, chunk_from_chars(0xff), chunk_from_chars(0x00, 0x00)},
76 { 1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0xff)},
77 };
78
79 START_TEST(test_compare)
80 {
81 int result, expected;
82
83 result = chunk_compare(compare_data[_i].a, compare_data[_i].b);
84 expected = compare_data[_i].result;
85 ck_assert((result == 0 && expected == 0) ||
86 (result < 0 && expected < 0) ||
87 (result > 0 && expected > 0));
88 }
89 END_TEST
90
91 /*******************************************************************************
92 * clear
93 */
94
95 START_TEST(test_chunk_clear)
96 {
97 chunk_t chunk;
98 u_char *ptr;
99 int i;
100 bool cleared = TRUE;
101
102 chunk = chunk_empty;
103 chunk_clear(&chunk);
104 chunk_free(&chunk);
105
106 chunk = chunk_alloc(64);
107 ptr = chunk.ptr;
108 for (i = 0; i < 64; i++)
109 {
110 chunk.ptr[i] = i;
111 }
112 chunk_clear(&chunk);
113 /* check memory area of freed chunk. We can't use ck_assert() for this
114 * test directly, as it might allocate data at the freed area. */
115 for (i = 0; i < 64; i++)
116 {
117 if (ptr[i] != 0 && ptr[i] == i)
118 {
119 cleared = FALSE;
120 break;
121 }
122 }
123 assert_chunk_empty(chunk);
124 ck_assert(cleared);
125 }
126 END_TEST
127
128 /*******************************************************************************
129 * chunk_length
130 */
131
132 START_TEST(test_chunk_length)
133 {
134 chunk_t a, b, c;
135 size_t len;
136
137 a = chunk_empty;
138 b = chunk_empty;
139 c = chunk_empty;
140 len = chunk_length("ccc", a, b, c);
141 ck_assert_int_eq(len, 0);
142
143 a = chunk_from_str("foo");
144 b = chunk_from_str("bar");
145 len = chunk_length("ccc", a, b, c);
146 ck_assert_int_eq(len, 6);
147
148 len = chunk_length("zcc", a, b, c);
149 ck_assert_int_eq(len, 0);
150
151 len = chunk_length("czc", a, b, c);
152 ck_assert_int_eq(len, 3);
153
154 a = chunk_from_str("foo");
155 b = chunk_from_str("bar");
156 c = chunk_from_str("baz");
157 len = chunk_length("ccc", a, b, c);
158 ck_assert_int_eq(len, 9);
159 }
160 END_TEST
161
162 /*******************************************************************************
163 * chunk_create_cat
164 */
165
166 START_TEST(test_chunk_create_cat)
167 {
168 chunk_t foo, bar;
169 chunk_t a, b, c;
170 u_char *ptra, *ptrb;
171
172 foo = chunk_from_str("foo");
173 bar = chunk_from_str("bar");
174
175 /* to simplify things we use the chunk_cata macro */
176
177 a = chunk_empty;
178 b = chunk_empty;
179 c = chunk_cata("cc", a, b);
180 ck_assert_int_eq(c.len, 0);
181 ck_assert(c.ptr != NULL);
182
183 a = foo;
184 b = bar;
185 c = chunk_cata("cc", a, b);
186 ck_assert_int_eq(c.len, 6);
187 ck_assert(chunk_equals(c, chunk_from_str("foobar")));
188
189 a = chunk_clone(foo);
190 b = chunk_clone(bar);
191 c = chunk_cata("mm", a, b);
192 ck_assert_int_eq(c.len, 6);
193 ck_assert(chunk_equals(c, chunk_from_str("foobar")));
194
195 a = chunk_clone(foo);
196 b = chunk_clone(bar);
197 ptra = a.ptr;
198 ptrb = b.ptr;
199 c = chunk_cata("ss", a, b);
200 ck_assert_int_eq(c.len, 6);
201 ck_assert(chunk_equals(c, chunk_from_str("foobar")));
202 /* check memory area of cleared chunk */
203 ck_assert(!chunk_equals(foo, chunk_create(ptra, 3)));
204 ck_assert(!chunk_equals(bar, chunk_create(ptrb, 3)));
205 }
206 END_TEST
207
208 /*******************************************************************************
209 * chunk_split
210 */
211
212 static bool mem_in_chunk(u_char *ptr, chunk_t chunk)
213 {
214 return ptr >= chunk.ptr && ptr < (chunk.ptr + chunk.len);
215 }
216
217 START_TEST(test_chunk_split)
218 {
219 chunk_t foo, bar, foobar;
220 chunk_t a, b, c;
221 u_char *ptra, *ptrb;
222
223 foo = chunk_from_str("foo");
224 bar = chunk_from_str("bar");
225 foobar = chunk_from_str("foobar");
226
227 chunk_split(foobar, "aa", 3, &a, 3, &b);
228 ck_assert(chunk_equals(a, foo));
229 ck_assert(chunk_equals(b, bar));
230 ck_assert(!mem_in_chunk(a.ptr, foobar));
231 ck_assert(!mem_in_chunk(b.ptr, foobar));
232 chunk_free(&a);
233 chunk_free(&b);
234
235 chunk_split(foobar, "mm", 3, &a, 3, &b);
236 ck_assert(chunk_equals(a, foo));
237 ck_assert(chunk_equals(b, bar));
238 ck_assert(mem_in_chunk(a.ptr, foobar));
239 ck_assert(mem_in_chunk(b.ptr, foobar));
240
241 chunk_split(foobar, "am", 3, &a, 3, &b);
242 ck_assert(chunk_equals(a, foo));
243 ck_assert(chunk_equals(b, bar));
244 ck_assert(!mem_in_chunk(a.ptr, foobar));
245 ck_assert(mem_in_chunk(b.ptr, foobar));
246 chunk_free(&a);
247
248 a = chunk_alloca(3);
249 ptra = a.ptr;
250 b = chunk_alloca(3);
251 ptrb = b.ptr;
252 chunk_split(foobar, "cc", 3, &a, 3, &b);
253 ck_assert(chunk_equals(a, foo));
254 ck_assert(chunk_equals(b, bar));
255 ck_assert(a.ptr == ptra);
256 ck_assert(b.ptr == ptrb);
257
258 chunk_split(foobar, "mm", 1, NULL, 2, &a, 2, NULL, 1, &b);
259 ck_assert(chunk_equals(a, chunk_from_str("oo")));
260 ck_assert(chunk_equals(b, chunk_from_str("r")));
261
262 chunk_split(foobar, "mm", 6, &a, 6, &b);
263 ck_assert(chunk_equals(a, foobar));
264 assert_chunk_empty(b);
265
266 chunk_split(foobar, "mac", 12, &a, 12, &b, 12, &c);
267 ck_assert(chunk_equals(a, foobar));
268 assert_chunk_empty(b);
269 assert_chunk_empty(c);
270 }
271 END_TEST
272
273 /*******************************************************************************
274 * chunk_skip[_zero]
275 */
276
277 START_TEST(test_chunk_skip)
278 {
279 chunk_t foobar, a;
280
281 foobar = chunk_from_str("foobar");
282 a = foobar;
283 a = chunk_skip(a, 0);
284 ck_assert(chunk_equals(a, foobar));
285 a = chunk_skip(a, 1);
286 ck_assert(chunk_equals(a, chunk_from_str("oobar")));
287 a = chunk_skip(a, 2);
288 ck_assert(chunk_equals(a, chunk_from_str("bar")));
289 a = chunk_skip(a, 3);
290 assert_chunk_empty(a);
291
292 a = foobar;
293 a = chunk_skip(a, 6);
294 assert_chunk_empty(a);
295
296 a = foobar;
297 a = chunk_skip(a, 10);
298 assert_chunk_empty(a);
299 }
300 END_TEST
301
302 START_TEST(test_chunk_skip_zero)
303 {
304 chunk_t foobar, a;
305
306 a = chunk_empty;
307 a = chunk_skip_zero(a);
308 assert_chunk_empty(a);
309
310 foobar = chunk_from_str("foobar");
311 a = foobar;
312 a = chunk_skip_zero(a);
313 ck_assert(chunk_equals(a, foobar));
314
315 a = chunk_from_chars(0x00, 0xaa, 0xbb, 0xcc);
316 a = chunk_skip_zero(a);
317 ck_assert(chunk_equals(a, chunk_from_chars(0xaa, 0xbb, 0xcc)));
318 a = chunk_skip_zero(a);
319 ck_assert(chunk_equals(a, chunk_from_chars(0xaa, 0xbb, 0xcc)));
320 }
321 END_TEST
322
323 /*******************************************************************************
324 * BASE16 encoding test
325 */
326
327 START_TEST(test_base16)
328 {
329 /* test vectors from RFC 4648:
330 *
331 * BASE16("") = ""
332 * BASE16("f") = "66"
333 * BASE16("fo") = "666F"
334 * BASE16("foo") = "666F6F"
335 * BASE16("foob") = "666F6F62"
336 * BASE16("fooba") = "666F6F6261"
337 * BASE16("foobar") = "666F6F626172"
338 */
339 typedef struct {
340 bool upper;
341 char *in;
342 char *out;
343 } testdata_t;
344
345 testdata_t test[] = {
346 {TRUE, "", ""},
347 {TRUE, "f", "66"},
348 {TRUE, "fo", "666F"},
349 {TRUE, "foo", "666F6F"},
350 {TRUE, "foob", "666F6F62"},
351 {TRUE, "fooba", "666F6F6261"},
352 {TRUE, "foobar", "666F6F626172"},
353 {FALSE, "", ""},
354 {FALSE, "f", "66"},
355 {FALSE, "fo", "666f"},
356 {FALSE, "foo", "666f6f"},
357 {FALSE, "foob", "666f6f62"},
358 {FALSE, "fooba", "666f6f6261"},
359 {FALSE, "foobar", "666f6f626172"},
360 };
361 testdata_t test_colon[] = {
362 {TRUE, "", ""},
363 {TRUE, "f", "66"},
364 {TRUE, "fo", "66:6F"},
365 {TRUE, "foo", "66:6F:6F"},
366 {FALSE, "foob", "66:6f:6f:62"},
367 {FALSE, "fooba", "66:6f:6f:62:61"},
368 {FALSE, "foobar", "66:6f:6f:62:61:72"},
369 {FALSE, "foobar", "66:6f6f:6261:72"},
370 };
371 int i;
372
373 for (i = 0; i < countof(test); i++)
374 {
375 chunk_t out;
376
377 out = chunk_to_hex(chunk_create(test[i].in, strlen(test[i].in)), NULL,
378 test[i].upper);
379 ck_assert_str_eq(out.ptr, test[i].out);
380 free(out.ptr);
381 }
382
383 for (i = 0; i < countof(test); i++)
384 {
385 chunk_t out;
386
387 out = chunk_from_hex(chunk_create(test[i].out, strlen(test[i].out)), NULL);
388 fail_unless(strneq(out.ptr, test[i].in, out.len),
389 "base16 conversion error - should '%s', is %#B",
390 test[i].in, &out);
391 free(out.ptr);
392 }
393
394 for (i = 0; i < countof(test_colon); i++)
395 {
396 chunk_t out;
397
398 out = chunk_from_hex(chunk_create(test_colon[i].out, strlen(test_colon[i].out)), NULL);
399 fail_unless(strneq(out.ptr, test_colon[i].in, out.len),
400 "base16 conversion error - should '%s', is %#B",
401 test_colon[i].in, &out);
402 free(out.ptr);
403 }
404 }
405 END_TEST
406
407 /*******************************************************************************
408 * BASE64 encoding test
409 */
410
411 START_TEST(test_base64)
412 {
413 /* test vectors from RFC 4648:
414 *
415 * BASE64("") = ""
416 * BASE64("f") = "Zg=="
417 * BASE64("fo") = "Zm8="
418 * BASE64("foo") = "Zm9v"
419 * BASE64("foob") = "Zm9vYg=="
420 * BASE64("fooba") = "Zm9vYmE="
421 * BASE64("foobar") = "Zm9vYmFy"
422 */
423 typedef struct {
424 char *in;
425 char *out;
426 } testdata_t;
427
428 testdata_t test[] = {
429 {"", ""},
430 {"f", "Zg=="},
431 {"fo", "Zm8="},
432 {"foo", "Zm9v"},
433 {"foob", "Zm9vYg=="},
434 {"fooba", "Zm9vYmE="},
435 {"foobar", "Zm9vYmFy"},
436 };
437 int i;
438
439 for (i = 0; i < countof(test); i++)
440 {
441 chunk_t out;
442
443 out = chunk_to_base64(chunk_create(test[i].in, strlen(test[i].in)), NULL);
444 ck_assert_str_eq(out.ptr, test[i].out);
445 free(out.ptr);
446 }
447
448 for (i = 0; i < countof(test); i++)
449 {
450 chunk_t out;
451
452 out = chunk_from_base64(chunk_create(test[i].out, strlen(test[i].out)), NULL);
453 fail_unless(strneq(out.ptr, test[i].in, out.len),
454 "base64 conversion error - should '%s', is %#B",
455 test[i].in, &out);
456 free(out.ptr);
457 }
458 }
459 END_TEST
460
461 /*******************************************************************************
462 * BASE32 encoding test
463 */
464
465 START_TEST(test_base32)
466 {
467 /* test vectors from RFC 4648:
468 *
469 * BASE32("") = ""
470 * BASE32("f") = "MY======"
471 * BASE32("fo") = "MZXQ===="
472 * BASE32("foo") = "MZXW6==="
473 * BASE32("foob") = "MZXW6YQ="
474 * BASE32("fooba") = "MZXW6YTB"
475 * BASE32("foobar") = "MZXW6YTBOI======"
476 */
477 typedef struct {
478 char *in;
479 char *out;
480 } testdata_t;
481
482 testdata_t test[] = {
483 {"", ""},
484 {"f", "MY======"},
485 {"fo", "MZXQ===="},
486 {"foo", "MZXW6==="},
487 {"foob", "MZXW6YQ="},
488 {"fooba", "MZXW6YTB"},
489 {"foobar", "MZXW6YTBOI======"},
490 };
491 int i;
492
493 for (i = 0; i < countof(test); i++)
494 {
495 chunk_t out;
496
497 out = chunk_to_base32(chunk_create(test[i].in, strlen(test[i].in)), NULL);
498 ck_assert_str_eq(out.ptr, test[i].out);
499 free(out.ptr);
500 }
501 }
502 END_TEST
503
504 /*******************************************************************************
505 * chunk_increment test
506 */
507
508 static struct {
509 bool overflow;
510 chunk_t in;
511 chunk_t out;
512 } increment_data[] = {
513 {TRUE, { NULL, 0 }, { NULL, 0 }},
514 {FALSE, chunk_from_chars(0x00), chunk_from_chars(0x01)},
515 {FALSE, chunk_from_chars(0xfe), chunk_from_chars(0xff)},
516 {TRUE, chunk_from_chars(0xff), chunk_from_chars(0x00)},
517 {FALSE, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
518 {FALSE, chunk_from_chars(0x00, 0xff), chunk_from_chars(0x01, 0x00)},
519 {FALSE, chunk_from_chars(0xfe, 0xff), chunk_from_chars(0xff, 0x00)},
520 {TRUE, chunk_from_chars(0xff, 0xff), chunk_from_chars(0x00, 0x00)},
521 };
522
523 START_TEST(test_increment)
524 {
525 chunk_t chunk;
526 bool overflow;
527
528 chunk = chunk_clonea(increment_data[_i].in);
529 overflow = chunk_increment(chunk);
530 ck_assert(overflow == increment_data[_i].overflow);
531 ck_assert(!increment_data[_i].out.ptr ||
532 chunk_equals(chunk, increment_data[_i].out));
533 }
534 END_TEST
535
536 /*******************************************************************************
537 * chunk_printable tests
538 */
539
540 static struct {
541 bool printable;
542 chunk_t in;
543 char *out;
544 } printable_data[] = {
545 {TRUE, chunk_from_chars(0x31), "1"},
546 {FALSE, chunk_from_chars(0x00), "?"},
547 {FALSE, chunk_from_chars(0x31, 0x00), "1?"},
548 {FALSE, chunk_from_chars(0x00, 0x31), "?1"},
549 {TRUE, chunk_from_chars(0x3f, 0x31), "?1"},
550 {FALSE, chunk_from_chars(0x00, 0x31, 0x00), "?1?"},
551 {FALSE, chunk_from_chars(0x00, 0x31, 0x00, 0x32), "?1?2"},
552 };
553
554 START_TEST(test_printable)
555 {
556 bool printable;
557
558 printable = chunk_printable(printable_data[_i].in, NULL, ' ');
559 ck_assert(printable == printable_data[_i].printable);
560 }
561 END_TEST
562
563 START_TEST(test_printable_sanitize)
564 {
565 chunk_t sane, expected;
566 bool printable;
567
568 printable = chunk_printable(printable_data[_i].in, &sane, '?');
569 ck_assert(printable == printable_data[_i].printable);
570 expected = chunk_from_str(printable_data[_i].out);
571 ck_assert(chunk_equals(sane, expected));
572 chunk_free(&sane);
573 }
574 END_TEST
575
576 START_TEST(test_printable_empty)
577 {
578 chunk_t sane;
579 bool printable;
580
581 printable = chunk_printable(chunk_empty, NULL, ' ');
582 ck_assert(printable);
583
584 sane.ptr = (void*)1;
585 sane.len = 1;
586 printable = chunk_printable(chunk_empty, &sane, ' ');
587 ck_assert(printable);
588 assert_chunk_empty(sane);
589 }
590 END_TEST
591
592 /*******************************************************************************
593 * test for chunk_mac(), i.e. SipHash-2-4
594 */
595
596 /**
597 * SipHash-2-4 output with
598 * k = 00 01 02 ...
599 * and
600 * in = (empty string)
601 * in = 00 (1 byte)
602 * in = 00 01 (2 bytes)
603 * in = 00 01 02 (3 bytes)
604 * ...
605 * in = 00 01 02 ... 3e (63 bytes)
606 */
607 static const u_char sip_vectors[64][8] =
608 {
609 { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
610 { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
611 { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
612 { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
613 { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
614 { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
615 { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
616 { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
617 { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
618 { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
619 { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
620 { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
621 { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
622 { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
623 { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
624 { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
625 { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
626 { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
627 { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
628 { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
629 { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
630 { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
631 { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
632 { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
633 { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
634 { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
635 { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
636 { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
637 { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
638 { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
639 { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
640 { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
641 { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
642 { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
643 { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
644 { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
645 { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
646 { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
647 { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
648 { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
649 { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
650 { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
651 { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
652 { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
653 { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
654 { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
655 { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
656 { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
657 { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
658 { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
659 { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
660 { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
661 { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
662 { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
663 { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
664 { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
665 { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
666 { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
667 { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
668 { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
669 { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
670 { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
671 { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
672 { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
673 };
674
675 /**
676 * Our SipHash-2-4 implementation returns the result in host order, which
677 * doesn't matter for practical purposes and even avoids a byte swap. But
678 * because the test vectors are in little-endian we have to account for this
679 * with this custom comparison function.
680 */
681 static inline bool sipeq(const void *a, const void *b, size_t n)
682 {
683 u_char *ap = (u_char*)a, *bp = (u_char*)b;
684 int i;
685
686 for (i = 0; i < n; i++)
687 {
688 #ifdef WORDS_BIGENDIAN
689 if (ap[i] != bp[n - i - 1])
690 #else
691 if (ap[i] != bp[i])
692 #endif
693 {
694 return FALSE;
695 }
696 }
697 return TRUE;
698 }
699
700 START_TEST(test_chunk_mac)
701 {
702 chunk_t in;
703 u_char key[16];
704 u_int64_t out;
705 int i, count;
706
707 count = countof(sip_vectors);
708 in = chunk_alloca(count);
709
710 for (i = 0; i < 16; ++i)
711 {
712 key[i] = i;
713 }
714
715 for (i = 0; i < count; ++i)
716 {
717 in.ptr[i] = i;
718 in.len = i;
719 out = chunk_mac(in, key);
720 fail_unless(sipeq(&out, sip_vectors[i], 8),
721 "test vector failed for %d bytes", i);
722 }
723 }
724 END_TEST
725
726 /*******************************************************************************
727 * test for chunk_hash[_inc]()
728 */
729
730 START_TEST(test_chunk_hash)
731 {
732 chunk_t chunk;
733 u_int32_t hash_a, hash_b, hash_c;
734
735 chunk = chunk_from_str("asdf");
736
737 /* output is randomized, so there are no test-vectors we could use */
738 hash_a = chunk_hash(chunk);
739 hash_b = chunk_hash(chunk);
740 ck_assert(hash_a == hash_b);
741 hash_b = chunk_hash_inc(chunk, hash_a);
742 ck_assert(hash_a != hash_b);
743 hash_c = chunk_hash_inc(chunk, hash_a);
744 ck_assert(hash_b == hash_c);
745 }
746 END_TEST
747
748 /*******************************************************************************
749 * test for chunk_hash_static[_inc]()
750 */
751
752 START_TEST(test_chunk_hash_static)
753 {
754 chunk_t in;
755 u_int32_t out, hash_a, hash_b, hash_inc = 0x7b891a95;
756 int i, count;
757
758 count = countof(sip_vectors);
759 in = chunk_alloca(count);
760
761 for (i = 0; i < count; ++i)
762 {
763 in.ptr[i] = i;
764 in.len = i;
765 /* compared to chunk_mac() we only get half the value back */
766 out = chunk_hash_static(in);
767 fail_unless(sipeq(&out, sip_vectors[i], 4),
768 "test vector failed for %d bytes", i);
769 }
770 hash_a = chunk_hash_static_inc(in, out);
771 ck_assert_int_eq(hash_a, hash_inc);
772 hash_b = chunk_hash_static_inc(in, out);
773 ck_assert_int_eq(hash_a, hash_b);
774 }
775 END_TEST
776
777 /*******************************************************************************
778 * printf_hook tests
779 */
780
781 static struct {
782 chunk_t in;
783 char *out;
784 char *out_plus;
785 } printf_hook_data[] = {
786 {chunk_from_chars(), "", ""},
787 {chunk_from_chars(0x00), "00", "00"},
788 {chunk_from_chars(0x00, 0x01), "00:01", "0001"},
789 {chunk_from_chars(0x00, 0x01, 0x02), "00:01:02", "000102"},
790 };
791
792 START_TEST(test_printf_hook_hash)
793 {
794 char buf[16];
795 int len;
796
797 len = snprintf(buf, sizeof(buf), "%#B", &printf_hook_data[_i].in);
798 ck_assert(len >= 0 && len < sizeof(buf));
799 ck_assert_str_eq(buf, printf_hook_data[_i].out);
800 }
801 END_TEST
802
803 START_TEST(test_printf_hook_plus)
804 {
805 char buf[16];
806 int len;
807
808 len = snprintf(buf, sizeof(buf), "%+B", &printf_hook_data[_i].in);
809 ck_assert(len >= 0 && len < sizeof(buf));
810 ck_assert_str_eq(buf, printf_hook_data[_i].out_plus);
811 }
812 END_TEST
813
814 START_TEST(test_printf_hook)
815 {
816 char buf[128], mem[128];
817 int len;
818
819 /* %B should be the same as %b, which is what we check, comparing the
820 * acutal result could be tricky as %b prints the chunk's memory address */
821 len = snprintf(buf, sizeof(buf), "%B", &printf_hook_data[_i].in);
822 ck_assert(len >= 0 && len < sizeof(buf));
823 len = snprintf(mem, sizeof(mem), "%b", printf_hook_data[_i].in.ptr,
824 (u_int)printf_hook_data[_i].in.len);
825 ck_assert(len >= 0 && len < sizeof(mem));
826 ck_assert_str_eq(buf, mem);
827 }
828 END_TEST
829
830 Suite *chunk_suite_create()
831 {
832 Suite *s;
833 TCase *tc;
834
835 s = suite_create("chunk");
836
837 tc = tcase_create("equals");
838 tcase_add_test(tc, test_chunk_equals);
839 suite_add_tcase(s, tc);
840
841 tc = tcase_create("chunk_compare");
842 tcase_add_loop_test(tc, test_compare, 0, countof(compare_data));
843 suite_add_tcase(s, tc);
844
845 tc = tcase_create("clear");
846 tcase_add_test(tc, test_chunk_clear);
847 suite_add_tcase(s, tc);
848
849 tc = tcase_create("chunk_length");
850 tcase_add_test(tc, test_chunk_length);
851 suite_add_tcase(s, tc);
852
853 tc = tcase_create("chunk_create_cat");
854 tcase_add_test(tc, test_chunk_create_cat);
855 suite_add_tcase(s, tc);
856
857 tc = tcase_create("chunk_split");
858 tcase_add_test(tc, test_chunk_split);
859 suite_add_tcase(s, tc);
860
861 tc = tcase_create("chunk_skip");
862 tcase_add_test(tc, test_chunk_skip);
863 tcase_add_test(tc, test_chunk_skip_zero);
864 suite_add_tcase(s, tc);
865
866 tc = tcase_create("chunk_increment");
867 tcase_add_loop_test(tc, test_increment, 0, countof(increment_data));
868 suite_add_tcase(s, tc);
869
870 tc = tcase_create("chunk_printable");
871 tcase_add_loop_test(tc, test_printable, 0, countof(printable_data));
872 tcase_add_loop_test(tc, test_printable_sanitize, 0, countof(printable_data));
873 tcase_add_test(tc, test_printable_empty);
874 suite_add_tcase(s, tc);
875
876 tc = tcase_create("baseXX");
877 tcase_add_test(tc, test_base64);
878 tcase_add_test(tc, test_base32);
879 tcase_add_test(tc, test_base16);
880 suite_add_tcase(s, tc);
881
882 tc = tcase_create("chunk_mac");
883 tcase_add_test(tc, test_chunk_mac);
884 suite_add_tcase(s, tc);
885
886 tc = tcase_create("chunk_hash");
887 tcase_add_test(tc, test_chunk_hash);
888 suite_add_tcase(s, tc);
889
890 tc = tcase_create("chunk_hash_static");
891 tcase_add_test(tc, test_chunk_hash_static);
892 suite_add_tcase(s, tc);
893
894 tc = tcase_create("printf_hook");
895 tcase_add_loop_test(tc, test_printf_hook_hash, 0, countof(printf_hook_data));
896 tcase_add_loop_test(tc, test_printf_hook_plus, 0, countof(printf_hook_data));
897 tcase_add_loop_test(tc, test_printf_hook, 0, countof(printf_hook_data));
898 suite_add_tcase(s, tc);
899
900 return s;
901 }