1 /*
2 * Copyright (c) 2018 Oticon A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Pseudo-random entropy generator for the ARCH_POSIX architecture:
7 * Following the principle of reproducibility of the native_posix board
8 * this entropy device will always generate the same random sequence when
9 * initialized with the same seed
10 *
11 * This entropy source should only be used for testing.
12 */
13
14 #define DT_DRV_COMPAT zephyr_native_posix_rng
15
16 #include <zephyr/device.h>
17 #include <zephyr/drivers/entropy.h>
18 #include <zephyr/init.h>
19 #include <zephyr/sys/util.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <zephyr/arch/posix/posix_trace.h>
23 #include "soc.h"
24 #include "cmdline.h" /* native_posix command line options header */
25 #include "nsi_host_trampolines.h"
26 #include "fake_entropy_native_bottom.h"
27
28 static unsigned int seed = 0x5678;
29 static bool seed_random;
30
entropy_native_posix_get_entropy(const struct device * dev,uint8_t * buffer,uint16_t length)31 static int entropy_native_posix_get_entropy(const struct device *dev,
32 uint8_t *buffer,
33 uint16_t length)
34 {
35 ARG_UNUSED(dev);
36
37 while (length) {
38 /*
39 * Note that only 1 thread (Zephyr thread or HW models), runs at
40 * a time, therefore there is no need to use random_r()
41 */
42 long value = nsi_host_random();
43
44 size_t to_copy = MIN(length, sizeof(long int));
45
46 memcpy(buffer, &value, to_copy);
47 buffer += to_copy;
48 length -= to_copy;
49 }
50
51 return 0;
52 }
53
entropy_native_posix_get_entropy_isr(const struct device * dev,uint8_t * buf,uint16_t len,uint32_t flags)54 static int entropy_native_posix_get_entropy_isr(const struct device *dev,
55 uint8_t *buf,
56 uint16_t len, uint32_t flags)
57 {
58 ARG_UNUSED(flags);
59
60 /*
61 * entropy_native_posix_get_entropy() is also safe for ISRs
62 * and always produces data.
63 */
64 entropy_native_posix_get_entropy(dev, buf, len);
65
66 return len;
67 }
68
entropy_native_posix_init(const struct device * dev)69 static int entropy_native_posix_init(const struct device *dev)
70 {
71 ARG_UNUSED(dev);
72 entropy_native_seed(seed, seed_random);
73 posix_print_warning("WARNING: "
74 "Using a test - not safe - entropy source\n");
75 return 0;
76 }
77
78 static const struct entropy_driver_api entropy_native_posix_api_funcs = {
79 .get_entropy = entropy_native_posix_get_entropy,
80 .get_entropy_isr = entropy_native_posix_get_entropy_isr
81 };
82
83 DEVICE_DT_INST_DEFINE(0,
84 entropy_native_posix_init, NULL,
85 NULL, NULL,
86 PRE_KERNEL_1, CONFIG_ENTROPY_INIT_PRIORITY,
87 &entropy_native_posix_api_funcs);
88
add_fake_entropy_option(void)89 static void add_fake_entropy_option(void)
90 {
91 static struct args_struct_t entropy_options[] = {
92 {
93 .option = "seed",
94 .name = "r_seed",
95 .type = 'u',
96 .dest = (void *)&seed,
97 .descript = "A 32-bit integer seed value for the entropy device, such as "
98 "97229 (decimal), 0x17BCD (hex), or 0275715 (octal)"
99 },
100 {
101 .is_switch = true,
102 .option = "seed-random",
103 .type = 'b',
104 .dest = (void *)&seed_random,
105 .descript = "Seed the random generator from /dev/urandom. "
106 "Note your test may not be reproducible if you set this option"
107 },
108 ARG_TABLE_ENDMARKER
109 };
110
111 native_add_command_line_opts(entropy_options);
112 }
113
114 NATIVE_TASK(add_fake_entropy_option, PRE_BOOT_1, 10);
115