1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/sys/atomic.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/drivers/entropy.h>
10 #include <string.h>
11
12 static const struct device *const entropy_dev =
13 DEVICE_DT_GET(DT_CHOSEN(zephyr_entropy));
14
rand_get(uint8_t * dst,size_t outlen,bool csrand)15 static int rand_get(uint8_t *dst, size_t outlen, bool csrand)
16 {
17 uint32_t random_num;
18 int ret;
19
20 __ASSERT(device_is_ready(entropy_dev), "Entropy device %s not ready",
21 entropy_dev->name);
22
23 ret = entropy_get_entropy(entropy_dev, dst, outlen);
24
25 if (unlikely(ret < 0)) {
26 /* Don't try to fill the buffer in case of
27 * cryptographically secure random numbers, just
28 * propagate the driver error.
29 */
30 if (csrand) {
31 return ret;
32 }
33
34 /* Use system timer in case the entropy device couldn't deliver
35 * 32-bit of data. There's not much that can be done in this
36 * situation. An __ASSERT() isn't used here as the HWRNG might
37 * still be gathering entropy during early boot situations.
38 */
39
40 uint32_t len = 0;
41 uint32_t blocksize = 4;
42
43 while (len < outlen) {
44 size_t copylen = outlen - len;
45
46 if (copylen > blocksize) {
47 copylen = blocksize;
48 }
49
50 random_num = k_cycle_get_32();
51 (void)memcpy(&(dst[len]), &random_num, copylen);
52 len += copylen;
53 }
54 }
55
56 return 0;
57 }
58
59 #if defined(CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR)
z_impl_sys_rand_get(void * dst,size_t outlen)60 void z_impl_sys_rand_get(void *dst, size_t outlen)
61 {
62 rand_get(dst, outlen, false);
63 }
64 #endif /* CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR */
65
66 #if defined(CONFIG_HARDWARE_DEVICE_CS_GENERATOR)
67
z_impl_sys_csrand_get(void * dst,size_t outlen)68 int z_impl_sys_csrand_get(void *dst, size_t outlen)
69 {
70 if (rand_get(dst, outlen, true) != 0) {
71 /* Is it the only error it should return ? entropy_sam
72 * can return -ETIMEDOUT for example
73 */
74 return -EIO;
75 }
76
77 return 0;
78 }
79
80 #endif /* CONFIG_HARDWARE_DEVICE_CS_GENERATOR */
81