summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile4
-rw-r--r--lib/birdlib.h3
-rw-r--r--lib/bitops.h2
-rw-r--r--lib/bitops_test.c123
-rw-r--r--lib/buffer_test.c147
-rw-r--r--lib/checksum_test.c94
-rw-r--r--lib/event_test.c88
-rw-r--r--lib/fletcher16_test.c169
-rw-r--r--lib/hash_test.c305
-rw-r--r--lib/heap_test.c186
-rw-r--r--lib/ip.c2
-rw-r--r--lib/ip_test.c161
-rw-r--r--lib/lists_test.c287
-rw-r--r--lib/mac_test.c1159
-rw-r--r--lib/patmatch_test.c149
-rw-r--r--lib/printf_test.c70
-rw-r--r--lib/slist_test.c384
-rw-r--r--lib/slists.c82
18 files changed, 3330 insertions, 85 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 551089c3..26d8bf65 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,3 +1,7 @@
src := bitops.c checksum.c event.c idm.c ip.c lists.c mac.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
obj := $(src-o-files)
$(all-daemon)
+
+tests_src := heap_test.c buffer_test.c event_test.c bitops_test.c patmatch_test.c fletcher16_test.c slist_test.c checksum_test.c lists_test.c mac_test.c ip_test.c hash_test.c printf_test.c
+tests_targets := $(tests_targets) $(tests-target-files)
+tests_objs := $(tests_objs) $(src-o-files)
diff --git a/lib/birdlib.h b/lib/birdlib.h
index ddc963f4..c352b7f6 100644
--- a/lib/birdlib.h
+++ b/lib/birdlib.h
@@ -56,7 +56,6 @@ static inline int u64_cmp(u64 i1, u64 i2)
#define NULL ((void *) 0)
#endif
-
/* Macros for gcc attributes */
#define NORET __attribute__((noreturn))
@@ -150,7 +149,7 @@ void bug(const char *msg, ...) NORET;
#define L_FATAL "\010" /* Fatal errors */
#define L_BUG "\011" /* BIRD bugs */
-void debug(const char *msg, ...); /* Printf to debug output */
+void debug(const char *msg, ...); /* Printf to debug output */
/* Debugging */
diff --git a/lib/bitops.h b/lib/bitops.h
index 9f954374..af648c26 100644
--- a/lib/bitops.h
+++ b/lib/bitops.h
@@ -9,6 +9,8 @@
#ifndef _BIRD_BITOPTS_H_
#define _BIRD_BITOPTS_H_
+#include "sysdep/config.h"
+
/*
* Bit mask operations:
*
diff --git a/lib/bitops_test.c b/lib/bitops_test.c
new file mode 100644
index 00000000..bd02fccc
--- /dev/null
+++ b/lib/bitops_test.c
@@ -0,0 +1,123 @@
+/*
+ * BIRD Library -- Generic Bit Operations Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+#include "test/bt-utils.h" /* naive_pow() */
+
+#include "lib/bitops.h"
+
+#define MAX_NUM 1000
+#define CHECK_BIT(var,pos) ((var) & (u32)(1<<(pos)))
+
+static int
+t_mkmask(void)
+{
+ int i;
+ u32 compute, expect;
+
+ bt_assert(u32_mkmask(0) == 0x00000000);
+ for (i = 1; i <= 32; i++)
+ {
+ compute = u32_mkmask(i);
+ expect = (u32) (0xffffffff << (32-i));
+ bt_assert_msg(compute == expect, "u32_mkmask(%d) = 0x%08X, expected 0x%08X", i, compute, expect);
+ }
+
+ return BT_SUCCESS;
+}
+
+static int
+u32_masklen_expected(u32 mask)
+{
+ int j, expect = 0;
+
+ int valid = 0;
+ for (j = 0; j <= 32; j++)
+ if (mask == (j ? (0xffffffff << (32-j)) : 0)) /* Shifting 32-bit value by 32 bits is undefined behavior */
+ valid = 1;
+
+ if (!valid && mask != 0)
+ expect = 255;
+ else
+ for (j = 0; j <= 31; j++)
+ if (CHECK_BIT(mask, (31-j)))
+ expect = j+1;
+ else
+ break;
+ return expect;
+}
+
+static void
+check_mask(u32 mask)
+{
+ int expected, masklen;
+
+ expected = u32_masklen_expected(mask);
+ masklen = u32_masklen(mask);
+ int ok = (expected == masklen);
+ bt_debug("u32_masklen(Ox%08x) = %d, expected %d %s\n", mask, masklen, expected, ok ? "OK" : "FAIL!");
+ bt_assert(ok);
+}
+
+static int
+t_masklen(void)
+{
+ u32 i;
+
+ check_mask(0x82828282);
+ check_mask(0x00000000);
+
+ for (i = 0; i <= 32; i++)
+ check_mask(((u32) (i ? (0xffffffff << (32-i)) : 0)) & 0xffffffff); /* Shifting 32-bit value by 32 bits is undefined behavior */
+
+ for (i = 0; i <= MAX_NUM; i++)
+ check_mask(bt_random());
+
+ return BT_SUCCESS;
+}
+
+static void
+check_log2(u32 n)
+{
+ u32 log = u32_log2(n);
+ u32 low = bt_naive_pow(2, log);
+ u32 high = bt_naive_pow(2, log+1);
+
+ bt_assert_msg(n >= low && n < high,
+ "u32_log2(%u) = %u, %u should be in the range <%u, %u)",
+ n, log, n, low, high);
+}
+
+static int
+t_log2(void)
+{
+ u32 i;
+
+ for (i = 0; i < 31; i++)
+ bt_assert(u32_log2(bt_naive_pow(2, i+1)) == i+1);
+
+ for (i = 1; i < MAX_NUM; i++)
+ check_log2(i);
+
+ for (i = 1; i < MAX_NUM; i++)
+ check_log2(((u32) bt_random()) % 0x0fffffff);
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_mkmask, "u32_mkmask()");
+ bt_test_suite(t_masklen, "u32_masklen()");
+ bt_test_suite(t_log2, "u32_log2()");
+
+ return bt_exit_value();
+}
diff --git a/lib/buffer_test.c b/lib/buffer_test.c
new file mode 100644
index 00000000..38e540b7
--- /dev/null
+++ b/lib/buffer_test.c
@@ -0,0 +1,147 @@
+/*
+ * BIRD Library -- Buffer Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdlib.h>
+
+#include "test/birdtest.h"
+
+#include "lib/buffer.h"
+
+#define MAX_NUM 33
+
+typedef BUFFER(int) buffer_int;
+static int expected[MAX_NUM];
+static buffer_int buf;
+static struct pool *buffer_pool;
+
+static void
+show_buf(buffer_int *b)
+{
+ uint i;
+ bt_debug(".used = %d, .size = %d\n", b->used, b->size);
+
+ for (i = 0; i < b->used; i++)
+ bt_debug(" .data[%3u] = %-16d expected %-16d %s\n", i, b->data[i], expected[i], (b->data[i] == expected[i] ? "OK" : "FAIL!"));
+}
+
+static void
+fill_expected_array(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_NUM; i++)
+ expected[i] = bt_random();
+}
+
+static void
+init_buffer(void)
+{
+ resource_init();
+ buffer_pool = &root_pool;
+ BUFFER_INIT(buf, buffer_pool, MAX_NUM);
+}
+
+static int
+is_buffer_as_expected(buffer_int *b)
+{
+ show_buf(b);
+
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ bt_assert(b->data[i] == expected[i]);
+ return 1;
+}
+
+static int
+t_buffer_push(void)
+{
+ int i;
+
+ init_buffer();
+ fill_expected_array();
+
+ for (i = 0; i < MAX_NUM; i++)
+ BUFFER_PUSH(buf) = expected[i];
+ is_buffer_as_expected(&buf);
+
+ return BT_SUCCESS;
+}
+
+static int
+t_buffer_pop(void)
+{
+ int i;
+
+ init_buffer();
+ fill_expected_array();
+
+ /* POP a half of elements */
+ for (i = 0; i < MAX_NUM; i++)
+ BUFFER_PUSH(buf) = expected[i];
+ for (i = MAX_NUM-1; i >= MAX_NUM/2; i--)
+ BUFFER_POP(buf);
+ for (i = MAX_NUM/2; i < MAX_NUM; i++)
+ BUFFER_PUSH(buf) = expected[i] = bt_random();
+ is_buffer_as_expected(&buf);
+
+ /* POP all of elements */
+ for (i = MAX_NUM-1; i >= 0; i--)
+ BUFFER_POP(buf);
+ bt_assert(buf.used == 0);
+ for (i = 0; i < MAX_NUM; i++)
+ BUFFER_PUSH(buf) = expected[i];
+ is_buffer_as_expected(&buf);
+
+ return BT_SUCCESS;
+}
+
+static int
+t_buffer_resize(void)
+{
+ int i;
+
+ init_buffer();
+ BUFFER_INIT(buf, buffer_pool, 0);
+ fill_expected_array();
+
+ for (i = 0; i < MAX_NUM; i++)
+ BUFFER_PUSH(buf) = expected[i];
+ is_buffer_as_expected(&buf);
+ bt_assert(buf.size >= MAX_NUM);
+
+ return BT_SUCCESS;
+}
+
+static int
+t_buffer_flush(void)
+{
+ int i;
+
+ init_buffer();
+ fill_expected_array();
+ for (i = 0; i < MAX_NUM; i++)
+ BUFFER_PUSH(buf) = expected[i];
+
+ BUFFER_FLUSH(buf);
+ bt_assert(buf.used == 0);
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_buffer_push, "Pushing new elements");
+ bt_test_suite(t_buffer_pop, "Fill whole buffer (PUSH), a half of elements POP and PUSH new elements");
+ bt_test_suite(t_buffer_resize, "Init a small buffer and try overfill");
+ bt_test_suite(t_buffer_flush, "Fill and flush all elements");
+
+ return bt_exit_value();
+}
diff --git a/lib/checksum_test.c b/lib/checksum_test.c
new file mode 100644
index 00000000..ae5a7f31
--- /dev/null
+++ b/lib/checksum_test.c
@@ -0,0 +1,94 @@
+/*
+ * BIRD Library -- IP One-Complement Checksum Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+
+#include "test/birdtest.h"
+
+#include "lib/checksum.h"
+
+#define MAX_NUM 10000
+
+static u16
+ipsum_calculate_expected(u32 *a)
+{
+ int i;
+ u32 sum = 0;
+
+ for(i = 0; i < MAX_NUM; i++)
+ {
+ sum += a[i] & 0xffff;
+ bt_debug("low) \t0x%08X \n", sum);
+
+ sum += a[i] >> 16;
+ bt_debug("high) \t0x%08X \n", sum);
+
+ u16 carry = sum >> 16;
+ sum = (sum & 0xffff) + carry;
+ bt_debug("carry) \t0x%08X \n\n", sum);
+ }
+ bt_debug("sum) \t0x%08X \n", sum);
+
+ sum = sum ^ 0xffff;
+ bt_debug("~sum) \t0x%08X \n", sum);
+
+ return sum;
+}
+
+static int
+t_calculate(void)
+{
+ u32 a[MAX_NUM];
+ int i;
+
+ for (i = 0; i < MAX_NUM; i++)
+ a[i] = bt_random();
+
+ u16 sum_calculated = ipsum_calculate(a, sizeof(a), NULL);
+ u16 sum_calculated_2 = ipsum_calculate(&a[0], sizeof(u32)*(MAX_NUM/2), &a[MAX_NUM/2], sizeof(u32)*(MAX_NUM - MAX_NUM/2), NULL);
+ bt_assert(sum_calculated == sum_calculated_2);
+
+ u16 sum_expected = ipsum_calculate_expected(a);
+
+ bt_debug("sum_calculated: %08X \n", sum_calculated);
+ bt_debug("sum_expected: %08X \n", sum_expected);
+
+ bt_assert(sum_calculated == sum_expected);
+
+ return BT_SUCCESS;
+}
+
+static int
+t_verify(void)
+{
+ u32 a[MAX_NUM+1];
+ int i;
+
+ for (i = 0; i < MAX_NUM; i++)
+ a[i] = bt_random();
+
+ u16 sum = ipsum_calculate_expected(a);
+
+ a[MAX_NUM] = sum;
+
+ bt_assert(ipsum_verify(a, sizeof(a), NULL));
+
+ return BT_SUCCESS;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_calculate, "Checksum of pseudo-random data");
+ bt_test_suite(t_verify, "Verification of pseudo-random data.");
+
+ return bt_exit_value();
+}
diff --git a/lib/event_test.c b/lib/event_test.c
new file mode 100644
index 00000000..1997344d
--- /dev/null
+++ b/lib/event_test.c
@@ -0,0 +1,88 @@
+/*
+ * BIRD Library -- Event Processing Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+
+#include "test/birdtest.h"
+
+#include "lib/net.h"
+#include "lib/event.h"
+#include "conf/conf.h"
+#include "nest/locks.h"
+#include "sysdep/unix/unix.h"
+#include "nest/iface.h"
+#include "nest/route.h"
+
+#define MAX_NUM 4
+
+int event_check_points[MAX_NUM];
+
+#define event_hook_body(num) \
+ do { \
+ bt_debug("Event Hook " #num "\n"); \
+ event_check_points[num] = 1; \
+ bt_assert_msg(event_check_points[num-1], "Events should be run in right order"); \
+ } while (0)
+
+static void event_hook_1(void *data UNUSED) { event_hook_body(1); }
+static void event_hook_2(void *data UNUSED) { event_hook_body(2); }
+static void event_hook_3(void *data UNUSED) { event_hook_body(3); }
+
+#define schedule_event(num) \
+ do { \
+ struct event *event_##num = ev_new(&root_pool); \
+ event_##num->hook = event_hook_##num; \
+ ev_schedule(event_##num); \
+ } while (0)
+
+static void
+init_event_check_points(void)
+{
+ int i;
+ event_check_points[0] = 1;
+ for (i = 1; i < MAX_NUM; i++)
+ event_check_points[i] = 0;
+}
+
+static int
+t_ev_run_list(void)
+{
+ int i;
+
+ resource_init();
+ olock_init();
+ io_init();
+ rt_init();
+ if_init();
+// roa_init();
+ config_init();
+ config = config_alloc("");
+
+ init_event_check_points();
+
+ schedule_event(1);
+ schedule_event(2);
+ schedule_event(3);
+
+ ev_run_list(&global_event_list);
+
+ for (i = 1; i < MAX_NUM; i++)
+ bt_assert(event_check_points[i]);
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_ev_run_list, "Schedule and run 3 events in right order.");
+
+ return bt_exit_value();
+}
+
diff --git a/lib/fletcher16_test.c b/lib/fletcher16_test.c
new file mode 100644
index 00000000..3e036900
--- /dev/null
+++ b/lib/fletcher16_test.c
@@ -0,0 +1,169 @@
+/*
+ * BIRD Library -- Fletcher-16 Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+#include "lib/fletcher16.h"
+
+static u16
+straightforward_fletcher16_compute(const char *data)
+{
+ int count = strlen(data);
+
+ u16 sum1 = 0;
+ u16 sum2 = 0;
+ int index;
+
+ for (index = 0; index < count; ++index)
+ {
+ sum1 = (sum1 + data[index]) % 255;
+ sum2 = (sum2 + sum1) % 255;
+ }
+
+ return (sum2 << 8) | sum1;
+}
+
+static u16
+straightforward_fletcher16_checksum(const char *data)
+{
+ u16 csum;
+ u8 c0,c1,f0,f1;
+
+ csum = straightforward_fletcher16_compute(data);
+ f0 = csum & 0xff;
+ f1 = (csum >> 8) & 0xff;
+ c0 = 0xff - ((f0 + f1) % 0xff);
+ c1 = 0xff - ((f0 + c0) % 0xff);
+
+ return (c1 << 8) | c0;
+}
+
+static int
+test_fletcher16(void *out_, const void *in_, const void *expected_out_)
+{
+ u16 *out = out_;
+ const char *in = in_;
+ const u16 *expected_out = expected_out_;
+
+ struct fletcher16_context ctxt;
+
+ fletcher16_init(&ctxt);
+ fletcher16_update(&ctxt, in, strlen(in));
+ put_u16(out, fletcher16_compute(&ctxt));
+
+ return (*out == *expected_out) ? BT_SUCCESS : BT_FAILURE;
+}
+
+static int
+test_fletcher16_checksum(void *out_, const void *in_, const void *expected_out_)
+{
+ u16 *out = out_;
+ const char *in = in_;
+ const u16 *expected_out = expected_out_;
+
+ struct fletcher16_context ctxt;
+ int len = strlen(in);
+
+ fletcher16_init(&ctxt);
+ fletcher16_update(&ctxt, in, len);
+ put_u16(out, fletcher16_final(&ctxt, len, len));
+
+ return (*out == *expected_out) ? BT_SUCCESS : BT_FAILURE;
+}
+
+static int
+t_fletcher16_compute(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "\001\002",
+ .out = & (const u16) { 0x0403 },
+ },
+ {
+ .in = "",
+ .out = & ((const u16) { straightforward_fletcher16_compute("") }),
+ },
+ {
+ .in = "a",
+ .out = & ((const u16) { straightforward_fletcher16_compute("a") }),
+ },
+ {
+ .in = "abcd",
+ .out = & ((const u16) { straightforward_fletcher16_compute("abcd") }),
+ },
+ {
+ .in = "message digest",
+ .out = & ((const u16) { straightforward_fletcher16_compute("message digest") }),
+ },
+ {
+ .in = "abcdefghijklmnopqrstuvwxyz",
+ .out = & ((const u16) { straightforward_fletcher16_compute("abcdefghijklmnopqrstuvwxyz") }),
+ },
+ {
+ .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .out = & ((const u16) { straightforward_fletcher16_compute("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") }),
+ },
+ {
+ .in = "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ .out = & ((const u16) { straightforward_fletcher16_compute("12345678901234567890123456789012345678901234567890123456789012345678901234567890") }),
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_fletcher16, bt_fmt_str, bt_fmt_unsigned);
+}
+
+static int
+t_fletcher16_checksum(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "\001\002",
+ .out = & ((const u16) { straightforward_fletcher16_checksum("\001\002") }),
+ },
+ {
+ .in = "",
+ .out = & ((const u16) { straightforward_fletcher16_checksum("") }),
+ },
+ {
+ .in = "a",
+ .out = & ((const u16) { straightforward_fletcher16_checksum("a") }),
+ },
+ {
+ .in = "abcd",
+ .out = & ((const u16) { straightforward_fletcher16_checksum("abcd") }),
+ },
+ {
+ .in = "message digest",
+ .out = & ((const u16) { straightforward_fletcher16_checksum("message digest") }),
+ },
+ {
+ .in = "abcdefghijklmnopqrstuvwxyz",
+ .out = & ((const u16) { straightforward_fletcher16_checksum("abcdefghijklmnopqrstuvwxyz") }),
+ },
+ {
+ .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .out = & ((const u16) { straightforward_fletcher16_checksum("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") }),
+ },
+ {
+ .in = "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ .out = & ((const u16) { straightforward_fletcher16_checksum("12345678901234567890123456789012345678901234567890123456789012345678901234567890") }),
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_fletcher16_checksum, bt_fmt_str, bt_fmt_unsigned);
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_fletcher16_compute, "Fletcher-16 Compute Tests");
+ bt_test_suite(t_fletcher16_checksum, "Fletcher-16 Checksum Tests");
+
+ return bt_exit_value();
+}
diff --git a/lib/hash_test.c b/lib/hash_test.c
new file mode 100644
index 00000000..07607f6e
--- /dev/null
+++ b/lib/hash_test.c
@@ -0,0 +1,305 @@
+/*
+ * BIRD Library -- Hash Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#undef LOCAL_DEBUG
+
+#include "test/birdtest.h"
+
+#include "lib/hash.h"
+
+struct test_node {
+ struct test_node *next; /* Hash chain */
+ u32 key;
+};
+
+#define TEST_KEY(n) n->key
+#define TEST_NEXT(n) n->next
+#define TEST_EQ(n1,n2) n1 == n2
+#define TEST_FN(n) (n) ^ u32_hash((n))
+#define TEST_ORDER 13
+#define TEST_PARAMS /TEST_ORDER, *2, 2, 2, TEST_ORDER, 20
+#define TEST_REHASH test_rehash
+
+HASH_DEFINE_REHASH_FN(TEST, struct test_node);
+
+HASH(struct test_node) hash;
+struct pool *my_pool;
+
+#define MAX_NUM (1 << TEST_ORDER)
+
+struct test_node nodes[MAX_NUM];
+
+static void
+print_rate_of_fulfilment(void)
+{
+ int i;
+ int num_stacked_items = 0;
+
+ for (i = 0; i < MAX_NUM; i++)
+ if (!hash.data[i])
+ num_stacked_items++;
+
+ double percent_stacked_items = ((double)num_stacked_items/(double)MAX_NUM)*100.;
+ bt_debug("%d (%.2f %%) chained of %d hashes \n", num_stacked_items, percent_stacked_items, MAX_NUM);
+}
+
+#ifdef LOCAL_DEBUG
+static void
+dump_nodes(void)
+{
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ bt_debug("nodes[%3d] is at address %14p has .key %3d, .next %14p \n", i, &nodes[i], nodes[i].key, nodes[i].next);
+}
+#endif
+
+static void
+init_hash_(uint order)
+{
+ resource_init();
+ my_pool = rp_new(&root_pool, "Test pool");
+
+ HASH_INIT(hash, my_pool, order);
+
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ nodes[i].key = i;
+ nodes[i].next = NULL;
+ }
+
+ bt_debug("MAX_NUM %d \n", MAX_NUM);
+}
+
+static void
+init_hash(void)
+{
+ init_hash_(TEST_ORDER);
+}
+
+static void
+validate_filled_hash(void)
+{
+ int i;
+ struct test_node *node;
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ node = HASH_FIND(hash, TEST, nodes[i].key);
+ bt_assert_msg(node->key == nodes[i].key, "Hash should be filled, to find (%p) the node[%d] (%p) with .key = %u, .next %p", node, i, &nodes[i], nodes[i].key, nodes[i].next);
+ }
+
+ print_rate_of_fulfilment();
+}
+
+static void
+validate_empty_hash(void)
+{
+ int i;
+ struct test_node *node;
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ node = HASH_FIND(hash, TEST, nodes[i].key);
+ bt_assert_msg(node == NULL, "Hash should be empty, to find (%p) the node[%d] (%p) with .key %u, .next %p", node, i, &nodes[i], nodes[i].key, nodes[i].next);
+ }
+}
+
+static void
+fill_hash(void)
+{
+ int i;
+ struct test_node *node;
+
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ nodes[i].key = i;
+ node = &nodes[i];
+ HASH_INSERT(hash, TEST, node);
+ }
+}
+
+static int
+t_insert_find(void)
+{
+ init_hash();
+ fill_hash();
+ validate_filled_hash();
+
+ return BT_SUCCESS;
+}
+
+static int
+t_insert_find_random(void)
+{
+ init_hash();
+
+ int i;
+ struct test_node *node;
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ nodes[i].key = bt_random();
+ node = &nodes[i];
+ HASH_INSERT(hash, TEST, node);
+ }
+
+ validate_filled_hash();
+
+ return BT_SUCCESS;
+}
+
+static int
+t_insert2_find(void)
+{
+ init_hash_(1);
+
+ int i;
+ struct test_node *node;
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ nodes[i].key = i;
+ node = &nodes[i];
+ HASH_INSERT2(hash, TEST, my_pool, node);
+ }
+ bt_assert_msg(hash.order != 1, "The hash should auto-resize from order 2^1. The order of the hash is 2^%u.", hash.order);
+
+ validate_filled_hash();
+
+ return BT_SUCCESS;
+}
+
+static int
+t_walk(void)
+{
+ init_hash();
+ fill_hash();
+
+ uint i;
+ uint check[MAX_NUM];
+ for (i = 0; i < MAX_NUM; i++)
+ check[i] = 0;
+
+ HASH_WALK(hash, next, n)
+ {
+ check[n->key]++;
+ }
+ HASH_WALK_END;
+
+ for (i = 0; i < MAX_NUM; i++)
+ bt_assert(check[i] == 1);
+
+ return BT_SUCCESS;
+}
+
+static int
+t_walk_delsafe_delete(void)
+{
+ init_hash();
+ fill_hash();
+
+ HASH_WALK_DELSAFE(hash, next, n)
+ {
+ HASH_DELETE(hash, TEST, n->key);
+ }
+ HASH_WALK_DELSAFE_END;
+
+ validate_empty_hash();
+
+ return BT_SUCCESS;
+}
+
+static int
+t_walk_delsafe_remove(void)
+{
+ init_hash();
+ fill_hash();
+
+ HASH_WALK_DELSAFE(hash, next, n)
+ {
+ HASH_REMOVE(hash, TEST, n);
+ }
+ HASH_WALK_DELSAFE_END;
+
+ validate_empty_hash();
+
+ return BT_SUCCESS;
+}
+
+static int
+t_walk_delsafe_delete2(void)
+{
+ init_hash();
+ fill_hash();
+
+ HASH_WALK_DELSAFE(hash, next, n)
+ {
+ HASH_DELETE2(hash, TEST, my_pool, n->key);
+ }
+ HASH_WALK_DELSAFE_END;
+
+ validate_empty_hash();
+
+ return BT_SUCCESS;
+}
+
+static int
+t_walk_delsafe_remove2(void)
+{
+ init_hash();
+ fill_hash();
+
+ HASH_WALK_DELSAFE(hash, next, n)
+ {
+ HASH_REMOVE2(hash, TEST, my_pool, n);
+ }
+ HASH_WALK_DELSAFE_END;
+
+ validate_empty_hash();
+
+ return BT_SUCCESS;
+}
+
+static int
+t_walk_filter(void)
+{
+ init_hash();
+ fill_hash();
+
+ uint i;
+ uint check[MAX_NUM];
+ for (i = 0; i < MAX_NUM; i++)
+ check[i] = 0;
+
+ HASH_WALK_FILTER(hash, next, n, m)
+ {
+ bt_assert(n == *m);
+ check[n->key]++;
+ }
+ HASH_WALK_FILTER_END;
+
+ for (i = 0; i < MAX_NUM; i++)
+ bt_assert(check[i] == 1);
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_insert_find, "HASH_INSERT and HASH_FIND");
+ bt_test_suite(t_insert_find_random, "HASH_INSERT pseudo-random keys and HASH_FIND");
+ bt_test_suite(t_insert2_find, "HASH_INSERT2 and HASH_FIND. HASH_INSERT2 is HASH_INSERT and a smart auto-resize function");
+ bt_test_suite(t_walk, "HASH_WALK");
+ bt_test_suite(t_walk_delsafe_delete, "HASH_WALK_DELSAFE and HASH_DELETE");
+ bt_test_suite(t_walk_delsafe_delete2, "HASH_WALK_DELSAFE and HASH_DELETE2. HASH_DELETE2 is HASH_DELETE and smart auto-resize function");
+ bt_test_suite(t_walk_delsafe_remove, "HASH_WALK_DELSAFE and HASH_REMOVE");
+ bt_test_suite(t_walk_delsafe_remove2, "HASH_WALK_DELSAFE and HASH_REMOVE2. HASH_REMOVE2 is HASH_REMOVE and smart auto-resize function");
+ bt_test_suite(t_walk_filter, "HASH_WALK_FILTER");
+
+ return bt_exit_value();
+}
diff --git a/lib/heap_test.c b/lib/heap_test.c
new file mode 100644
index 00000000..40c9dd83
--- /dev/null
+++ b/lib/heap_test.c
@@ -0,0 +1,186 @@
+/*
+ * BIRD Library -- Universal Heap Macros Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+#include "sysdep/config.h"
+#include "lib/heap.h"
+
+#define MAX_NUM 1000
+#define SPECIAL_KEY -3213
+
+#define MY_CMP(x, y) ((x) < (y))
+
+#define MY_HEAP_SWAP(heap,a,b,t) \
+ do { \
+ bt_debug("swap(%u %u) ", a, b); \
+ HEAP_SWAP(heap,a,b,t); \
+ } while(0)
+
+static int heap[MAX_NUM+1];
+static uint num;
+
+/*
+ * A valid heap must follow these rules:
+ * - `num >= 0`
+ * - `heap[i] >= heap[i / 2]` for each `i` in `[2, num]`
+ */
+static int
+is_heap_valid(int heap[], uint num)
+{
+ uint i;
+
+ if (num > MAX_NUM)
+ return 0;
+
+ for (i = 2; i <= num; i++)
+ if (heap[i] < heap[i / 2])
+ return 0;
+
+ return 1;
+}
+
+static void
+show_heap(void)
+{
+ uint i;
+ bt_debug("\n");
+ bt_debug("numbers %u; ", num);
+ for (i = 0; i <= num; i++)
+ bt_debug("%d ", heap[i]);
+ bt_debug(is_heap_valid(heap, num) ? "OK" : "NON-VALID HEAP!");
+ bt_debug("\n");
+}
+
+static void
+init_heap(void)
+{
+ uint i;
+ num = 0;
+ heap[0] = SPECIAL_KEY; /* heap[0] should be unused */
+ for (i = 1; i <= MAX_NUM; i++)
+ heap[i] = 0;
+}
+
+static int
+t_heap_insert(void)
+{
+ uint i;
+
+ init_heap();
+
+ for (i = MAX_NUM; i >= 1; i--)
+ {
+ bt_debug("ins %u at pos %u ", i, MAX_NUM - i);
+ heap[MAX_NUM - i + 1] = i;
+ HEAP_INSERT(heap, ++num, int, MY_CMP, MY_HEAP_SWAP);
+ show_heap();
+ bt_assert(is_heap_valid(heap, num));
+ }
+
+ return BT_SUCCESS;
+}
+
+static int
+t_heap_increase_decrease(void)
+{
+ uint i;
+
+ t_heap_insert();
+
+ for (i = 1; i <= MAX_NUM; i++)
+ {
+ if ((int)i > heap[i])
+ {
+ bt_debug("inc %u ", i);
+ heap[i] = i;
+ HEAP_INCREASE(heap, num, int, MY_CMP, MY_HEAP_SWAP, i);
+ }
+ else if ((int)i < heap[i])
+ {
+ bt_debug("dec %u ", i);
+ heap[i] = i;
+ HEAP_INCREASE(heap, num, int, MY_CMP, MY_HEAP_SWAP, i);
+ }
+ show_heap();
+ bt_assert(is_heap_valid(heap, num));
+ }
+
+ return BT_SUCCESS;
+}
+
+static int
+t_heap_delete(void)
+{
+ uint i;
+
+ t_heap_insert();
+
+ for (i = 1; i <= num; i++)
+ {
+ bt_debug("del at pos %u ", i);
+ HEAP_DELETE(heap, num, int, MY_CMP, MY_HEAP_SWAP, i);
+ show_heap();
+ bt_assert(is_heap_valid(heap, num));
+ }
+
+ return BT_SUCCESS;
+}
+
+static int
+t_heap_0(void)
+{
+ init_heap();
+ t_heap_insert();
+ t_heap_increase_decrease();
+ t_heap_delete();
+
+ return (heap[0] == SPECIAL_KEY) ? BT_SUCCESS : BT_FAILURE;
+}
+
+static int
+t_heap_insert_random(void)
+{
+ int i, j;
+ int expected[MAX_NUM+1];
+
+ init_heap();
+
+ for (i = 1; i <= MAX_NUM; i++)
+ {
+ heap[i] = expected[i] = bt_random();
+ HEAP_INSERT(heap, ++num, int, MY_CMP, MY_HEAP_SWAP);
+ show_heap();
+ bt_assert(is_heap_valid(heap, num));
+ }
+
+ for (i = 1; i <= MAX_NUM; i++)
+ for (j = 1; j <= MAX_NUM; j++)
+ if(expected[i] == heap[j])
+ break;
+ else if (j == MAX_NUM)
+ {
+ show_heap();
+ bt_abort_msg("Did not find a number %d in heap.", expected[i]);
+ }
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_heap_insert, "Inserting a descending sequence of numbers (the worst case)");
+ bt_test_suite(t_heap_insert_random, "Inserting pseudo-random numbers");
+ bt_test_suite(t_heap_increase_decrease, "Increasing/Decreasing");
+ bt_test_suite(t_heap_delete, "Deleting");
+ bt_test_suite(t_heap_0, "Is a heap[0] really unused?");
+
+ return bt_exit_value();
+}
diff --git a/lib/ip.c b/lib/ip.c
index 5e039c12..9497248c 100644
--- a/lib/ip.c
+++ b/lib/ip.c
@@ -306,7 +306,7 @@ ip6_pton(const char *a, ip6_addr *o)
if (*a == ':' && a[1])
a++;
- else if (*a == '.' && (i == 6 || i < 6 && hfil >= 0))
+ else if (*a == '.' && (i == 6 || (i < 6 && hfil >= 0)))
{ /* Embedded IPv4 address */
ip4_addr x;
if (!ip4_pton(start, &x))
diff --git a/lib/ip_test.c b/lib/ip_test.c
new file mode 100644
index 00000000..81b4897e
--- /dev/null
+++ b/lib/ip_test.c
@@ -0,0 +1,161 @@
+/*
+ * BIRD Library -- IP address functions Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+
+#include "lib/ip.h"
+
+#define IP4_MAX_LEN 16
+
+static int
+test_ipa_pton(void *out_, const void *in_, const void *expected_out_)
+{
+ ip_addr *out = out_;
+ const char *in = in_;
+ const ip_addr *expected_out = expected_out_;
+
+ if (ipa_is_ip4(*expected_out))
+ {
+ ip4_addr ip4;
+ bt_assert(ip4_pton(in, &ip4));
+ *out = ipa_from_ip4(ip4);
+ }
+ else
+ {
+ bt_assert(ip6_pton(in, out));
+ /* ip_addr == ip6_addr */
+ }
+
+ return ipa_equal(*out, *expected_out) ? BT_SUCCESS : BT_FAILURE;
+}
+
+static int
+t_ip4_pton(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "192.168.1.128",
+ .out = & ipa_build4(192, 168, 1, 128),
+ },
+ {
+ .in = "255.255.255.255",
+ .out = & ipa_build4(255, 255, 255, 255),
+ },
+ {
+ .in = "0.0.0.0",
+ .out = & ipa_build4(0, 0, 0, 0),
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_ipa_pton, bt_fmt_str, bt_fmt_ipa);
+}
+
+static int
+t_ip6_pton(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "2001:0db8:0000:0000:0000:0000:1428:57ab",
+ .out = & ipa_build6(0x20010DB8, 0x00000000, 0x00000000, 0x142857AB),
+ },
+ {
+ .in = "2001:0db8:0000:0000:0000::1428:57ab",
+ .out = & ipa_build6(0x20010DB8, 0x00000000, 0x00000000, 0x142857AB),
+ },
+ {
+ .in = "2001:0db8::1428:57ab",
+ .out = & ipa_build6(0x20010DB8, 0x00000000, 0x00000000, 0x142857AB),
+ },
+ {
+ .in = "2001:db8::1428:57ab",
+ .out = & ipa_build6(0x20010DB8, 0x00000000, 0x00000000, 0x142857AB),
+ },
+ {
+ .in = "::1",
+ .out = & ipa_build6(0x00000000, 0x00000000, 0x00000000, 0x00000001),
+ },
+ {
+ .in = "::",
+ .out = & ipa_build6(0x00000000, 0x00000000, 0x00000000, 0x00000000),
+ },
+ {
+ .in = "2605:2700:0:3::4713:93e3",
+ .out = & ipa_build6(0x26052700, 0x00000003, 0x00000000, 0x471393E3),
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_ipa_pton, bt_fmt_str, bt_fmt_ipa);
+}
+
+static int
+test_ipa_ntop(void *out_, const void *in_, const void *expected_out_)
+{
+ char *out = out_;
+ const ip_addr *in = in_;
+ const char *expected_out = expected_out_;
+
+ if (ipa_is_ip4(*in))
+ ip4_ntop(ipa_to_ip4(*in), out);
+ else
+ ip6_ntop(ipa_to_ip6(*in), out);
+
+ int result = strncmp(out, expected_out, ipa_is_ip4(*in) ? IP4_MAX_TEXT_LENGTH : IP6_MAX_TEXT_LENGTH) == 0;
+ return result ? BT_SUCCESS : BT_FAILURE;
+}
+
+static int
+t_ip4_ntop(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & ipa_build4(192, 168, 1, 128),
+ .out = "192.168.1.128",
+ },
+ {
+ .in = & ipa_build4(255, 255, 255, 255),
+ .out = "255.255.255.255",
+ },
+ {
+ .in = & ipa_build4(0, 0, 0, 1),
+ .out = "0.0.0.1",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_ipa_ntop, bt_fmt_ipa, bt_fmt_str);
+}
+
+static int
+t_ip6_ntop(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & ipa_build6(0x20010DB8, 0x00000000, 0x00000000, 0x142857AB),
+ .out = "2001:db8::1428:57ab",
+ },
+ {
+ .in = & ipa_build6(0x26052700, 0x00000003, 0x00000000, 0x471393E3),
+ .out = "2605:2700:0:3::4713:93e3",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_ipa_ntop, bt_fmt_ipa, bt_fmt_str);
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_ip4_pton, "Converting IPv4 string to ip4_addr struct");
+ bt_test_suite(t_ip6_pton, "Converting IPv6 string to ip6_addr struct");
+ bt_test_suite(t_ip4_ntop, "Converting ip4_addr struct to IPv4 string");
+ bt_test_suite(t_ip6_ntop, "Converting ip6_addr struct to IPv6 string");
+
+ return bt_exit_value();
+}
+
diff --git a/lib/lists_test.c b/lib/lists_test.c
new file mode 100644
index 00000000..56cc8427
--- /dev/null
+++ b/lib/lists_test.c
@@ -0,0 +1,287 @@
+/*
+ * BIRD Library -- Linked Lists Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+#include "lib/lists.h"
+
+#define MAX_NUM 1000
+
+static node nodes[MAX_NUM];
+static list l;
+
+static void
+show_list(void)
+{
+ bt_debug("\n");
+ bt_debug("list.null is at %p and point to %p\n", &l.null, l.null);
+ bt_debug("list.head is at %p and point to %p\n", &l.head, l.head);
+ bt_debug("list.tail is at %p and point to %p\n", &l.tail, l.tail);
+
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ bt_debug("n[%3i] is at %p\n", i, &nodes[i]);
+ bt_debug(" prev is at %p and point to %p\n", &(nodes[i].prev), nodes[i].prev);
+ bt_debug(" next is at %p and point to %p\n", &(nodes[i].next), nodes[i].next);
+ }
+}
+
+static int
+is_filled_list_well_linked(void)
+{
+ int i;
+ bt_assert(l.head == &nodes[0]);
+ bt_assert(l.tail == &nodes[MAX_NUM-1]);
+ bt_assert((void *) nodes[0].prev == (void *) &l.head);
+ bt_assert((void *) nodes[MAX_NUM-1].next == (void *) &l.null);
+
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ if (i < (MAX_NUM-1))
+ bt_assert(nodes[i].next == &nodes[i+1]);
+
+ if (i > 0)
+ bt_assert(nodes[i].prev == &nodes[i-1]);
+ }
+
+ return 1;
+}
+
+static int
+is_empty_list_well_unlinked(void)
+{
+ int i;
+
+ bt_assert(l.head == NODE &l.null);
+ bt_assert(l.tail == NODE &l.head);
+ bt_assert(EMPTY_LIST(l));
+
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ bt_assert(nodes[i].next == NULL);
+ bt_assert(nodes[i].prev == NULL);
+ }
+
+ return 1;
+}
+
+static void
+init_list__(list *l, struct node nodes[])
+{
+ init_list(l);
+
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ nodes[i].next = NULL;
+ nodes[i].prev = NULL;
+ }
+}
+
+static void
+init_list_(void)
+{
+ init_list__(&l, (node *) nodes);
+}
+
+static int
+t_add_tail(void)
+{
+ int i;
+
+ init_list_();
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ add_tail(&l, &nodes[i]);
+ bt_debug(".");
+ bt_assert(l.tail == &nodes[i]);
+ bt_assert(l.head == &nodes[0]);
+ bt_assert((void *) nodes[i].next == (void *) &l.null);
+ if (i > 0)
+ {
+ bt_assert(nodes[i-1].next == &nodes[i]);
+ bt_assert(nodes[i].prev == &nodes[i-1]);
+ }
+ }
+ show_list();
+ bt_assert(is_filled_list_well_linked());
+
+ return BT_SUCCESS;
+}
+
+static int
+t_add_head(void)
+{
+ int i;
+
+ init_list_();
+ for (i = MAX_NUM-1; i >= 0; i--)
+ {
+ add_head(&l, &nodes[i]);
+ bt_debug(".");
+ bt_assert(l.head == &nodes[i]);
+ bt_assert(l.tail == &nodes[MAX_NUM-1]);
+ if (i < MAX_NUM-1)
+ {
+ bt_assert(nodes[i+1].prev == &nodes[i]);
+ bt_assert(nodes[i].next == &nodes[i+1]);
+ }
+ }
+ show_list();
+ bt_assert(is_filled_list_well_linked());
+
+ return BT_SUCCESS;
+}
+
+static void
+insert_node_(node *n, node *after)
+{
+ insert_node(n, after);
+ bt_debug(".");
+}
+
+static int
+t_insert_node(void)
+{
+ int i;
+
+ init_list_();
+
+ // add first node
+ insert_node_(&nodes[0], NODE &l.head);
+
+ // add odd nodes
+ for (i = 2; i < MAX_NUM; i+=2)
+ insert_node_(&nodes[i], &nodes[i-2]);
+
+ // add even nodes
+ for (i = 1; i < MAX_NUM; i+=2)
+ insert_node_(&nodes[i], &nodes[i-1]);
+
+ bt_debug("\n");
+ bt_assert(is_filled_list_well_linked());
+
+ return BT_SUCCESS;
+}
+
+static void
+fill_list2(list *l, node nodes[])
+{
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ add_tail(l, &nodes[i]);
+}
+
+static void
+fill_list(void)
+{
+ fill_list2(&l, (node *) nodes);
+}
+
+static int
+t_remove_node(void)
+{
+ int i;
+
+ init_list_();
+
+ /* Fill & Remove & Check */
+ fill_list();
+ for (i = 0; i < MAX_NUM; i++)
+ rem_node(&nodes[i]);
+ bt_assert(is_empty_list_well_unlinked());
+
+ /* Fill & Remove the half of nodes & Check & Remove the rest nodes & Check */
+ fill_list();
+ for (i = 0; i < MAX_NUM; i+=2)
+ rem_node(&nodes[i]);
+
+ int tail_node_index = (MAX_NUM % 2) ? MAX_NUM - 2 : MAX_NUM - 1;
+ bt_assert(l.head == &nodes[1]);
+ bt_assert(l.tail == &nodes[tail_node_index]);
+ bt_assert(nodes[tail_node_index].next == NODE &l.null);
+
+ for (i = 1; i < MAX_NUM; i+=2)
+ {
+ if (i > 1)
+ bt_assert(nodes[i].prev == &nodes[i-2]);
+ if (i < tail_node_index)
+ bt_assert(nodes[i].next == &nodes[i+2]);
+ }
+
+ for (i = 1; i < MAX_NUM; i+=2)
+ rem_node(&nodes[i]);
+ bt_assert(is_empty_list_well_unlinked());
+
+ return BT_SUCCESS;
+}
+
+static int
+t_replace_node(void)
+{
+ node head, inside, tail;
+
+ init_list_();
+ fill_list();
+
+ replace_node(&nodes[0], &head);
+ bt_assert(l.head == &head);
+ bt_assert(head.prev == NODE &l.head);
+ bt_assert(head.next == &nodes[1]);
+ bt_assert(nodes[1].prev == &head);
+
+ replace_node(&nodes[MAX_NUM/2], &inside);
+ bt_assert(nodes[MAX_NUM/2-1].next == &inside);
+ bt_assert(nodes[MAX_NUM/2+1].prev == &inside);
+ bt_assert(inside.prev == &nodes[MAX_NUM/2-1]);
+ bt_assert(inside.next == &nodes[MAX_NUM/2+1]);
+
+ replace_node(&nodes[MAX_NUM-1], &tail);
+ bt_assert(l.tail == &tail);
+ bt_assert(tail.prev == &nodes[MAX_NUM-2]);
+ bt_assert(tail.next == NODE &l.null);
+ bt_assert(nodes[MAX_NUM-2].next == &tail);
+
+ return BT_SUCCESS;
+}
+
+static int
+t_add_tail_list(void)
+{
+ node nodes2[MAX_NUM];
+ list l2;
+
+ init_list__(&l, (node *) nodes);
+ fill_list2(&l, (node *) nodes);
+
+ init_list__(&l2, (node *) nodes2);
+ fill_list2(&l2, (node *) nodes2);
+
+ add_tail_list(&l, &l2);
+
+ bt_assert(nodes[MAX_NUM-1].next == &nodes2[0]);
+ bt_assert(nodes2[0].prev == &nodes[MAX_NUM-1]);
+ bt_assert(l.tail == &nodes2[MAX_NUM-1]);
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_add_tail, "Adding nodes to tail of list");
+ bt_test_suite(t_add_head, "Adding nodes to head of list");
+ bt_test_suite(t_insert_node, "Inserting nodes to list");
+ bt_test_suite(t_remove_node, "Removing nodes from list");
+ bt_test_suite(t_replace_node, "Replacing nodes in list");
+ bt_test_suite(t_add_tail_list, "At the tail of a list adding the another list");
+
+ return bt_exit_value();
+}
diff --git a/lib/mac_test.c b/lib/mac_test.c
new file mode 100644
index 00000000..8522f95e
--- /dev/null
+++ b/lib/mac_test.c
@@ -0,0 +1,1159 @@
+/*
+ * BIRD Library -- SHA and HMAC-SHA functions tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+#include "test/bt-utils.h"
+
+#include "lib/mac.h"
+
+
+#define define_test_hash_fn(name,id) \
+static int \
+test_##name(void *out_, const void *in_, const void *expected_out_) \
+{ \
+ char *out = out_; \
+ const char *in = in_; \
+ const char *expected_out = expected_out_; \
+ \
+ struct mac_context ctx; \
+ mac_init(&ctx, id, NULL, 0); \
+ mac_update(&ctx, in, strlen(in)); \
+ byte *out_bin = mac_final(&ctx); \
+ \
+ uint len = mac_type_length(id); \
+ bt_bytes_to_hex(out, out_bin, len); \
+ \
+ return strncmp(out, expected_out, 2*len+1) == 0 ? BT_SUCCESS : BT_FAILURE; \
+}
+
+define_test_hash_fn(md5, ALG_MD5)
+define_test_hash_fn(sha1, ALG_SHA1)
+define_test_hash_fn(sha224, ALG_SHA224)
+define_test_hash_fn(sha256, ALG_SHA256)
+define_test_hash_fn(sha384, ALG_SHA384)
+define_test_hash_fn(sha512, ALG_SHA512)
+
+
+static int
+t_md5(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "",
+ .out = "d41d8cd98f00b204e9800998ecf8427e",
+ },
+ {
+ .in = "a",
+ .out = "0cc175b9c0f1b6a831c399e269772661",
+ },
+ {
+ .in = "abc",
+ .out = "900150983cd24fb0d6963f7d28e17f72",
+ },
+ {
+ .in = "message digest",
+ .out = "f96b697d7cb7938d525a2f31aaf161d0",
+ },
+ {
+ .in = "abcdefghijklmnopqrstuvwxyz",
+ .out = "c3fcd3d76192e4007dfb496cca67e13b",
+ },
+ {
+ .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .out = "d174ab98d277d9f5a5611c2c9f419d9f",
+ },
+ {
+ .in = "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ .out = "57edf4a22be3c955ac49da2e2107b67a",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_md5, bt_fmt_str, bt_fmt_str);
+}
+
+
+/*
+ * Testing SHAxxx functions
+ */
+
+
+static int
+t_sha1(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "",
+ .out = "da39a3ee5e6b4b0d3255bfef95601890afd80709",
+ },
+ {
+ .in = "a",
+ .out = "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8",
+ },
+ {
+ .in = "abc",
+ .out = "a9993e364706816aba3e25717850c26c9cd0d89d",
+ },
+ {
+ .in = "message digest",
+ .out = "c12252ceda8be8994d5fa0290a47231c1d16aae3",
+ },
+ {
+ .in = "abcdefghijklmnopqrstuvwxyz",
+ .out = "32d10c7b8cf96570ca04ce37f2a19d84240d3a89",
+ },
+ {
+ .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .out = "761c457bf73b14d27e9e9265c46f4b4dda11f940",
+ },
+ {
+ .in = "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ .out = "50abf5706a150990a08b2c5ea40fa0e585554732",
+ },
+ {
+ .in = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ .out = "6a64fcc1fb970f7339ce886601775d2efea5cd4b",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha1, bt_fmt_str, bt_fmt_str);
+}
+
+static int
+t_sha224(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "",
+ .out = "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f",
+ },
+ {
+ .in = "a",
+ .out = "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5",
+ },
+ {
+ .in = "abc",
+ .out = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7",
+ },
+ {
+ .in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .out = "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525",
+ },
+ {
+ .in = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ .out = "cca7dd1a332a17775d8b0429bdb45055c2d4368ebaab0c7cf385586e",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha224, bt_fmt_str, bt_fmt_str);
+}
+
+static int
+t_sha256(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "",
+ .out = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ },
+ {
+ .in = "a",
+ .out = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb",
+ },
+ {
+ .in = "abc",
+ .out = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
+ },
+ {
+ .in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .out = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
+ },
+ {
+ .in = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ .out = "bf18b43b61652b5d73f41ebf3d72e5e43aebf5076f497dde31ea3de9de4998ef",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha256, bt_fmt_str, bt_fmt_str);
+}
+
+static int
+t_sha384(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "",
+ .out = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b",
+ },
+ {
+ .in = "a",
+ .out = "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31",
+ },
+ {
+ .in = "abc",
+ .out = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
+ },
+ {
+ .in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .out = "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b",
+ },
+ {
+ .in = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ .out = "6452928a62ca915a60f2d16ea22cc832d8ecb35443d78a3ff6986e7def9174a1dc16ce2ff65d3ed1666db98357f3c05e",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha384, bt_fmt_str, bt_fmt_str);
+}
+
+static int
+t_sha512(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = "",
+ .out = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+ },
+ {
+ .in = "a",
+ .out = "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75",
+ },
+ {
+ .in = "abc",
+ .out = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
+ },
+ {
+ .in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ .out = "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445",
+ },
+ {
+ .in = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ .out = "415509a1c345371acb3e27a88b3835e3b6dfebcbbab5134850596f4db64d7bb22ac42c3cd179446a80c92b8be955460eb536eac01389a7e1fdf09d1dca83922f",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha512, bt_fmt_str, bt_fmt_str);
+}
+
+
+/*
+ * Testing SHAxxx HMAC functions
+ */
+
+#define HMAC_BUFFER_SIZE 160
+struct hmac_data_in {
+ byte key[HMAC_BUFFER_SIZE];
+ uint key_len;
+ byte data[HMAC_BUFFER_SIZE];
+ uint data_len;
+};
+
+static void
+hmac_in_fmt(char *buf, size_t size, const void *data_)
+{
+ uint i;
+ const struct hmac_data_in *data = data_;
+
+ snprintf(buf, size, "data: '");
+ for (i = 0; i < data->data_len; i++)
+ snprintf(buf+strlen(buf), size-strlen(buf), bt_is_char(data->data[i]) ? "%c" : " 0x%02x", data->data[i]);
+
+ snprintf(buf+strlen(buf), size-strlen(buf), "', key: '");
+ for (i = 0; i < data->key_len; i++)
+ snprintf(buf+strlen(buf), size-strlen(buf), bt_is_char(data->key[i]) ? "%c" : " 0x%02x", data->key[i]);
+ snprintf(buf+strlen(buf), size-strlen(buf), "'");
+}
+
+#define define_test_hmac_fn(name,id) \
+static int \
+test_##name##_hmac(void *out_, const void *in_, const void *expected_out_) \
+{ \
+ char *out = out_; \
+ const struct hmac_data_in *in = in_; \
+ const char *expected_out = expected_out_; \
+ \
+ struct mac_context ctx; \
+ mac_init(&ctx, id, in->key, in->key_len); \
+ mac_update(&ctx, in->data, in->data_len); \
+ byte *out_bin = mac_final(&ctx); \
+ \
+ uint len = mac_type_length(id); \
+ bt_bytes_to_hex(out, out_bin, len); \
+ \
+ return strncmp(out, expected_out, 2*len+1) == 0 ? BT_SUCCESS : BT_FAILURE; \
+}
+
+define_test_hmac_fn(md5, ALG_HMAC_MD5)
+define_test_hmac_fn(sha1, ALG_HMAC_SHA1)
+define_test_hmac_fn(sha224, ALG_HMAC_SHA224)
+define_test_hmac_fn(sha256, ALG_HMAC_SHA256)
+define_test_hmac_fn(sha384, ALG_HMAC_SHA384)
+define_test_hmac_fn(sha512, ALG_HMAC_SHA512)
+
+
+static int
+t_md5_hmac(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ },
+ .key_len = 16,
+ .data = "Hi There",
+ .data_len = 8,
+ },
+ .out = "9294727a3638bb1c13f48ef8158bfc9d",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = "Jefe",
+ .key_len = 4,
+ .data = "what do ya want for nothing?",
+ .data_len = 28,
+ },
+ .out = "750c783e6ab0b503eaa86e310a5db738",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 16,
+ .data = {
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ },
+ .data_len = 50,
+ },
+ .out = "56be34521d144c88dbb8c733f0e8b3f6",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19,
+ },
+ .key_len = 25,
+ .data = {
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ },
+ .data_len = 50,
+ },
+ .out = "697eaf0aca3a3aea3a75164746ffaa79",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ },
+ .key_len = 16,
+ .data = "Test With Truncation",
+ .data_len = 20,
+ },
+ .out = "56461ef2342edc00f9bab995690efd4c",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 80,
+ .data = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .data_len = 54,
+ },
+ .out = "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 80,
+ .data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
+ .data_len = 73,
+ },
+ .out = "6f630fad67cda0ee1fb1f562db3aa53e",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_md5_hmac, hmac_in_fmt, bt_fmt_str);
+}
+
+static int
+t_sha1_hmac(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ },
+ .key_len = 20,
+ .data = "Hi There",
+ .data_len = 8,
+ },
+ .out = "b617318655057264e28bc0b6fb378c8ef146be00",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = "Jefe",
+ .key_len = 4,
+ .data = "what do ya want for nothing?",
+ .data_len = 28,
+ },
+ .out = "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 20,
+ .data = {
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ },
+ .data_len = 50,
+ },
+ .out = "125d7342b9ac11cd91a39af48aa17b4f63f175d3",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19,
+ },
+ .key_len = 25,
+ .data = {
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ },
+ .data_len = 50,
+ },
+ .out = "4c9007f4026250c6bc8414f9bf50c86c2d7235da",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ },
+ .key_len = 20,
+ .data = "Test With Truncation",
+ .data_len = 20,
+ },
+ .out = "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 80,
+ .data = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .data_len = 54,
+ },
+ .out = "aa4ae5e15272d00e95705637ce8a3b55ed402112",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 80,
+ .data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
+ .data_len = 73,
+ },
+ .out = "e8e99d0f45237d786d6bbaa7965c7808bbff1a91",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61,
+ },
+ .key_len = 64,
+ .data = "Test Using key 64 bytes sized",
+ .data_len = 29,
+ },
+ .out = "a55d4fb80962a6b3d2e720705314bee417d68cf6",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha1_hmac, hmac_in_fmt, bt_fmt_str);
+}
+
+static int
+t_sha224_hmac(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ },
+ .key_len = 20,
+ .data = "Hi There",
+ .data_len = 8,
+ },
+ .out = "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = "Jefe",
+ .key_len = 4,
+ .data = "what do ya want for nothing?",
+ .data_len = 28,
+ },
+ .out = "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 20,
+ .data = {
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ },
+ .data_len = 50,
+ },
+ .out = "7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19,
+ },
+ .key_len = 25,
+ .data = {
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ },
+ .data_len = 50,
+ },
+ .out = "6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ },
+ .key_len = 20,
+ .data = "Test With Truncation",
+ .data_len = 20,
+ },
+ .out = "0e2aea68a90c8d37c988bcdb9fca6fa8099cd857c7ec4a1815cac54c",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa,
+ },
+ .key_len = 131,
+ .data = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .data_len = 54,
+ },
+ .out = "95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa,
+ },
+ .key_len = 131,
+ .data = "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+ .data_len = 152,
+ },
+ .out = "3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha224_hmac, hmac_in_fmt, bt_fmt_str);
+}
+
+static int
+t_sha256_hmac(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ },
+ .key_len = 20,
+ .data = "Hi There",
+ .data_len = 8,
+ },
+ .out = "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = "Jefe",
+ .key_len = 4,
+ .data = "what do ya want for nothing?",
+ .data_len = 28,
+ },
+ .out = "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 20,
+ .data = {
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ },
+ .data_len = 50,
+ },
+ .out = "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19,
+ },
+ .key_len = 25,
+ .data = {
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ },
+ .data_len = 50,
+ },
+ .out = "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ },
+ .key_len = 20,
+ .data = "Test With Truncation",
+ .data_len = 20,
+ },
+ .out = "a3b6167473100ee06e0c796c2955552bfa6f7c0a6a8aef8b93f860aab0cd20c5",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa,
+ },
+ .key_len = 131,
+ .data = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .data_len = 54,
+ },
+ .out = "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa,
+ },
+ .key_len = 131,
+ .data = "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+ .data_len = 152,
+ },
+ .out = "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha256_hmac, hmac_in_fmt, bt_fmt_str);
+}
+
+static int
+t_sha384_hmac(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ },
+ .key_len = 20,
+ .data = "Hi There",
+ .data_len = 8,
+ },
+ .out = "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = "Jefe",
+ .key_len = 4,
+ .data = "what do ya want for nothing?",
+ .data_len = 28,
+ },
+ .out = "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 20,
+ .data = {
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ },
+ .data_len = 50,
+ },
+ .out = "88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19,
+ },
+ .key_len = 25,
+ .data = {
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ },
+ .data_len = 50,
+ },
+ .out = "3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ },
+ .key_len = 20,
+ .data = "Test With Truncation",
+ .data_len = 20,
+ },
+ .out = "3abf34c3503b2a23a46efc619baef897f4c8e42c934ce55ccbae9740fcbc1af4ca62269e2a37cd88ba926341efe4aeea",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa,
+ },
+ .key_len = 131,
+ .data = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .data_len = 54,
+ },
+ .out = "4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa,
+ },
+ .key_len = 131,
+ .data = "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+ .data_len = 152,
+ },
+ .out = "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha384_hmac, hmac_in_fmt, bt_fmt_str);
+}
+
+static int
+t_sha512_hmac(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ },
+ .key_len = 20,
+ .data = "Hi There",
+ .data_len = 8,
+ },
+ .out = "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = "Jefe",
+ .key_len = 4,
+ .data = "what do ya want for nothing?",
+ .data_len = 28,
+ },
+ .out = "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ .key_len = 20,
+ .data = {
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ },
+ .data_len = 50,
+ },
+ .out = "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19,
+ },
+ .key_len = 25,
+ .data = {
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ },
+ .data_len = 50,
+ },
+ .out = "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ },
+ .key_len = 20,
+ .data = "Test With Truncation",
+ .data_len = 20,
+ },
+ .out = "415fad6271580a531d4179bc891d87a650188707922a4fbb36663a1eb16da008711c5b50ddd0fc235084eb9d3364a1454fb2ef67cd1d29fe6773068ea266e96b",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa,
+ },
+ .key_len = 131,
+ .data = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .data_len = 54,
+ },
+ .out = "80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598",
+ },
+ {
+ .in = & (struct hmac_data_in) {
+ .key = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa,
+ },
+ .key_len = 131,
+ .data = "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+ .data_len = 152,
+ },
+ .out = "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58",
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_sha512_hmac, hmac_in_fmt, bt_fmt_str);
+}
+
+
+/*
+ * Testing SHAxxx concating independence
+ */
+
+#include "lib/sha256.h"
+#include "lib/sha512.h"
+
+static int
+t_sha256_concating(void)
+{
+ char hash_a[SHA256_HEX_SIZE];
+ char hash_b[SHA256_HEX_SIZE];
+
+ char *str_a = "a" "bb" "ccc" "dddd" "eeeee" "ffffff";
+ char *str_b1 = "a" ;
+ char *str_b2 = "bb" ;
+ char *str_b3 = "ccc" ;
+ char *str_b4 = "dddd" ;
+ char *str_b5 = "eeeee" ;
+ char *str_b6 = "ffffff";
+
+ struct hash_context ctx_a;
+ sha256_init(&ctx_a);
+ sha256_update(&ctx_a, str_a, strlen(str_a));
+ byte *hash_a_ = sha256_final(&ctx_a);
+ bt_bytes_to_hex(hash_a, hash_a_, SHA256_SIZE);
+
+ struct hash_context ctx_b;
+ sha256_init(&ctx_b);
+ sha256_update(&ctx_b, str_b1, strlen(str_b1));
+ sha256_update(&ctx_b, str_b2, strlen(str_b2));
+ sha256_update(&ctx_b, str_b3, strlen(str_b3));
+ sha256_update(&ctx_b, str_b4, strlen(str_b4));
+ sha256_update(&ctx_b, str_b5, strlen(str_b5));
+ sha256_update(&ctx_b, str_b6, strlen(str_b6));
+ byte *hash_b_ = sha256_final(&ctx_b);
+ bt_bytes_to_hex(hash_b, hash_b_, SHA256_SIZE);
+
+ int are_hash_a_b_equal = (strncmp(hash_a, hash_b, sizeof(hash_a)) == 0);
+ bt_assert_msg(are_hash_a_b_equal, "Hashes A: %s, B: %s should be same", hash_a, hash_b);
+
+ return BT_SUCCESS;
+}
+
+
+static int
+t_sha512_concating(void)
+{
+ char hash_a[SHA512_HEX_SIZE];
+ char hash_b[SHA512_HEX_SIZE];
+
+ char *str_a = "a" "bb" "ccc" "dddd" "eeeee" "ffffff";
+ char *str_b1 = "a" ;
+ char *str_b2 = "bb" ;
+ char *str_b3 = "ccc" ;
+ char *str_b4 = "dddd" ;
+ char *str_b5 = "eeeee" ;
+ char *str_b6 = "ffffff";
+
+ struct hash_context ctx_a;
+ sha512_init(&ctx_a);
+ sha512_update(&ctx_a, str_a, strlen(str_a));
+ byte *hash_a_ = sha512_final(&ctx_a);
+ bt_bytes_to_hex(hash_a, hash_a_, SHA512_SIZE);
+
+ struct hash_context ctx_b;
+ sha512_init(&ctx_b);
+ sha512_update(&ctx_b, str_b1, strlen(str_b1));
+ sha512_update(&ctx_b, str_b2, strlen(str_b2));
+ sha512_update(&ctx_b, str_b3, strlen(str_b3));
+ sha512_update(&ctx_b, str_b4, strlen(str_b4));
+ sha512_update(&ctx_b, str_b5, strlen(str_b5));
+ sha512_update(&ctx_b, str_b6, strlen(str_b6));
+ byte *hash_b_ = sha512_final(&ctx_b);
+ bt_bytes_to_hex(hash_b, hash_b_, SHA512_SIZE);
+
+ int are_hash_a_b_equal = (strncmp(hash_a, hash_b, sizeof(hash_a)) == 0);
+ bt_assert_msg(are_hash_a_b_equal, "Hashes A: %s, B: %s should be same", hash_a, hash_b);
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_md5, "Testing MD5 by RFC 1321");
+ bt_test_suite(t_sha1, "Testing SHA-1");
+ bt_test_suite(t_sha224, "Testing SHA-224");
+ bt_test_suite(t_sha256, "Testing SHA-256");
+ bt_test_suite(t_sha384, "Testing SHA-384");
+ bt_test_suite(t_sha512, "Testing SHA-512");
+
+ bt_test_suite(t_md5_hmac, "Testing HMAC-MD5 by RFC 2202");
+ bt_test_suite(t_sha1_hmac, "Testing HMAC-SHA-1 by RFC 2202");
+ bt_test_suite(t_sha224_hmac, "Testing HMAC-SHA-224 by RFC 4231");
+ bt_test_suite(t_sha256_hmac, "Testing HMAC-SHA-256 by RFC 4231");
+ bt_test_suite(t_sha384_hmac, "Testing HMAC-SHA-384 by RFC 4231");
+ bt_test_suite(t_sha512_hmac, "Testing HMAC-SHA-512 by RFC 4231");
+
+ bt_test_suite(t_sha256_concating, "Testing concatenation input string to hash using sha256_update");
+ bt_test_suite(t_sha512_concating, "Testing concatenation input string to hash using sha512_update");
+
+ return bt_exit_value();
+}
diff --git a/lib/patmatch_test.c b/lib/patmatch_test.c
new file mode 100644
index 00000000..b2b4cb92
--- /dev/null
+++ b/lib/patmatch_test.c
@@ -0,0 +1,149 @@
+/*
+ * BIRD Library -- Pattern Matching Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+
+#include "nest/bird.h"
+#include "lib/string.h"
+
+#define MATCH (int) { 1 }
+#define NOMATCH (int) { 0 }
+
+struct match_pair {
+ byte *pattern;
+ byte *data;
+};
+
+static int
+test_matching(void *out_, const void *in_, const void *expected_out_)
+{
+ int *out = out_;
+ const struct match_pair *in = in_;
+ const int *expected_out = expected_out_;
+
+ *out = patmatch(in->pattern, in->data);
+
+ return (*out == *expected_out) ? BT_SUCCESS : BT_FAILURE;
+}
+
+static void
+fmt_match_pair(char *buf, size_t size, const void *data)
+{
+ const struct match_pair *mp = data;
+ snprintf(buf, size, "pattern: '%s', subject: '%s'", mp->pattern, mp->data);
+}
+
+static void
+fmt_match_result(char *buf, size_t size, const void *data)
+{
+ const int *result = data;
+ snprintf(buf, size, *result ? "match" : "no-match");
+}
+
+static int
+t_matching(void)
+{
+ struct bt_pair test_vectors[] = {
+ {
+ .in = & (struct match_pair) {
+ .pattern = "",
+ .data = "",
+ },
+ .out = & MATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "*",
+ .data = "",
+ },
+ .out = & MATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "\\*",
+ .data = "*",
+ },
+ .out = & MATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "\\*",
+ .data = "a",
+ },
+ .out = & NOMATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "?",
+ .data = "",
+ },
+ .out = & NOMATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "abcdefghijklmnopqrstuvwxyz",
+ .data = "abcdefghijklmnopqrstuvwxyz",
+ },
+ .out = & MATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "??????????????????????????",
+ .data = "abcdefghijklmnopqrstuvwxyz",
+ },
+ .out = & MATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "*abcdefghijklmnopqrstuvwxyz*",
+ .data = "abcdefghijklmnopqrstuvwxyz",
+ },
+ .out = & MATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "ab?defg*jklmnop*stu*wxy*z",
+ .data = "abcdefghijklmnopqrstuvwxyz",
+ },
+ .out = & MATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "abcdefghijklmnopqrstuvwxyz",
+ .data = "abcdefghijklmnopqrtuvwxyz",
+ },
+ .out = & NOMATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "abcdefghijklmnopqr?uvwxyz",
+ .data = "abcdefghijklmnopqrstuvwxyz",
+ },
+ .out = & NOMATCH,
+ },
+ {
+ .in = & (struct match_pair) {
+ .pattern = "aa*aaaaa?aaaaaaaaaaaaaaaaaaa",
+ .data = "aaaaaaaaaaaaaaaaaaaaaaaaaa",
+ },
+ .out = & NOMATCH,
+ },
+ };
+
+ return bt_assert_batch(test_vectors, test_matching, fmt_match_pair, fmt_match_result);
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_matching, "Pattern matching");
+
+ return bt_exit_value();
+}
diff --git a/lib/printf_test.c b/lib/printf_test.c
new file mode 100644
index 00000000..9763b7b1
--- /dev/null
+++ b/lib/printf_test.c
@@ -0,0 +1,70 @@
+/*
+ * BIRD Library -- String Functions Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+
+#include "lib/string.h"
+
+#define BSPRINTF(nw, res, buf, fmt, ...) \
+ do { \
+ int n = bsprintf(buf, fmt, ##__VA_ARGS__); \
+ bt_assert_msg(n == nw, "fmt=\"%s\" returns n=%d, want %d", fmt, n, nw); \
+ bt_assert_msg(buf[n] == 0, "fmt=\"%s\" buf[%d] should be \'\\0\', found 0x%02x", fmt, n, buf[n]); \
+ bt_assert_msg(memcmp(buf, res, nw) == 0, "fmt=\"%s\" writes \"%*s\", want \"%*s\"", fmt, (n < nw ? n : nw), buf, nw, res); \
+ } while (0)
+
+static int
+t_simple(void)
+{
+ char buf[256];
+ memset(buf, 0xa5, 256);
+
+ BSPRINTF(0, "", buf, "", NULL);
+ BSPRINTF(1, "%", buf, "%%", NULL);
+ BSPRINTF(2, "%%", buf, "%%%%", NULL);
+
+ BSPRINTF(1, "\x00", buf, "%c", 0);
+ BSPRINTF(1, "@", buf, "@", 64);
+ BSPRINTF(1, "\xff", buf, "%c", 0xff);
+
+ errno = 5;
+ BSPRINTF(18, "Input/output error", buf, "%m");
+ errno = 0;
+
+ BSPRINTF(18, "Input/output error", buf, "%M", 5);
+
+ BSPRINTF(11, "TeSt%StRiNg", buf, "%s", "TeSt%StRiNg");
+
+ if (sizeof(void *) == 4)
+ BSPRINTF(8, "1a15600d", buf, "%p", (void *) 0x1a15600d);
+ else
+ BSPRINTF(16, "00000fee1a15600d", buf, "%p", (void *) 0xfee1a15600d);
+
+ long ln = 0;
+ BSPRINTF(10, "TeStStRiNg", buf, "TeStS%lntRiNg", &ln);
+ bt_assert_msg(ln == 5, "fmt=\"TeStS%%lntRiNg\", &ln makes ln=%ld, want 5", ln);
+
+ BSPRINTF(2, "%d", buf, "%%d", 1);
+ BSPRINTF(1, "1", buf, "%d", 1);
+ BSPRINTF(2, "+1", buf, "%+d", 1);
+ BSPRINTF(2, " 1", buf, "% d", 1);
+ BSPRINTF(2, "-1", buf, "%d", -1);
+ BSPRINTF(11, "-2147483648", buf, "%d", -2147483648);
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_simple, "printf without varargs");
+
+ return bt_exit_value();
+}
diff --git a/lib/slist_test.c b/lib/slist_test.c
new file mode 100644
index 00000000..fd0b1ca6
--- /dev/null
+++ b/lib/slist_test.c
@@ -0,0 +1,384 @@
+/*
+ * BIRD Library -- Safe Linked Lists Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+
+#include "lib/slists.h"
+
+#define MAX_NUM 1000
+
+static snode nodes[MAX_NUM];
+static slist lst;
+
+static void
+show_list(void)
+{
+ bt_debug("\n");
+ bt_debug("list.null is at %p and point to %p \n", &lst.null, lst.null);
+ bt_debug("list.head is at %p and point to %p \n", &lst.head, lst.head);
+ bt_debug("list.tail is at %p and point to %p \n", &lst.tail, lst.tail);
+ bt_debug("list.tail_readers is at %p and point to %p \n", &lst.tail_readers, lst.tail_readers);
+
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ bt_debug("n[%3i] is at %p, .prev (%p) points to %p, .next (%p) points to %p, .readers (%p) points to %p \n",
+ i, &nodes[i], &(nodes[i].prev), nodes[i].prev, &(nodes[i].next), nodes[i].next, &(nodes[i].readers), nodes[i].readers);
+}
+
+static int
+is_filled_list_well_linked(void)
+{
+ int i;
+ bt_assert(lst.head == &nodes[0]);
+ bt_assert(lst.tail == &nodes[MAX_NUM-1]);
+ bt_assert((void *) nodes[0].prev == (void *) &lst.head);
+ bt_assert((void *) nodes[MAX_NUM-1].next == (void *) &lst.null);
+
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ if (i < (MAX_NUM-1))
+ bt_assert(nodes[i].next == &nodes[i+1]);
+
+ if (i > 0)
+ bt_assert(nodes[i].prev == &nodes[i-1]);
+ }
+
+ return 1;
+}
+
+static int
+is_empty_list_well_unlinked(void)
+{
+ bt_assert(lst.head == SNODE &lst.null);
+ bt_assert(lst.tail == SNODE &lst.head);
+
+ bt_assert(EMPTY_SLIST(lst));
+
+ return 1;
+}
+
+static void
+init_list__(slist *l, struct snode nodes[])
+{
+ s_init_list(l);
+
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ nodes[i].next = NULL;
+ nodes[i].prev = NULL;
+ }
+}
+
+static void
+init_list_(void)
+{
+ init_list__(&lst, nodes);
+}
+
+static int
+t_add_tail(void)
+{
+ int i;
+
+ init_list_();
+ for (i = 0; i < MAX_NUM; i++)
+ {
+ s_add_tail(&lst, &nodes[i]);
+ bt_debug(".");
+ bt_assert(lst.tail == &nodes[i]);
+ bt_assert(lst.head == &nodes[0]);
+ bt_assert((void *) nodes[i].next == (void *) &lst.null);
+ if (i > 0)
+ {
+ bt_assert(nodes[i-1].next == &nodes[i]);
+ bt_assert(nodes[i].prev == &nodes[i-1]);
+ }
+ }
+
+ bt_assert(is_filled_list_well_linked());
+
+ return BT_SUCCESS;
+}
+
+static int
+t_add_head(void)
+{
+ int i;
+
+ init_list_();
+ for (i = MAX_NUM-1; i >= 0; i--)
+ {
+ s_add_head(&lst, &nodes[i]);
+ bt_debug(".");
+ bt_assert(lst.head == &nodes[i]);
+ bt_assert(lst.tail == &nodes[MAX_NUM-1]);
+ if (i < MAX_NUM-1)
+ {
+ bt_assert(nodes[i+1].prev == &nodes[i]);
+ bt_assert(nodes[i].next == &nodes[i+1]);
+ }
+ }
+
+ bt_assert(is_filled_list_well_linked());
+
+ return BT_SUCCESS;
+}
+
+static void
+insert_node_(snode *n, snode *after)
+{
+ s_insert_node(n, after);
+ bt_debug(".");
+}
+
+static int
+t_insert_node(void)
+{
+ int i;
+
+ init_list_();
+
+ // add first node
+ insert_node_(&nodes[0], SNODE &lst.head);
+
+ // add odd nodes
+ for (i = 2; i < MAX_NUM; i+=2)
+ insert_node_(&nodes[i], &nodes[i-2]);
+
+ // add even nodes
+ for (i = 1; i < MAX_NUM; i+=2)
+ insert_node_(&nodes[i], &nodes[i-1]);
+
+ bt_debug("\n");
+ bt_assert(is_filled_list_well_linked());
+
+ return BT_SUCCESS;
+}
+
+static void
+fill_list2(slist *l, snode nodes[])
+{
+ int i;
+ for (i = 0; i < MAX_NUM; i++)
+ s_add_tail(l, &nodes[i]);
+}
+
+static void
+fill_list(void)
+{
+ fill_list2(&lst, SNODE nodes);
+}
+
+
+static int
+t_remove_node(void)
+{
+ int i;
+
+ init_list_();
+
+ /* Fill & Remove & Check */
+ fill_list();
+ for (i = 0; i < MAX_NUM; i++)
+ s_rem_node(&nodes[i]);
+ bt_assert(is_empty_list_well_unlinked());
+
+ /* Fill & Remove the half of nodes & Check & Remove the rest nodes & Check */
+ fill_list();
+ for (i = 0; i < MAX_NUM; i+=2)
+ s_rem_node(&nodes[i]);
+
+ int tail_node_index = (MAX_NUM % 2) ? MAX_NUM - 2 : MAX_NUM - 1;
+ bt_assert(lst.head == &nodes[1]);
+ bt_assert(lst.tail == &nodes[tail_node_index]);
+ bt_assert(nodes[tail_node_index].next == SNODE &lst.null);
+
+ for (i = 1; i < MAX_NUM; i+=2)
+ {
+ if (i > 1)
+ bt_assert(nodes[i].prev == &nodes[i-2]);
+ if (i < tail_node_index)
+ bt_assert(nodes[i].next == &nodes[i+2]);
+ }
+
+ for (i = 1; i < MAX_NUM; i+=2)
+ s_rem_node(&nodes[i]);
+ bt_assert(is_empty_list_well_unlinked());
+
+ return BT_SUCCESS;
+}
+
+static int
+t_add_tail_list(void)
+{
+ snode nodes2[MAX_NUM];
+ slist l2;
+
+ init_list__(&lst, SNODE &nodes);
+ fill_list2(&lst, SNODE &nodes);
+
+ init_list__(&l2, SNODE &nodes2);
+ fill_list2(&l2, SNODE &nodes2);
+
+ s_add_tail_list(&lst, &l2);
+
+ bt_assert(nodes[MAX_NUM-1].next == &nodes2[0]);
+ bt_assert(nodes2[0].prev == &nodes[MAX_NUM-1]);
+ bt_assert(lst.tail == &nodes2[MAX_NUM-1]);
+
+ return BT_SUCCESS;
+}
+
+void
+dump(const char *str, slist *a)
+{
+ snode *x;
+
+ bt_debug("%s \n", str);
+ for (x = SHEAD(*a); x; x = x->next)
+ {
+ siterator *i, *j;
+ bt_debug("%p", x);
+ j = (siterator *) x;
+ for (i = x->readers; i; i = i->next)
+ {
+ if (i->prev != j)
+ bt_debug(" ???");
+ j = i;
+ bt_debug(" [%p:%p]", i, i->node);
+ }
+ bt_debug("\n");
+ }
+ bt_debug("---\n");
+}
+
+static int
+t_iterator_walk(void)
+{
+ snode *node;
+ siterator iter;
+
+ init_list_();
+ fill_list();
+
+ int k;
+ int i = 0;
+
+ show_list();
+
+ s_init(&iter, &lst);
+ WALK_SLIST(node, lst)
+ {
+ s_get(&iter);
+ s_put(&iter, node);
+ bt_debug("node->readers: %p, iter: %p, nodes[%d].readers: %p, node: %p, nodes[i]: %p, node->next: %p \n",
+ node->readers, &iter, i, nodes[i].readers, node, &(nodes[i]), node->next);
+ bt_assert(node->readers == &iter);
+ bt_assert(node->readers == nodes[i].readers);
+ bt_assert(node == &(nodes[i]));
+ for (k = 0; k < MAX_NUM; k++)
+ if (k != i)
+ bt_assert(nodes[k].readers == NULL);
+
+ dump("",&lst);
+ i++;
+ }
+
+ return BT_SUCCESS;
+}
+
+static int
+t_original(void)
+{
+ slist a, b;
+ snode *x, *y;
+ siterator i, j;
+
+ s_init_list(&a);
+ s_init_list(&b);
+ x = xmalloc(sizeof(*x));
+ s_add_tail(&a, x);
+ x = xmalloc(sizeof(*x));
+ s_add_tail(&a, x);
+ x = xmalloc(sizeof(*x));
+ s_add_tail(&a, x);
+ dump("1", &a);
+
+ s_init(&i, &a);
+ s_init(&j, &a);
+ dump("2", &a);
+
+ x = s_get(&i);
+ bt_debug("Got %p\n", x);
+ dump("3", &a);
+
+ s_put(&i, x->next);
+ dump("4", &a);
+
+ y = s_get(&j);
+ while (y)
+ {
+ s_put(&j, y);
+ dump("5*", &a);
+ y = s_get(&j)->next;
+ }
+
+ dump("5 done", &a);
+
+ s_rem_node(a.head->next);
+ dump("6 (deletion)", &a);
+
+ s_put(&i, s_get(&i)->next);
+ dump("6 (relink)", &a);
+
+ x = xmalloc(sizeof(*x));
+ s_add_tail(&b, x);
+ dump("7 (second list)", &b);
+
+ s_add_tail_list(&b, &a);
+ dump("8 (after merge)", &b);
+
+ return BT_SUCCESS;
+}
+
+static int
+t_safe_del_walk(void)
+{
+ init_list_();
+ fill_list();
+
+ show_list();
+
+ snode *node, *node_next;
+ WALK_SLIST_DELSAFE(node,node_next, lst)
+ {
+ bt_debug("Will remove node %p \n", node);
+ s_rem_node(SNODE node);
+ }
+ bt_assert(is_empty_list_well_unlinked());
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_add_tail, "Adding nodes to tail of list");
+ bt_test_suite(t_add_head, "Adding nodes to head of list");
+ bt_test_suite(t_insert_node, "Inserting nodes to list");
+ bt_test_suite(t_remove_node, "Removing nodes from list");
+ bt_test_suite(t_add_tail_list, "At the tail of a list adding the another list");
+ bt_test_suite(t_iterator_walk, "Iterator walk");
+ bt_test_suite(t_safe_del_walk, "WALK_SLIST_DELSAFE and s_rem_node all nodes");
+ bt_test_suite(t_original, "The original BIRD test suit for SLIST");
+
+ return bt_exit_value();
+}
diff --git a/lib/slists.c b/lib/slists.c
index 6e0df39e..00f3c84f 100644
--- a/lib/slists.c
+++ b/lib/slists.c
@@ -150,85 +150,3 @@ s_add_tail_list(slist *to, slist *l)
to->tail = q;
s_merge((snode *) &l->null, (snode *) &to->null);
}
-
-#ifdef TEST
-
-#include "lib/resource.h"
-#include <stdio.h>
-
-void dump(char *c, slist *a)
-{
- snode *x;
-
- puts(c);
- for(x=SHEAD(*a); x; x=x->next)
- {
- siterator *i, *j;
- printf("%p", x);
- j = (siterator *) x;
- for(i=x->readers; i; i=i->next)
- {
- if (i->prev != j)
- printf(" ???");
- j = i;
- printf(" [%p:%p]", i, i->node);
- }
- putchar('\n');
- }
- puts("---");
-}
-
-int main(void)
-{
- slist a, b;
- snode *x, *y;
- siterator i, j;
-
- s_init_list(&a);
- s_init_list(&b);
- x = xmalloc(sizeof(*x));
- s_add_tail(&a, x);
- x = xmalloc(sizeof(*x));
- s_add_tail(&a, x);
- x = xmalloc(sizeof(*x));
- s_add_tail(&a, x);
- dump("1", &a);
-
- s_init(&i, &a);
- s_init(&j, &a);
- dump("2", &a);
-
- x = s_get(&i);
- printf("Got %p\n", x);
- dump("3", &a);
-
- s_put(&i, x->next);
- dump("4", &a);
-
- y = s_get(&j);
- while (y)
- {
- s_put(&j, y);
- dump("5*", &a);
- y = s_get(&j)->next;
- }
-
- dump("5 done", &a);
-
- s_rem_node(a.head->next);
- dump("6 (deletion)", &a);
-
- s_put(&i, s_get(&i)->next);
- dump("6 (relink)", &a);
-
- x = xmalloc(sizeof(*x));
- s_add_tail(&b, x);
- dump("7 (second list)", &b);
-
- s_add_tail_list(&b, &a);
- dump("8 (after merge)", &b);
-
- return 0;
-}
-
-#endif