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