1 /* test random number generator APIs */
2
3 /*
4 * Copyright (c) 2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 /*
10 * This tests the following random number routines:
11 * void z_early_rand_get(uint8_t *buf, size_t length)
12 * uint32_t sys_rand32_get(void);
13 */
14
15
16 #include <zephyr/ztest.h>
17 #include <kernel_internal.h>
18 #include <zephyr/random/random.h>
19
20 #define N_VALUES 10
21
22
23 /**
24 *
25 * @brief Regression test's entry point
26 *
27 */
28
ZTEST(rng_common,test_rand32)29 ZTEST(rng_common, test_rand32)
30 {
31 uint32_t gen, last_gen, tmp;
32 int rnd_cnt;
33 int equal_count = 0;
34 uint32_t buf[N_VALUES];
35 int err;
36
37 /* Test early boot random number generation function */
38 /* Cover the case, where argument "length" is < size of "size_t" */
39 z_early_rand_get((uint8_t *)&tmp, (size_t)1);
40 z_early_rand_get((uint8_t *)&last_gen, sizeof(last_gen));
41 z_early_rand_get((uint8_t *)&gen, sizeof(gen));
42 zassert_true(last_gen != gen && last_gen != tmp && tmp != gen,
43 "z_early_rand_get failed");
44
45 /*
46 * Test subsequently calls sys_rand32_get(), checking
47 * that two values are not equal.
48 */
49 printk("Generating random numbers\n");
50 last_gen = sys_rand32_get();
51 /*
52 * Get several subsequent numbers as fast as possible.
53 * Based on review comments in
54 * https://github.com/zephyrproject-rtos/zephyr/pull/5066
55 * If minimum half of the numbers generated were the same
56 * as the previously generated one, then test fails, this
57 * should catch a buggy sys_rand32_get() function.
58 */
59 for (rnd_cnt = 0; rnd_cnt < (N_VALUES - 1); rnd_cnt++) {
60 gen = sys_rand32_get();
61 if (gen == last_gen) {
62 equal_count++;
63 }
64 last_gen = gen;
65 }
66
67 if (equal_count > N_VALUES / 2) {
68 zassert_false((equal_count > N_VALUES / 2),
69 "random numbers returned same value with high probability");
70 }
71
72 printk("Generating bulk fill random numbers\n");
73 memset(buf, 0, sizeof(buf));
74 sys_rand_get((uint8_t *)(&buf[0]), sizeof(buf));
75
76 for (rnd_cnt = 0; rnd_cnt < (N_VALUES - 1); rnd_cnt++) {
77 gen = buf[rnd_cnt];
78 if (gen == last_gen) {
79 equal_count++;
80 }
81 last_gen = gen;
82 }
83
84 if (equal_count > N_VALUES / 2) {
85 zassert_false((equal_count > N_VALUES / 2),
86 "random numbers returned same value with high probability");
87 }
88
89 #if defined(CONFIG_CSPRNG_ENABLED)
90
91 printk("Generating bulk fill cryptographically secure random numbers\n");
92
93 memset(buf, 0, sizeof(buf));
94
95 err = sys_csrand_get(buf, sizeof(buf));
96
97 zassert_true(err == 0, "sys_csrand_get returned an error");
98
99 for (rnd_cnt = 0; rnd_cnt < (N_VALUES - 1); rnd_cnt++) {
100 gen = buf[rnd_cnt];
101 if (gen == last_gen) {
102 equal_count++;
103 }
104 last_gen = gen;
105 }
106
107 if (equal_count > N_VALUES / 2) {
108 zassert_false((equal_count > N_VALUES / 2),
109 "random numbers returned same value with high probability");
110 }
111
112 #else
113
114 printk("Cryptographically secure implementation not enabled\n");
115 printk("Ensure sys_csrand_get passes for library usage\n");
116
117 err = sys_csrand_get(buf, sizeof(buf));
118
119 zassert_true(err == 0, "sys_csrand_get returned an error");
120
121 #endif /* CONFIG_CSPRNG_ENABLED */
122 }
123
124 ZTEST_SUITE(rng_common, NULL, NULL, NULL, NULL, NULL);
125