chunk: Add helper to copy a chunk left-padded to a certain length
[strongswan.git] / src / libstrongswan / tests / suites / test_chunk.c
1 /*
2 * Copyright (C) 2013 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * HSR 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 #include "test_suite.h"
18
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <errno.h>
24
25 #include <utils/chunk.h>
26 #include <threading/thread.h>
27
28 /*******************************************************************************
29 * utilities
30 */
31
32 static void assert_chunk_empty(chunk_t chunk)
33 {
34 ck_assert(chunk.len == 0 && chunk.ptr == NULL);
35 }
36
37 /*******************************************************************************
38 * equals
39 */
40
41 START_TEST(test_chunk_equals)
42 {
43 chunk_t chunk = chunk_from_str("chunk");
44 chunk_t chunk_a, chunk_b;
45
46 chunk_a = chunk_empty;
47 chunk_b = chunk_empty;
48 ck_assert(!chunk_equals(chunk_a, chunk_b));
49
50 chunk_a = chunk;
51 ck_assert(!chunk_equals(chunk_a, chunk_b));
52 chunk_b = chunk;
53 ck_assert(chunk_equals(chunk_a, chunk_b));
54
55 chunk_b = chunk_from_str("asdf");
56 ck_assert(!chunk_equals(chunk_a, chunk_b));
57
58 chunk_b = chunk_from_str("chunk");
59 ck_assert(chunk_equals(chunk_a, chunk_b));
60 }
61 END_TEST
62
63 /*******************************************************************************
64 * equals_const
65 */
66
67 START_TEST(test_chunk_equals_const)
68 {
69 chunk_t chunk = chunk_from_str("chunk");
70 chunk_t chunk_a, chunk_b;
71
72 chunk_a = chunk_empty;
73 chunk_b = chunk_empty;
74 ck_assert(!chunk_equals_const(chunk_a, chunk_b));
75
76 chunk_a = chunk;
77 ck_assert(!chunk_equals_const(chunk_a, chunk_b));
78 chunk_b = chunk;
79 ck_assert(chunk_equals_const(chunk_a, chunk_b));
80
81 chunk_b = chunk_from_str("asdf");
82 ck_assert(!chunk_equals_const(chunk_a, chunk_b));
83
84 chunk_b = chunk_from_str("chunk");
85 ck_assert(chunk_equals_const(chunk_a, chunk_b));
86 }
87 END_TEST
88
89 /*******************************************************************************
90 * chunk_compare test
91 */
92
93 static struct {
94 int result;
95 chunk_t a;
96 chunk_t b;
97 } compare_data[] = {
98 { 0, { NULL, 0 }, { NULL, 0 }},
99 { 0, chunk_from_chars(0x00), chunk_from_chars(0x00)},
100 {-1, chunk_from_chars(0x00), chunk_from_chars(0x01)},
101 { 1, chunk_from_chars(0x01), chunk_from_chars(0x00)},
102 { 0, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x00)},
103 {-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
104 { 1, chunk_from_chars(0x00, 0x01), chunk_from_chars(0x00, 0x00)},
105 {-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x01, 0x00)},
106 { 1, chunk_from_chars(0x01, 0x00), chunk_from_chars(0x00, 0x00)},
107 {-1, chunk_from_chars(0xff), chunk_from_chars(0x00, 0x00)},
108 { 1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0xff)},
109 };
110
111 START_TEST(test_compare)
112 {
113 int result, expected;
114
115 result = chunk_compare(compare_data[_i].a, compare_data[_i].b);
116 expected = compare_data[_i].result;
117 ck_assert((result == 0 && expected == 0) ||
118 (result < 0 && expected < 0) ||
119 (result > 0 && expected > 0));
120 }
121 END_TEST
122
123 /*******************************************************************************
124 * clear
125 */
126
127 START_TEST(test_chunk_clear)
128 {
129 chunk_t chunk;
130 u_char *ptr;
131 int i;
132 bool cleared = TRUE;
133
134 chunk = chunk_empty;
135 chunk_clear(&chunk);
136 chunk_free(&chunk);
137
138 chunk = chunk_alloc(64);
139 ptr = chunk.ptr;
140 for (i = 0; i < 64; i++)
141 {
142 chunk.ptr[i] = i;
143 }
144 chunk_clear(&chunk);
145 /* check memory area of freed chunk. We can't use ck_assert() for this
146 * test directly, as it might allocate data at the freed area. comparing
147 * two bytes at once reduces the chances of conflicts if memory got
148 * overwritten already */
149 for (i = 0; i < 64; i += 2)
150 {
151 if (ptr[i] != 0 && ptr[i] == i &&
152 ptr[i+1] != 0 && ptr[i+1] == i+1)
153 {
154 cleared = FALSE;
155 break;
156 }
157 }
158 assert_chunk_empty(chunk);
159 ck_assert(cleared);
160 }
161 END_TEST
162
163 /*******************************************************************************
164 * chunk_length
165 */
166
167 START_TEST(test_chunk_length)
168 {
169 chunk_t a, b, c;
170 size_t len;
171
172 a = chunk_empty;
173 b = chunk_empty;
174 c = chunk_empty;
175 len = chunk_length("ccc", a, b, c);
176 ck_assert_int_eq(len, 0);
177
178 a = chunk_from_str("foo");
179 b = chunk_from_str("bar");
180 len = chunk_length("ccc", a, b, c);
181 ck_assert_int_eq(len, 6);
182
183 len = chunk_length("zcc", a, b, c);
184 ck_assert_int_eq(len, 0);
185
186 len = chunk_length("czc", a, b, c);
187 ck_assert_int_eq(len, 3);
188
189 a = chunk_from_str("foo");
190 b = chunk_from_str("bar");
191 c = chunk_from_str("baz");
192 len = chunk_length("ccc", a, b, c);
193 ck_assert_int_eq(len, 9);
194 }
195 END_TEST
196
197 /*******************************************************************************
198 * chunk_create_cat
199 */
200
201 START_TEST(test_chunk_create_cat)
202 {
203 chunk_t foo, bar;
204 chunk_t a, b, c;
205 u_char *ptra, *ptrb;
206
207 foo = chunk_from_str("foo");
208 bar = chunk_from_str("bar");
209
210 /* to simplify things we use the chunk_cata macro */
211
212 a = chunk_empty;
213 b = chunk_empty;
214 c = chunk_cata("cc", a, b);
215 ck_assert_int_eq(c.len, 0);
216 ck_assert(c.ptr != NULL);
217
218 a = foo;
219 b = bar;
220 c = chunk_cata("cc", a, b);
221 ck_assert_int_eq(c.len, 6);
222 ck_assert(chunk_equals(c, chunk_from_str("foobar")));
223
224 a = chunk_clone(foo);
225 b = chunk_clone(bar);
226 c = chunk_cata("mm", a, b);
227 ck_assert_int_eq(c.len, 6);
228 ck_assert(chunk_equals(c, chunk_from_str("foobar")));
229
230 a = chunk_clone(foo);
231 b = chunk_clone(bar);
232 ptra = a.ptr;
233 ptrb = b.ptr;
234 c = chunk_cata("ss", a, b);
235 ck_assert_int_eq(c.len, 6);
236 ck_assert(chunk_equals(c, chunk_from_str("foobar")));
237 /* check memory area of cleared chunk */
238 ck_assert(!chunk_equals(foo, chunk_create(ptra, 3)));
239 ck_assert(!chunk_equals(bar, chunk_create(ptrb, 3)));
240 }
241 END_TEST
242
243 /*******************************************************************************
244 * chunk_split
245 */
246
247 static bool mem_in_chunk(u_char *ptr, chunk_t chunk)
248 {
249 return ptr >= chunk.ptr && ptr < (chunk.ptr + chunk.len);
250 }
251
252 START_TEST(test_chunk_split)
253 {
254 chunk_t foo, bar, foobar;
255 chunk_t a, b, c;
256 u_char *ptra, *ptrb;
257
258 foo = chunk_from_str("foo");
259 bar = chunk_from_str("bar");
260 foobar = chunk_from_str("foobar");
261
262 chunk_split(foobar, "aa", 3, &a, 3, &b);
263 ck_assert(chunk_equals(a, foo));
264 ck_assert(chunk_equals(b, bar));
265 ck_assert(!mem_in_chunk(a.ptr, foobar));
266 ck_assert(!mem_in_chunk(b.ptr, foobar));
267 chunk_free(&a);
268 chunk_free(&b);
269
270 chunk_split(foobar, "mm", 3, &a, 3, &b);
271 ck_assert(chunk_equals(a, foo));
272 ck_assert(chunk_equals(b, bar));
273 ck_assert(mem_in_chunk(a.ptr, foobar));
274 ck_assert(mem_in_chunk(b.ptr, foobar));
275
276 chunk_split(foobar, "am", 3, &a, 3, &b);
277 ck_assert(chunk_equals(a, foo));
278 ck_assert(chunk_equals(b, bar));
279 ck_assert(!mem_in_chunk(a.ptr, foobar));
280 ck_assert(mem_in_chunk(b.ptr, foobar));
281 chunk_free(&a);
282
283 a = chunk_alloca(3);
284 ptra = a.ptr;
285 b = chunk_alloca(3);
286 ptrb = b.ptr;
287 chunk_split(foobar, "cc", 3, &a, 3, &b);
288 ck_assert(chunk_equals(a, foo));
289 ck_assert(chunk_equals(b, bar));
290 ck_assert(a.ptr == ptra);
291 ck_assert(b.ptr == ptrb);
292
293 chunk_split(foobar, "mm", 1, NULL, 2, &a, 2, NULL, 1, &b);
294 ck_assert(chunk_equals(a, chunk_from_str("oo")));
295 ck_assert(chunk_equals(b, chunk_from_str("r")));
296
297 chunk_split(foobar, "mm", 6, &a, 6, &b);
298 ck_assert(chunk_equals(a, foobar));
299 assert_chunk_empty(b);
300
301 chunk_split(foobar, "mac", 12, &a, 12, &b, 12, &c);
302 ck_assert(chunk_equals(a, foobar));
303 assert_chunk_empty(b);
304 assert_chunk_empty(c);
305 }
306 END_TEST
307
308 /*******************************************************************************
309 * chunk_skip[_zero]
310 */
311
312 START_TEST(test_chunk_skip)
313 {
314 chunk_t foobar, a;
315
316 foobar = chunk_from_str("foobar");
317 a = foobar;
318 a = chunk_skip(a, 0);
319 ck_assert_chunk_eq(a, foobar);
320 a = chunk_skip(a, 1);
321 ck_assert_chunk_eq(a, chunk_from_str("oobar"));
322 a = chunk_skip(a, 2);
323 ck_assert_chunk_eq(a, chunk_from_str("bar"));
324 a = chunk_skip(a, 3);
325 assert_chunk_empty(a);
326
327 a = foobar;
328 a = chunk_skip(a, 6);
329 assert_chunk_empty(a);
330
331 a = foobar;
332 a = chunk_skip(a, 10);
333 assert_chunk_empty(a);
334 }
335 END_TEST
336
337 START_TEST(test_chunk_skip_zero)
338 {
339 chunk_t foobar, a;
340
341 a = chunk_skip_zero(chunk_empty);
342 assert_chunk_empty(a);
343
344 foobar = chunk_from_str("foobar");
345 a = chunk_skip_zero(foobar);
346 ck_assert_chunk_eq(a, foobar);
347
348 foobar = chunk_from_chars(0x00);
349 a = chunk_skip_zero(foobar);
350 ck_assert_chunk_eq(a, foobar);
351
352 a = chunk_skip_zero(chunk_from_chars(0x00, 0xaa, 0xbb, 0xcc));
353 ck_assert_chunk_eq(a, chunk_from_chars(0xaa, 0xbb, 0xcc));
354 a = chunk_skip_zero(a);
355 ck_assert_chunk_eq(a, chunk_from_chars(0xaa, 0xbb, 0xcc));
356
357 a = chunk_skip_zero(chunk_from_chars(0x00, 0x00, 0xaa, 0xbb, 0xcc));
358 ck_assert_chunk_eq(a, chunk_from_chars(0xaa, 0xbb, 0xcc));
359 }
360 END_TEST
361
362 /*******************************************************************************
363 * BASE16 encoding test
364 */
365
366 START_TEST(test_base16)
367 {
368 /* test vectors from RFC 4648:
369 *
370 * BASE16("") = ""
371 * BASE16("f") = "66"
372 * BASE16("fo") = "666F"
373 * BASE16("foo") = "666F6F"
374 * BASE16("foob") = "666F6F62"
375 * BASE16("fooba") = "666F6F6261"
376 * BASE16("foobar") = "666F6F626172"
377 */
378 typedef struct {
379 bool upper;
380 char *in;
381 char *out;
382 } testdata_t;
383
384 testdata_t test[] = {
385 {TRUE, "", ""},
386 {TRUE, "f", "66"},
387 {TRUE, "fo", "666F"},
388 {TRUE, "foo", "666F6F"},
389 {TRUE, "foob", "666F6F62"},
390 {TRUE, "fooba", "666F6F6261"},
391 {TRUE, "foobar", "666F6F626172"},
392 {FALSE, "", ""},
393 {FALSE, "f", "66"},
394 {FALSE, "fo", "666f"},
395 {FALSE, "foo", "666f6f"},
396 {FALSE, "foob", "666f6f62"},
397 {FALSE, "fooba", "666f6f6261"},
398 {FALSE, "foobar", "666f6f626172"},
399 };
400 testdata_t test_prefix_colon[] = {
401 {TRUE, "", "0x"},
402 {TRUE, "f", "0x66"},
403 {TRUE, "fo", "66:6F"},
404 {TRUE, "foo", "0x66:6F:6F"},
405 {FALSE, "foob", "66:6f:6f:62"},
406 {FALSE, "fooba", "0x66:6f:6f:62:61"},
407 {FALSE, "foobar", "66:6f:6f:62:61:72"},
408 {FALSE, "foobar", "0x66:6f6f:6261:72"},
409 };
410 int i;
411
412 for (i = 0; i < countof(test); i++)
413 {
414 chunk_t out;
415
416 out = chunk_to_hex(chunk_create(test[i].in, strlen(test[i].in)), NULL,
417 test[i].upper);
418 ck_assert_str_eq(out.ptr, test[i].out);
419 free(out.ptr);
420 }
421
422 for (i = 0; i < countof(test); i++)
423 {
424 chunk_t out;
425
426 out = chunk_from_hex(chunk_create(test[i].out, strlen(test[i].out)), NULL);
427 fail_unless(strneq(out.ptr, test[i].in, out.len),
428 "base16 conversion error - should '%s', is %#B",
429 test[i].in, &out);
430 free(out.ptr);
431 }
432
433 for (i = 0; i < countof(test_prefix_colon); i++)
434 {
435 chunk_t out;
436
437 out = chunk_from_hex(chunk_create(test_prefix_colon[i].out,
438 strlen(test_prefix_colon[i].out)), NULL);
439 fail_unless(strneq(out.ptr, test_prefix_colon[i].in, out.len),
440 "base16 conversion error - should '%s', is %#B",
441 test_prefix_colon[i].in, &out);
442 free(out.ptr);
443 }
444 }
445 END_TEST
446
447 /*******************************************************************************
448 * BASE64 encoding test
449 */
450
451 START_TEST(test_base64)
452 {
453 /* test vectors from RFC 4648:
454 *
455 * BASE64("") = ""
456 * BASE64("f") = "Zg=="
457 * BASE64("fo") = "Zm8="
458 * BASE64("foo") = "Zm9v"
459 * BASE64("foob") = "Zm9vYg=="
460 * BASE64("fooba") = "Zm9vYmE="
461 * BASE64("foobar") = "Zm9vYmFy"
462 */
463 typedef struct {
464 char *in;
465 char *out;
466 } testdata_t;
467
468 testdata_t test[] = {
469 {"", ""},
470 {"f", "Zg=="},
471 {"fo", "Zm8="},
472 {"foo", "Zm9v"},
473 {"foob", "Zm9vYg=="},
474 {"fooba", "Zm9vYmE="},
475 {"foobar", "Zm9vYmFy"},
476 };
477 int i;
478
479 for (i = 0; i < countof(test); i++)
480 {
481 chunk_t out;
482
483 out = chunk_to_base64(chunk_create(test[i].in, strlen(test[i].in)), NULL);
484 ck_assert_str_eq(out.ptr, test[i].out);
485 free(out.ptr);
486 }
487
488 for (i = 0; i < countof(test); i++)
489 {
490 chunk_t out;
491
492 out = chunk_from_base64(chunk_create(test[i].out, strlen(test[i].out)), NULL);
493 fail_unless(strneq(out.ptr, test[i].in, out.len),
494 "base64 conversion error - should '%s', is %#B",
495 test[i].in, &out);
496 free(out.ptr);
497 }
498 }
499 END_TEST
500
501 /*******************************************************************************
502 * BASE32 encoding test
503 */
504
505 START_TEST(test_base32)
506 {
507 /* test vectors from RFC 4648:
508 *
509 * BASE32("") = ""
510 * BASE32("f") = "MY======"
511 * BASE32("fo") = "MZXQ===="
512 * BASE32("foo") = "MZXW6==="
513 * BASE32("foob") = "MZXW6YQ="
514 * BASE32("fooba") = "MZXW6YTB"
515 * BASE32("foobar") = "MZXW6YTBOI======"
516 */
517 typedef struct {
518 char *in;
519 char *out;
520 } testdata_t;
521
522 testdata_t test[] = {
523 {"", ""},
524 {"f", "MY======"},
525 {"fo", "MZXQ===="},
526 {"foo", "MZXW6==="},
527 {"foob", "MZXW6YQ="},
528 {"fooba", "MZXW6YTB"},
529 {"foobar", "MZXW6YTBOI======"},
530 };
531 int i;
532
533 for (i = 0; i < countof(test); i++)
534 {
535 chunk_t out;
536
537 out = chunk_to_base32(chunk_create(test[i].in, strlen(test[i].in)), NULL);
538 ck_assert_str_eq(out.ptr, test[i].out);
539 free(out.ptr);
540 }
541 }
542 END_TEST
543
544 /*******************************************************************************
545 * chunk_increment test
546 */
547
548 static struct {
549 bool overflow;
550 chunk_t in;
551 chunk_t out;
552 } increment_data[] = {
553 {TRUE, { NULL, 0 }, { NULL, 0 }},
554 {FALSE, chunk_from_chars(0x00), chunk_from_chars(0x01)},
555 {FALSE, chunk_from_chars(0xfe), chunk_from_chars(0xff)},
556 {TRUE, chunk_from_chars(0xff), chunk_from_chars(0x00)},
557 {FALSE, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
558 {FALSE, chunk_from_chars(0x00, 0xff), chunk_from_chars(0x01, 0x00)},
559 {FALSE, chunk_from_chars(0xfe, 0xff), chunk_from_chars(0xff, 0x00)},
560 {TRUE, chunk_from_chars(0xff, 0xff), chunk_from_chars(0x00, 0x00)},
561 };
562
563 START_TEST(test_increment)
564 {
565 chunk_t chunk;
566 bool overflow;
567
568 chunk = chunk_clonea(increment_data[_i].in);
569 overflow = chunk_increment(chunk);
570 ck_assert(overflow == increment_data[_i].overflow);
571 ck_assert(!increment_data[_i].out.ptr ||
572 chunk_equals(chunk, increment_data[_i].out));
573 }
574 END_TEST
575
576 /*******************************************************************************
577 * chunk_copy_pad tests
578 */
579
580 static struct {
581 size_t len;
582 u_char chr;
583 chunk_t src;
584 chunk_t exp;
585 } copy_pad_data[] = {
586 {0, 0x00, { NULL, 0 }, { NULL, 0 }},
587 {4, 0x00, { NULL, 0 }, chunk_from_chars(0x00,0x00,0x00,0x00)},
588 {0, 0x00, chunk_from_chars(0x01), { NULL, 0 }},
589 {1, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x01)},
590 {2, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x01)},
591 {3, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x00,0x01)},
592 {4, 0x00, chunk_from_chars(0x01), chunk_from_chars(0x00,0x00,0x00,0x01)},
593 {4, 0x02, chunk_from_chars(0x01), chunk_from_chars(0x02,0x02,0x02,0x01)},
594 {1, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x04)},
595 {2, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x03,0x04)},
596 {3, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x02,0x03,0x04)},
597 {4, 0x00, chunk_from_chars(0x01,0x02,0x03,0x04), chunk_from_chars(0x01,0x02,0x03,0x04)},
598 };
599
600 START_TEST(test_copy_pad)
601 {
602 chunk_t chunk;
603
604 chunk = chunk_copy_pad(chunk_alloca(copy_pad_data[_i].len),
605 copy_pad_data[_i].src, copy_pad_data[_i].chr);
606 ck_assert_chunk_eq(chunk, copy_pad_data[_i].exp);
607 }
608 END_TEST
609
610 /*******************************************************************************
611 * chunk_printable tests
612 */
613
614 static struct {
615 bool printable;
616 chunk_t in;
617 char *out;
618 } printable_data[] = {
619 {TRUE, chunk_from_chars(0x31), "1"},
620 {FALSE, chunk_from_chars(0x00), "?"},
621 {FALSE, chunk_from_chars(0x31, 0x00), "1?"},
622 {FALSE, chunk_from_chars(0x00, 0x31), "?1"},
623 {TRUE, chunk_from_chars(0x3f, 0x31), "?1"},
624 {FALSE, chunk_from_chars(0x00, 0x31, 0x00), "?1?"},
625 {FALSE, chunk_from_chars(0x00, 0x31, 0x00, 0x32), "?1?2"},
626 };
627
628 START_TEST(test_printable)
629 {
630 bool printable;
631
632 printable = chunk_printable(printable_data[_i].in, NULL, ' ');
633 ck_assert(printable == printable_data[_i].printable);
634 }
635 END_TEST
636
637 START_TEST(test_printable_sanitize)
638 {
639 chunk_t sane, expected;
640 bool printable;
641
642 printable = chunk_printable(printable_data[_i].in, &sane, '?');
643 ck_assert(printable == printable_data[_i].printable);
644 expected = chunk_from_str(printable_data[_i].out);
645 ck_assert(chunk_equals(sane, expected));
646 chunk_free(&sane);
647 }
648 END_TEST
649
650 START_TEST(test_printable_empty)
651 {
652 chunk_t sane;
653 bool printable;
654
655 printable = chunk_printable(chunk_empty, NULL, ' ');
656 ck_assert(printable);
657
658 sane.ptr = (void*)1;
659 sane.len = 1;
660 printable = chunk_printable(chunk_empty, &sane, ' ');
661 ck_assert(printable);
662 assert_chunk_empty(sane);
663 }
664 END_TEST
665
666 /*******************************************************************************
667 * test for chunk_mac(), i.e. SipHash-2-4
668 */
669
670 /**
671 * SipHash-2-4 output with
672 * k = 00 01 02 ...
673 * and
674 * in = (empty string)
675 * in = 00 (1 byte)
676 * in = 00 01 (2 bytes)
677 * in = 00 01 02 (3 bytes)
678 * ...
679 * in = 00 01 02 ... 3e (63 bytes)
680 */
681 static const u_char sip_vectors[64][8] =
682 {
683 { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
684 { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
685 { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
686 { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
687 { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
688 { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
689 { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
690 { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
691 { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
692 { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
693 { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
694 { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
695 { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
696 { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
697 { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
698 { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
699 { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
700 { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
701 { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
702 { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
703 { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
704 { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
705 { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
706 { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
707 { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
708 { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
709 { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
710 { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
711 { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
712 { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
713 { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
714 { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
715 { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
716 { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
717 { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
718 { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
719 { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
720 { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
721 { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
722 { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
723 { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
724 { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
725 { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
726 { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
727 { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
728 { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
729 { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
730 { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
731 { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
732 { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
733 { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
734 { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
735 { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
736 { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
737 { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
738 { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
739 { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
740 { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
741 { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
742 { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
743 { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
744 { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
745 { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
746 { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
747 };
748
749 /**
750 * Our SipHash-2-4 implementation returns the result in host order, which
751 * doesn't matter for practical purposes and even avoids a byte swap. But
752 * because the test vectors are in little-endian we have to account for this
753 * with this custom comparison function.
754 */
755 static inline bool sipeq(const void *a, const void *b, size_t n)
756 {
757 u_char *ap = (u_char*)a, *bp = (u_char*)b;
758 int i;
759
760 for (i = 0; i < n; i++)
761 {
762 #ifdef WORDS_BIGENDIAN
763 if (ap[i] != bp[n - i - 1])
764 #else
765 if (ap[i] != bp[i])
766 #endif
767 {
768 return FALSE;
769 }
770 }
771 return TRUE;
772 }
773
774 START_TEST(test_chunk_mac)
775 {
776 chunk_t in;
777 u_char key[16];
778 uint64_t out;
779 int i, count;
780
781 count = countof(sip_vectors);
782 in = chunk_alloca(count);
783
784 for (i = 0; i < 16; ++i)
785 {
786 key[i] = i;
787 }
788
789 for (i = 0; i < count; ++i)
790 {
791 in.ptr[i] = i;
792 in.len = i;
793 out = chunk_mac(in, key);
794 fail_unless(sipeq(&out, sip_vectors[i], 8),
795 "test vector failed for %d bytes", i);
796 }
797 }
798 END_TEST
799
800 /*******************************************************************************
801 * test for chunk_hash[_inc]()
802 */
803
804 START_TEST(test_chunk_hash)
805 {
806 chunk_t chunk;
807 uint32_t hash_a, hash_b, hash_c;
808
809 chunk = chunk_from_str("asdf");
810
811 /* output is randomized, so there are no test-vectors we could use */
812 hash_a = chunk_hash(chunk);
813 hash_b = chunk_hash(chunk);
814 ck_assert(hash_a == hash_b);
815 hash_b = chunk_hash_inc(chunk, hash_a);
816 ck_assert(hash_a != hash_b);
817 hash_c = chunk_hash_inc(chunk, hash_a);
818 ck_assert(hash_b == hash_c);
819 }
820 END_TEST
821
822 /*******************************************************************************
823 * test for chunk_hash_static[_inc]()
824 */
825
826 START_TEST(test_chunk_hash_static)
827 {
828 chunk_t in;
829 uint32_t out, hash_a, hash_b, hash_inc = 0x7b891a95;
830 int i, count;
831
832 count = countof(sip_vectors);
833 in = chunk_alloca(count);
834
835 for (i = 0; i < count; ++i)
836 {
837 in.ptr[i] = i;
838 in.len = i;
839 /* compared to chunk_mac() we only get half the value back */
840 out = chunk_hash_static(in);
841 fail_unless(sipeq(&out, sip_vectors[i], 4),
842 "test vector failed for %d bytes", i);
843 }
844 hash_a = chunk_hash_static_inc(in, out);
845 ck_assert_int_eq(hash_a, hash_inc);
846 hash_b = chunk_hash_static_inc(in, out);
847 ck_assert_int_eq(hash_a, hash_b);
848 }
849 END_TEST
850
851 /*******************************************************************************
852 * test for chunk_internet_checksum[_inc]()
853 */
854
855 static inline uint16_t compensate_alignment(uint16_t val)
856 {
857 return ((val & 0xff) << 8) | (val >> 8);
858 }
859
860 START_TEST(test_chunk_internet_checksum)
861 {
862 chunk_t chunk;
863 uint16_t sum;
864
865 chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06,
866 0x00,0x00,0x8c,0x7c,0x19,0xac,0xae,0x24,0x1e,0x2b);
867
868 sum = chunk_internet_checksum(chunk);
869 ck_assert_int_eq(0x442e, ntohs(sum));
870
871 sum = chunk_internet_checksum(chunk_create(chunk.ptr, 10));
872 sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+10, 10), sum);
873 ck_assert_int_eq(0x442e, ntohs(sum));
874
875 /* need to compensate for even/odd alignment */
876 sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
877 sum = compensate_alignment(sum);
878 sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 11), sum);
879 sum = compensate_alignment(sum);
880 ck_assert_int_eq(0x442e, ntohs(sum));
881
882 chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06,
883 0x00,0x00,0x8c,0x7c,0x19,0xac,0xae,0x24,0x1e);
884
885 sum = chunk_internet_checksum(chunk);
886 ck_assert_int_eq(0x4459, ntohs(sum));
887
888 sum = chunk_internet_checksum(chunk_create(chunk.ptr, 10));
889 sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+10, 9), sum);
890 ck_assert_int_eq(0x4459, ntohs(sum));
891
892 /* need to compensate for even/odd alignment */
893 sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
894 sum = compensate_alignment(sum);
895 sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 10), sum);
896 sum = compensate_alignment(sum);
897 ck_assert_int_eq(0x4459, ntohs(sum));
898 }
899 END_TEST
900
901 /*******************************************************************************
902 * test for chunk_map and friends
903 */
904
905 START_TEST(test_chunk_map)
906 {
907 chunk_t *map, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05);
908 #ifdef WIN32
909 char *path = "C:\\Windows\\Temp\\strongswan-chunk-map-test";
910 #else
911 char *path = "/tmp/strongswan-chunk-map-test";
912 #endif
913
914 ck_assert(chunk_write(contents, path, 022, TRUE));
915
916 /* read */
917 map = chunk_map(path, FALSE);
918 ck_assert(map != NULL);
919 ck_assert_msg(chunk_equals(*map, contents), "%B", map);
920 /* altering mapped chunk should not hurt */
921 *map = chunk_empty;
922 ck_assert(chunk_unmap(map));
923
924 /* write */
925 map = chunk_map(path, TRUE);
926 ck_assert(map != NULL);
927 ck_assert_msg(chunk_equals(*map, contents), "%B", map);
928 map->ptr[0] = 0x06;
929 ck_assert(chunk_unmap(map));
930
931 /* verify write */
932 contents.ptr[0] = 0x06;
933 map = chunk_map(path, FALSE);
934 ck_assert(map != NULL);
935 ck_assert_msg(chunk_equals(*map, contents), "%B", map);
936 ck_assert(chunk_unmap(map));
937
938 unlink(path);
939 }
940 END_TEST
941
942 /*******************************************************************************
943 * test for chunk_from_fd
944 */
945
946 START_TEST(test_chunk_from_fd_file)
947 {
948 chunk_t in, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05);
949 #ifdef WIN32
950 char *path = "C:\\Windows\\Temp\\strongswan-chunk-fd-test";
951 #else
952 char *path = "/tmp/strongswan-chunk-fd-test";
953 #endif
954 int fd;
955
956 ck_assert(chunk_write(contents, path, 022, TRUE));
957
958 fd = open(path, O_RDONLY);
959 ck_assert(fd != -1);
960
961 ck_assert(chunk_from_fd(fd, &in));
962 close(fd);
963 ck_assert_msg(chunk_equals(in, contents), "%B", &in);
964 unlink(path);
965 free(in.ptr);
966 }
967 END_TEST
968
969 START_TEST(test_chunk_from_fd_skt)
970 {
971 chunk_t in, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05);
972 int s[2];
973
974 ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0);
975 ck_assert_int_eq(send(s[1], contents.ptr, contents.len, 0), contents.len);
976 close(s[1]);
977 ck_assert_msg(chunk_from_fd(s[0], &in), "%s", strerror(errno));
978 close(s[0]);
979 ck_assert_msg(chunk_equals(in, contents), "%B", &in);
980 free(in.ptr);
981 }
982 END_TEST
983
984 #define FROM_FD_COUNT 8192
985
986 void *chunk_from_fd_run(void *data)
987 {
988 int i, fd = (uintptr_t)data;
989
990 for (i = 0; i < FROM_FD_COUNT; i++)
991 {
992 ck_assert(send(fd, &i, sizeof(i), 0) == sizeof(i));
993 }
994 close(fd);
995 return NULL;
996 }
997
998 START_TEST(test_chunk_from_fd_huge)
999 {
1000 thread_t *thread;
1001 chunk_t in;
1002 int s[2], i;
1003
1004 ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0);
1005
1006 thread = thread_create(chunk_from_fd_run, (void*)(uintptr_t)s[1]);
1007 ck_assert_msg(chunk_from_fd(s[0], &in), "%s", strerror(errno));
1008 ck_assert_int_eq(in.len, FROM_FD_COUNT * sizeof(i));
1009 for (i = 0; i < FROM_FD_COUNT; i++)
1010 {
1011 ck_assert_int_eq(((int*)in.ptr)[i], i);
1012 }
1013 thread->join(thread);
1014 close(s[0]);
1015 free(in.ptr);
1016 }
1017 END_TEST
1018
1019 /*******************************************************************************
1020 * printf_hook tests
1021 */
1022
1023 static struct {
1024 chunk_t in;
1025 char *out;
1026 char *out_plus;
1027 } printf_hook_data[] = {
1028 {chunk_from_chars(), "", ""},
1029 {chunk_from_chars(0x00), "00", "00"},
1030 {chunk_from_chars(0x00, 0x01), "00:01", "0001"},
1031 {chunk_from_chars(0x00, 0x01, 0x02), "00:01:02", "000102"},
1032 };
1033
1034 START_TEST(test_printf_hook_hash)
1035 {
1036 char buf[16];
1037 int len;
1038
1039 len = snprintf(buf, sizeof(buf), "%#B", &printf_hook_data[_i].in);
1040 ck_assert(len >= 0 && len < sizeof(buf));
1041 ck_assert_str_eq(buf, printf_hook_data[_i].out);
1042 }
1043 END_TEST
1044
1045 START_TEST(test_printf_hook_plus)
1046 {
1047 char buf[16];
1048 int len;
1049
1050 len = snprintf(buf, sizeof(buf), "%+B", &printf_hook_data[_i].in);
1051 ck_assert(len >= 0 && len < sizeof(buf));
1052 ck_assert_str_eq(buf, printf_hook_data[_i].out_plus);
1053 }
1054 END_TEST
1055
1056 START_TEST(test_printf_hook)
1057 {
1058 char buf[128], mem[128];
1059 int len;
1060
1061 /* %B should be the same as %b, which is what we check, comparing the
1062 * actual result could be tricky as %b prints the chunk's memory address */
1063 len = snprintf(buf, sizeof(buf), "%B", &printf_hook_data[_i].in);
1064 ck_assert(len >= 0 && len < sizeof(buf));
1065 len = snprintf(mem, sizeof(mem), "%b", printf_hook_data[_i].in.ptr,
1066 (u_int)printf_hook_data[_i].in.len);
1067 ck_assert(len >= 0 && len < sizeof(mem));
1068 ck_assert_str_eq(buf, mem);
1069 }
1070 END_TEST
1071
1072 Suite *chunk_suite_create()
1073 {
1074 Suite *s;
1075 TCase *tc;
1076
1077 s = suite_create("chunk");
1078
1079 tc = tcase_create("equals");
1080 tcase_add_test(tc, test_chunk_equals);
1081 tcase_add_test(tc, test_chunk_equals_const);
1082 suite_add_tcase(s, tc);
1083
1084 tc = tcase_create("chunk_compare");
1085 tcase_add_loop_test(tc, test_compare, 0, countof(compare_data));
1086 suite_add_tcase(s, tc);
1087
1088 tc = tcase_create("clear");
1089 tcase_add_test(tc, test_chunk_clear);
1090 suite_add_tcase(s, tc);
1091
1092 tc = tcase_create("chunk_length");
1093 tcase_add_test(tc, test_chunk_length);
1094 suite_add_tcase(s, tc);
1095
1096 tc = tcase_create("chunk_create_cat");
1097 tcase_add_test(tc, test_chunk_create_cat);
1098 suite_add_tcase(s, tc);
1099
1100 tc = tcase_create("chunk_split");
1101 tcase_add_test(tc, test_chunk_split);
1102 suite_add_tcase(s, tc);
1103
1104 tc = tcase_create("chunk_skip");
1105 tcase_add_test(tc, test_chunk_skip);
1106 tcase_add_test(tc, test_chunk_skip_zero);
1107 suite_add_tcase(s, tc);
1108
1109 tc = tcase_create("chunk_increment");
1110 tcase_add_loop_test(tc, test_increment, 0, countof(increment_data));
1111 suite_add_tcase(s, tc);
1112
1113 tc = tcase_create("chunk_copy_pad");
1114 tcase_add_loop_test(tc, test_copy_pad, 0, countof(copy_pad_data));
1115 suite_add_tcase(s, tc);
1116
1117 tc = tcase_create("chunk_printable");
1118 tcase_add_loop_test(tc, test_printable, 0, countof(printable_data));
1119 tcase_add_loop_test(tc, test_printable_sanitize, 0, countof(printable_data));
1120 tcase_add_test(tc, test_printable_empty);
1121 suite_add_tcase(s, tc);
1122
1123 tc = tcase_create("baseXX");
1124 tcase_add_test(tc, test_base64);
1125 tcase_add_test(tc, test_base32);
1126 tcase_add_test(tc, test_base16);
1127 suite_add_tcase(s, tc);
1128
1129 tc = tcase_create("chunk_mac");
1130 tcase_add_test(tc, test_chunk_mac);
1131 suite_add_tcase(s, tc);
1132
1133 tc = tcase_create("chunk_hash");
1134 tcase_add_test(tc, test_chunk_hash);
1135 suite_add_tcase(s, tc);
1136
1137 tc = tcase_create("chunk_hash_static");
1138 tcase_add_test(tc, test_chunk_hash_static);
1139 suite_add_tcase(s, tc);
1140
1141 tc = tcase_create("chunk_internet_checksum");
1142 tcase_add_test(tc, test_chunk_internet_checksum);
1143 suite_add_tcase(s, tc);
1144
1145 tc = tcase_create("chunk_map");
1146 tcase_add_test(tc, test_chunk_map);
1147 suite_add_tcase(s, tc);
1148
1149 tc = tcase_create("chunk_from_fd");
1150 tcase_add_test(tc, test_chunk_from_fd_file);
1151 tcase_add_test(tc, test_chunk_from_fd_skt);
1152 tcase_add_test(tc, test_chunk_from_fd_huge);
1153 suite_add_tcase(s, tc);
1154
1155 tc = tcase_create("printf_hook");
1156 tcase_add_loop_test(tc, test_printf_hook_hash, 0, countof(printf_hook_data));
1157 tcase_add_loop_test(tc, test_printf_hook_plus, 0, countof(printf_hook_data));
1158 tcase_add_loop_test(tc, test_printf_hook, 0, countof(printf_hook_data));
1159 suite_add_tcase(s, tc);
1160
1161 return s;
1162 }