Refactor crypto RNG; add getrandom() support
[tinc] / test / unit / test_random.c
1 #include "unittest.h"
2 #include "../../src/random.h"
3 #include "../../src/xalloc.h"
4
5 static int setup(void **state) {
6         (void)state;
7         random_init();
8         return 0;
9 }
10
11 static int teardown(void **state) {
12         (void)state;
13         random_exit();
14         return 0;
15 }
16
17 #define zerolen 128
18 static const uint8_t zero[zerolen] = {0};
19
20 static void test_randomize_zero_must_not_change_memory(void **state) {
21         (void)state;
22
23         uint8_t buf[zerolen] = {0};
24         randomize(buf, 0);
25
26         assert_memory_equal(zero, buf, sizeof(buf));
27 }
28
29 static void test_randomize_does_not_overflow(void **state) {
30         (void)state;
31
32         uint8_t buf[zerolen] = {0};
33         const size_t half = sizeof(buf) / 2;
34         randomize(buf, half);
35
36         assert_memory_not_equal(zero, buf, half);
37         assert_memory_equal(zero, &buf[half], half);
38 }
39
40 static void test_randomize_full_changes_memory(void **state) {
41         (void)state;
42
43         uint8_t buf[zerolen] = {0};
44         randomize(buf, sizeof(buf));
45
46         assert_memory_not_equal(zero, buf, sizeof(buf));
47 }
48
49 static void test_randomize_does_not_repeat(void **state) {
50         (void)state;
51
52         // Ask randomize() for small chunks so there's more
53         // chance for it to repeat itself (within reason).
54 #define chunklen 16
55
56         const size_t chunks = 1024;
57         uint8_t (*buffers)[chunklen] = xzalloc(chunks * chunklen);
58
59         // Fill buffers with (hopefully) random data
60         for(size_t i = 0; i < chunks; ++i) {
61                 randomize(buffers[i], chunklen);
62
63                 // Check there was no overflow to the right
64                 if(i < chunks - 1) {
65                         assert_memory_equal(zero, buffers[i + 1], chunklen);
66                 }
67         }
68
69         // Check there were no repetitions (with 128-bit buffers collisions are very unlikely)
70         for(size_t i = 0; i < chunks - 1; ++i) {
71                 for(size_t j = i + 1; j < chunks; ++j) {
72                         assert_memory_not_equal(buffers[i], buffers[j], chunklen);
73                 }
74         }
75
76         free(buffers);
77 #undef chunklen
78 }
79
80 int main(void) {
81         const struct CMUnitTest tests[] = {
82                 cmocka_unit_test(test_randomize_zero_must_not_change_memory),
83                 cmocka_unit_test(test_randomize_does_not_overflow),
84                 cmocka_unit_test(test_randomize_full_changes_memory),
85                 cmocka_unit_test(test_randomize_does_not_repeat),
86         };
87         return cmocka_run_group_tests(tests, setup, teardown);
88 }