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
36 /* Test early boot random number generation function */
37 /* Cover the case, where argument "length" is < size of "size_t" */
38 z_early_rand_get((uint8_t *)&tmp, (size_t)1);
39 z_early_rand_get((uint8_t *)&last_gen, sizeof(last_gen));
40 z_early_rand_get((uint8_t *)&gen, sizeof(gen));
41 zassert_true(last_gen != gen && last_gen != tmp && tmp != gen,
42 "z_early_rand_get failed");
43
44 /*
45 * Test subsequently calls sys_rand32_get(), checking
46 * that two values are not equal.
47 */
48 printk("Generating random numbers\n");
49 last_gen = sys_rand32_get();
50 /*
51 * Get several subsequent numbers as fast as possible.
52 * Based on review comments in
53 * https://github.com/zephyrproject-rtos/zephyr/pull/5066
54 * If minimum half of the numbers generated were the same
55 * as the previously generated one, then test fails, this
56 * should catch a buggy sys_rand32_get() function.
57 */
58 for (rnd_cnt = 0; rnd_cnt < (N_VALUES - 1); rnd_cnt++) {
59 gen = sys_rand32_get();
60 if (gen == last_gen) {
61 equal_count++;
62 }
63 last_gen = gen;
64 }
65
66 if (equal_count > N_VALUES / 2) {
67 zassert_false((equal_count > N_VALUES / 2),
68 "random numbers returned same value with high probability");
69 }
70
71 printk("Generating bulk fill random numbers\n");
72 memset(buf, 0, sizeof(buf));
73 sys_rand_get((uint8_t *)(&buf[0]), sizeof(buf));
74
75 for (rnd_cnt = 0; rnd_cnt < (N_VALUES - 1); rnd_cnt++) {
76 gen = buf[rnd_cnt];
77 if (gen == last_gen) {
78 equal_count++;
79 }
80 last_gen = gen;
81 }
82
83 if (equal_count > N_VALUES / 2) {
84 zassert_false((equal_count > N_VALUES / 2),
85 "random numbers returned same value with high probability");
86 }
87
88 #if defined(CONFIG_CSPRNG_ENABLED)
89
90 printk("Generating bulk fill cryptographically secure random numbers\n");
91
92 memset(buf, 0, sizeof(buf));
93
94 int err = sys_csrand_get(buf, sizeof(buf));
95
96 zassert_true(err == 0, "sys_csrand_get returned an error");
97
98 for (rnd_cnt = 0; rnd_cnt < (N_VALUES - 1); rnd_cnt++) {
99 gen = buf[rnd_cnt];
100 if (gen == last_gen) {
101 equal_count++;
102 }
103 last_gen = gen;
104 }
105
106 if (equal_count > N_VALUES / 2) {
107 zassert_false((equal_count > N_VALUES / 2),
108 "random numbers returned same value with high probability");
109 }
110
111 #else
112
113 printk("Cryptographically secure random number APIs not enabled\n");
114
115 #endif /* CONFIG_CSPRNG_ENABLED */
116 }
117
118 ZTEST_SUITE(rng_common, NULL, NULL, NULL, NULL, NULL);
119