fbfb3ff9f829ee3bad83d3303277c59c1bcd0077
[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_printable tests
578 */
579
580 static struct {
581 bool printable;
582 chunk_t in;
583 char *out;
584 } printable_data[] = {
585 {TRUE, chunk_from_chars(0x31), "1"},
586 {FALSE, chunk_from_chars(0x00), "?"},
587 {FALSE, chunk_from_chars(0x31, 0x00), "1?"},
588 {FALSE, chunk_from_chars(0x00, 0x31), "?1"},
589 {TRUE, chunk_from_chars(0x3f, 0x31), "?1"},
590 {FALSE, chunk_from_chars(0x00, 0x31, 0x00), "?1?"},
591 {FALSE, chunk_from_chars(0x00, 0x31, 0x00, 0x32), "?1?2"},
592 };
593
594 START_TEST(test_printable)
595 {
596 bool printable;
597
598 printable = chunk_printable(printable_data[_i].in, NULL, ' ');
599 ck_assert(printable == printable_data[_i].printable);
600 }
601 END_TEST
602
603 START_TEST(test_printable_sanitize)
604 {
605 chunk_t sane, expected;
606 bool printable;
607
608 printable = chunk_printable(printable_data[_i].in, &sane, '?');
609 ck_assert(printable == printable_data[_i].printable);
610 expected = chunk_from_str(printable_data[_i].out);
611 ck_assert(chunk_equals(sane, expected));
612 chunk_free(&sane);
613 }
614 END_TEST
615
616 START_TEST(test_printable_empty)
617 {
618 chunk_t sane;
619 bool printable;
620
621 printable = chunk_printable(chunk_empty, NULL, ' ');
622 ck_assert(printable);
623
624 sane.ptr = (void*)1;
625 sane.len = 1;
626 printable = chunk_printable(chunk_empty, &sane, ' ');
627 ck_assert(printable);
628 assert_chunk_empty(sane);
629 }
630 END_TEST
631
632 /*******************************************************************************
633 * test for chunk_mac(), i.e. SipHash-2-4
634 */
635
636 /**
637 * SipHash-2-4 output with
638 * k = 00 01 02 ...
639 * and
640 * in = (empty string)
641 * in = 00 (1 byte)
642 * in = 00 01 (2 bytes)
643 * in = 00 01 02 (3 bytes)
644 * ...
645 * in = 00 01 02 ... 3e (63 bytes)
646 */
647 static const u_char sip_vectors[64][8] =
648 {
649 { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
650 { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
651 { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
652 { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
653 { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
654 { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
655 { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
656 { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
657 { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
658 { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
659 { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
660 { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
661 { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
662 { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
663 { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
664 { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
665 { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
666 { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
667 { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
668 { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
669 { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
670 { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
671 { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
672 { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
673 { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
674 { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
675 { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
676 { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
677 { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
678 { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
679 { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
680 { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
681 { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
682 { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
683 { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
684 { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
685 { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
686 { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
687 { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
688 { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
689 { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
690 { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
691 { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
692 { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
693 { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
694 { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
695 { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
696 { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
697 { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
698 { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
699 { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
700 { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
701 { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
702 { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
703 { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
704 { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
705 { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
706 { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
707 { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
708 { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
709 { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
710 { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
711 { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
712 { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
713 };
714
715 /**
716 * Our SipHash-2-4 implementation returns the result in host order, which
717 * doesn't matter for practical purposes and even avoids a byte swap. But
718 * because the test vectors are in little-endian we have to account for this
719 * with this custom comparison function.
720 */
721 static inline bool sipeq(const void *a, const void *b, size_t n)
722 {
723 u_char *ap = (u_char*)a, *bp = (u_char*)b;
724 int i;
725
726 for (i = 0; i < n; i++)
727 {
728 #ifdef WORDS_BIGENDIAN
729 if (ap[i] != bp[n - i - 1])
730 #else
731 if (ap[i] != bp[i])
732 #endif
733 {
734 return FALSE;
735 }
736 }
737 return TRUE;
738 }
739
740 START_TEST(test_chunk_mac)
741 {
742 chunk_t in;
743 u_char key[16];
744 uint64_t out;
745 int i, count;
746
747 count = countof(sip_vectors);
748 in = chunk_alloca(count);
749
750 for (i = 0; i < 16; ++i)
751 {
752 key[i] = i;
753 }
754
755 for (i = 0; i < count; ++i)
756 {
757 in.ptr[i] = i;
758 in.len = i;
759 out = chunk_mac(in, key);
760 fail_unless(sipeq(&out, sip_vectors[i], 8),
761 "test vector failed for %d bytes", i);
762 }
763 }
764 END_TEST
765
766 /*******************************************************************************
767 * test for chunk_hash[_inc]()
768 */
769
770 START_TEST(test_chunk_hash)
771 {
772 chunk_t chunk;
773 uint32_t hash_a, hash_b, hash_c;
774
775 chunk = chunk_from_str("asdf");
776
777 /* output is randomized, so there are no test-vectors we could use */
778 hash_a = chunk_hash(chunk);
779 hash_b = chunk_hash(chunk);
780 ck_assert(hash_a == hash_b);
781 hash_b = chunk_hash_inc(chunk, hash_a);
782 ck_assert(hash_a != hash_b);
783 hash_c = chunk_hash_inc(chunk, hash_a);
784 ck_assert(hash_b == hash_c);
785 }
786 END_TEST
787
788 /*******************************************************************************
789 * test for chunk_hash_static[_inc]()
790 */
791
792 START_TEST(test_chunk_hash_static)
793 {
794 chunk_t in;
795 uint32_t out, hash_a, hash_b, hash_inc = 0x7b891a95;
796 int i, count;
797
798 count = countof(sip_vectors);
799 in = chunk_alloca(count);
800
801 for (i = 0; i < count; ++i)
802 {
803 in.ptr[i] = i;
804 in.len = i;
805 /* compared to chunk_mac() we only get half the value back */
806 out = chunk_hash_static(in);
807 fail_unless(sipeq(&out, sip_vectors[i], 4),
808 "test vector failed for %d bytes", i);
809 }
810 hash_a = chunk_hash_static_inc(in, out);
811 ck_assert_int_eq(hash_a, hash_inc);
812 hash_b = chunk_hash_static_inc(in, out);
813 ck_assert_int_eq(hash_a, hash_b);
814 }
815 END_TEST
816
817 /*******************************************************************************
818 * test for chunk_internet_checksum[_inc]()
819 */
820
821 static inline uint16_t compensate_alignment(uint16_t val)
822 {
823 return ((val & 0xff) << 8) | (val >> 8);
824 }
825
826 START_TEST(test_chunk_internet_checksum)
827 {
828 chunk_t chunk;
829 uint16_t sum;
830
831 chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06,
832 0x00,0x00,0x8c,0x7c,0x19,0xac,0xae,0x24,0x1e,0x2b);
833
834 sum = chunk_internet_checksum(chunk);
835 ck_assert_int_eq(0x442e, ntohs(sum));
836
837 sum = chunk_internet_checksum(chunk_create(chunk.ptr, 10));
838 sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+10, 10), sum);
839 ck_assert_int_eq(0x442e, ntohs(sum));
840
841 /* need to compensate for even/odd alignment */
842 sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
843 sum = compensate_alignment(sum);
844 sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 11), sum);
845 sum = compensate_alignment(sum);
846 ck_assert_int_eq(0x442e, ntohs(sum));
847
848 chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06,
849 0x00,0x00,0x8c,0x7c,0x19,0xac,0xae,0x24,0x1e);
850
851 sum = chunk_internet_checksum(chunk);
852 ck_assert_int_eq(0x4459, ntohs(sum));
853
854 sum = chunk_internet_checksum(chunk_create(chunk.ptr, 10));
855 sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+10, 9), sum);
856 ck_assert_int_eq(0x4459, ntohs(sum));
857
858 /* need to compensate for even/odd alignment */
859 sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
860 sum = compensate_alignment(sum);
861 sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 10), sum);
862 sum = compensate_alignment(sum);
863 ck_assert_int_eq(0x4459, ntohs(sum));
864 }
865 END_TEST
866
867 /*******************************************************************************
868 * test for chunk_map and friends
869 */
870
871 START_TEST(test_chunk_map)
872 {
873 chunk_t *map, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05);
874 #ifdef WIN32
875 char *path = "C:\\Windows\\Temp\\strongswan-chunk-map-test";
876 #else
877 char *path = "/tmp/strongswan-chunk-map-test";
878 #endif
879
880 ck_assert(chunk_write(contents, path, 022, TRUE));
881
882 /* read */
883 map = chunk_map(path, FALSE);
884 ck_assert(map != NULL);
885 ck_assert_msg(chunk_equals(*map, contents), "%B", map);
886 /* altering mapped chunk should not hurt */
887 *map = chunk_empty;
888 ck_assert(chunk_unmap(map));
889
890 /* write */
891 map = chunk_map(path, TRUE);
892 ck_assert(map != NULL);
893 ck_assert_msg(chunk_equals(*map, contents), "%B", map);
894 map->ptr[0] = 0x06;
895 ck_assert(chunk_unmap(map));
896
897 /* verify write */
898 contents.ptr[0] = 0x06;
899 map = chunk_map(path, FALSE);
900 ck_assert(map != NULL);
901 ck_assert_msg(chunk_equals(*map, contents), "%B", map);
902 ck_assert(chunk_unmap(map));
903
904 unlink(path);
905 }
906 END_TEST
907
908 /*******************************************************************************
909 * test for chunk_from_fd
910 */
911
912 START_TEST(test_chunk_from_fd_file)
913 {
914 chunk_t in, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05);
915 #ifdef WIN32
916 char *path = "C:\\Windows\\Temp\\strongswan-chunk-fd-test";
917 #else
918 char *path = "/tmp/strongswan-chunk-fd-test";
919 #endif
920 int fd;
921
922 ck_assert(chunk_write(contents, path, 022, TRUE));
923
924 fd = open(path, O_RDONLY);
925 ck_assert(fd != -1);
926
927 ck_assert(chunk_from_fd(fd, &in));
928 close(fd);
929 ck_assert_msg(chunk_equals(in, contents), "%B", &in);
930 unlink(path);
931 free(in.ptr);
932 }
933 END_TEST
934
935 START_TEST(test_chunk_from_fd_skt)
936 {
937 chunk_t in, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05);
938 int s[2];
939
940 ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0);
941 ck_assert_int_eq(send(s[1], contents.ptr, contents.len, 0), contents.len);
942 close(s[1]);
943 ck_assert_msg(chunk_from_fd(s[0], &in), "%s", strerror(errno));
944 close(s[0]);
945 ck_assert_msg(chunk_equals(in, contents), "%B", &in);
946 free(in.ptr);
947 }
948 END_TEST
949
950 #define FROM_FD_COUNT 8192
951
952 void *chunk_from_fd_run(void *data)
953 {
954 int i, fd = (uintptr_t)data;
955
956 for (i = 0; i < FROM_FD_COUNT; i++)
957 {
958 ck_assert(send(fd, &i, sizeof(i), 0) == sizeof(i));
959 }
960 close(fd);
961 return NULL;
962 }
963
964 START_TEST(test_chunk_from_fd_huge)
965 {
966 thread_t *thread;
967 chunk_t in;
968 int s[2], i;
969
970 ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0);
971
972 thread = thread_create(chunk_from_fd_run, (void*)(uintptr_t)s[1]);
973 ck_assert_msg(chunk_from_fd(s[0], &in), "%s", strerror(errno));
974 ck_assert_int_eq(in.len, FROM_FD_COUNT * sizeof(i));
975 for (i = 0; i < FROM_FD_COUNT; i++)
976 {
977 ck_assert_int_eq(((int*)in.ptr)[i], i);
978 }
979 thread->join(thread);
980 close(s[0]);
981 free(in.ptr);
982 }
983 END_TEST
984
985 /*******************************************************************************
986 * printf_hook tests
987 */
988
989 static struct {
990 chunk_t in;
991 char *out;
992 char *out_plus;
993 } printf_hook_data[] = {
994 {chunk_from_chars(), "", ""},
995 {chunk_from_chars(0x00), "00", "00"},
996 {chunk_from_chars(0x00, 0x01), "00:01", "0001"},
997 {chunk_from_chars(0x00, 0x01, 0x02), "00:01:02", "000102"},
998 };
999
1000 START_TEST(test_printf_hook_hash)
1001 {
1002 char buf[16];
1003 int len;
1004
1005 len = snprintf(buf, sizeof(buf), "%#B", &printf_hook_data[_i].in);
1006 ck_assert(len >= 0 && len < sizeof(buf));
1007 ck_assert_str_eq(buf, printf_hook_data[_i].out);
1008 }
1009 END_TEST
1010
1011 START_TEST(test_printf_hook_plus)
1012 {
1013 char buf[16];
1014 int len;
1015
1016 len = snprintf(buf, sizeof(buf), "%+B", &printf_hook_data[_i].in);
1017 ck_assert(len >= 0 && len < sizeof(buf));
1018 ck_assert_str_eq(buf, printf_hook_data[_i].out_plus);
1019 }
1020 END_TEST
1021
1022 START_TEST(test_printf_hook)
1023 {
1024 char buf[128], mem[128];
1025 int len;
1026
1027 /* %B should be the same as %b, which is what we check, comparing the
1028 * actual result could be tricky as %b prints the chunk's memory address */
1029 len = snprintf(buf, sizeof(buf), "%B", &printf_hook_data[_i].in);
1030 ck_assert(len >= 0 && len < sizeof(buf));
1031 len = snprintf(mem, sizeof(mem), "%b", printf_hook_data[_i].in.ptr,
1032 (u_int)printf_hook_data[_i].in.len);
1033 ck_assert(len >= 0 && len < sizeof(mem));
1034 ck_assert_str_eq(buf, mem);
1035 }
1036 END_TEST
1037
1038 Suite *chunk_suite_create()
1039 {
1040 Suite *s;
1041 TCase *tc;
1042
1043 s = suite_create("chunk");
1044
1045 tc = tcase_create("equals");
1046 tcase_add_test(tc, test_chunk_equals);
1047 tcase_add_test(tc, test_chunk_equals_const);
1048 suite_add_tcase(s, tc);
1049
1050 tc = tcase_create("chunk_compare");
1051 tcase_add_loop_test(tc, test_compare, 0, countof(compare_data));
1052 suite_add_tcase(s, tc);
1053
1054 tc = tcase_create("clear");
1055 tcase_add_test(tc, test_chunk_clear);
1056 suite_add_tcase(s, tc);
1057
1058 tc = tcase_create("chunk_length");
1059 tcase_add_test(tc, test_chunk_length);
1060 suite_add_tcase(s, tc);
1061
1062 tc = tcase_create("chunk_create_cat");
1063 tcase_add_test(tc, test_chunk_create_cat);
1064 suite_add_tcase(s, tc);
1065
1066 tc = tcase_create("chunk_split");
1067 tcase_add_test(tc, test_chunk_split);
1068 suite_add_tcase(s, tc);
1069
1070 tc = tcase_create("chunk_skip");
1071 tcase_add_test(tc, test_chunk_skip);
1072 tcase_add_test(tc, test_chunk_skip_zero);
1073 suite_add_tcase(s, tc);
1074
1075 tc = tcase_create("chunk_increment");
1076 tcase_add_loop_test(tc, test_increment, 0, countof(increment_data));
1077 suite_add_tcase(s, tc);
1078
1079 tc = tcase_create("chunk_printable");
1080 tcase_add_loop_test(tc, test_printable, 0, countof(printable_data));
1081 tcase_add_loop_test(tc, test_printable_sanitize, 0, countof(printable_data));
1082 tcase_add_test(tc, test_printable_empty);
1083 suite_add_tcase(s, tc);
1084
1085 tc = tcase_create("baseXX");
1086 tcase_add_test(tc, test_base64);
1087 tcase_add_test(tc, test_base32);
1088 tcase_add_test(tc, test_base16);
1089 suite_add_tcase(s, tc);
1090
1091 tc = tcase_create("chunk_mac");
1092 tcase_add_test(tc, test_chunk_mac);
1093 suite_add_tcase(s, tc);
1094
1095 tc = tcase_create("chunk_hash");
1096 tcase_add_test(tc, test_chunk_hash);
1097 suite_add_tcase(s, tc);
1098
1099 tc = tcase_create("chunk_hash_static");
1100 tcase_add_test(tc, test_chunk_hash_static);
1101 suite_add_tcase(s, tc);
1102
1103 tc = tcase_create("chunk_internet_checksum");
1104 tcase_add_test(tc, test_chunk_internet_checksum);
1105 suite_add_tcase(s, tc);
1106
1107 tc = tcase_create("chunk_map");
1108 tcase_add_test(tc, test_chunk_map);
1109 suite_add_tcase(s, tc);
1110
1111 tc = tcase_create("chunk_from_fd");
1112 tcase_add_test(tc, test_chunk_from_fd_file);
1113 tcase_add_test(tc, test_chunk_from_fd_skt);
1114 tcase_add_test(tc, test_chunk_from_fd_huge);
1115 suite_add_tcase(s, tc);
1116
1117 tc = tcase_create("printf_hook");
1118 tcase_add_loop_test(tc, test_printf_hook_hash, 0, countof(printf_hook_data));
1119 tcase_add_loop_test(tc, test_printf_hook_plus, 0, countof(printf_hook_data));
1120 tcase_add_loop_test(tc, test_printf_hook, 0, countof(printf_hook_data));
1121 suite_add_tcase(s, tc);
1122
1123 return s;
1124 }