1 /*
2  * Copyright (c) 2017 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <zephyr/bluetooth/bluetooth.h>
7 #include <zephyr/drivers/entropy.h>
8 #include <zephyr/ztest.h>
9 
10 /*
11  * @addtogroup t_entropy_api
12  * @{
13  * @defgroup t_entropy_get_entropy test_entropy_get_entropy
14  * @brief TestPurpose: verify Get entropy works
15  * @details
16  * - Test Steps
17  *   -# Read random numbers from Entropy driver.
18  *   -# Verify whether buffer overflow occurred or not.
19  *   -# Verify whether buffer completely filled or not.
20  * - Expected Results
21  *   -# Random number should be generated.
22  * @}
23  */
24 
25 #define BUFFER_LENGTH           10
26 #define RECHECK_RANDOM_ENTROPY  0x10
27 
28 #ifdef CONFIG_RANDOM_BUFFER_NOCACHED
29 __attribute__((__section__(".nocache")))
30 static uint8_t entropy_buffer[BUFFER_LENGTH] = {0};
31 #else
32 static uint8_t entropy_buffer[BUFFER_LENGTH] = {0};
33 #endif
34 
random_entropy(const struct device * dev,char * buffer,char num)35 static int random_entropy(const struct device *dev, char *buffer, char num)
36 {
37 	int ret, i;
38 	int count = 0;
39 
40 	(void)memset(buffer, num, BUFFER_LENGTH);
41 
42 	/* The BUFFER_LENGTH-1 is used so the driver will not
43 	 * write the last byte of the buffer. If that last
44 	 * byte is not 0 on return it means the driver wrote
45 	 * outside the passed buffer, and that should never
46 	 * happen.
47 	 */
48 	ret = entropy_get_entropy(dev, buffer, BUFFER_LENGTH - 1);
49 	if (ret) {
50 		TC_PRINT("Error: entropy_get_entropy failed: %d\n", ret);
51 		return TC_FAIL;
52 	}
53 	if (buffer[BUFFER_LENGTH - 1] != num) {
54 		TC_PRINT("Error: entropy_get_entropy buffer overflow\n");
55 		return TC_FAIL;
56 	}
57 
58 	for (i = 0; i < BUFFER_LENGTH - 1; i++) {
59 		TC_PRINT("  0x%02x\n", buffer[i]);
60 		if (buffer[i] == num) {
61 			count++;
62 		}
63 	}
64 
65 	if (count >= 2) {
66 		return RECHECK_RANDOM_ENTROPY;
67 	} else {
68 		return TC_PASS;
69 	}
70 }
71 
72 /*
73  * Function invokes the get_entropy callback in driver
74  * to get the random data and fill to passed buffer
75  */
get_entropy(void)76 static int get_entropy(void)
77 {
78 	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_entropy));
79 	int ret;
80 
81 	if (!device_is_ready(dev)) {
82 		TC_PRINT("error: random device not ready\n");
83 		return TC_FAIL;
84 	}
85 
86 	TC_PRINT("random device is %p, name is %s\n",
87 		 dev, dev->name);
88 
89 	ret = random_entropy(dev, entropy_buffer, 0);
90 
91 	/* Check whether 20% or more of buffer still filled with default
92 	 * value(0), if yes then recheck again by filling nonzero value(0xa5)
93 	 * to buffer. Recheck random_entropy and verify whether 20% or more
94 	 * of buffer filled with value(0xa5) or not.
95 	 */
96 	if (ret == RECHECK_RANDOM_ENTROPY) {
97 		ret = random_entropy(dev, entropy_buffer, 0xa5);
98 		if (ret == RECHECK_RANDOM_ENTROPY) {
99 			return TC_FAIL;
100 		} else {
101 			return ret;
102 		}
103 	}
104 	return ret;
105 }
106 
ZTEST(entropy_api,test_entropy_get_entropy)107 ZTEST(entropy_api, test_entropy_get_entropy)
108 {
109 	zassert_true(get_entropy() == TC_PASS);
110 }
111 
entropy_api_setup(void)112 void *entropy_api_setup(void)
113 {
114 #ifdef CONFIG_BT
115 	bt_enable(NULL);
116 #endif /* CONFIG_BT */
117 
118 	return NULL;
119 }
120 
121 ZTEST_SUITE(entropy_api, NULL, entropy_api_setup, NULL, NULL, NULL);
122