Annotation of embedaddon/strongswan/src/libstrongswan/tests/suites/test_chunk.c, revision 1.1.1.1
1.1 misho 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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>