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 "device.h"
17 #include <drivers/entropy.h>
18 #include "init.h"
19 #include <sys/util.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <arch/posix/posix_trace.h>
23 #include "soc.h"
24 #include "cmdline.h" /* native_posix command line options header */
25
26 static unsigned int seed = 0x5678;
27
entropy_native_posix_get_entropy(const struct device * dev,uint8_t * buffer,uint16_t length)28 static int entropy_native_posix_get_entropy(const struct device *dev,
29 uint8_t *buffer,
30 uint16_t length)
31 {
32 ARG_UNUSED(dev);
33
34 while (length) {
35 /*
36 * Note that only 1 thread (Zephyr thread or HW models), runs at
37 * a time, therefore there is no need to use random_r()
38 */
39 long int value = random();
40
41 size_t to_copy = MIN(length, sizeof(long int));
42
43 memcpy(buffer, &value, to_copy);
44 buffer += to_copy;
45 length -= to_copy;
46 }
47
48 return 0;
49 }
50
entropy_native_posix_get_entropy_isr(const struct device * dev,uint8_t * buf,uint16_t len,uint32_t flags)51 static int entropy_native_posix_get_entropy_isr(const struct device *dev,
52 uint8_t *buf,
53 uint16_t len, uint32_t flags)
54 {
55 ARG_UNUSED(flags);
56
57 /*
58 * entropy_native_posix_get_entropy() is also safe for ISRs
59 * and always produces data.
60 */
61 return entropy_native_posix_get_entropy(dev, buf, len);
62 }
63
entropy_native_posix_init(const struct device * dev)64 static int entropy_native_posix_init(const struct device *dev)
65 {
66 ARG_UNUSED(dev);
67 srandom(seed);
68 posix_print_warning("WARNING: "
69 "Using a test - not safe - entropy source\n");
70 return 0;
71 }
72
73 static const struct entropy_driver_api entropy_native_posix_api_funcs = {
74 .get_entropy = entropy_native_posix_get_entropy,
75 .get_entropy_isr = entropy_native_posix_get_entropy_isr
76 };
77
78 DEVICE_DT_INST_DEFINE(0,
79 entropy_native_posix_init, NULL,
80 NULL, NULL,
81 PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
82 &entropy_native_posix_api_funcs);
83
add_fake_entropy_option(void)84 static void add_fake_entropy_option(void)
85 {
86 static struct args_struct_t entropy_options[] = {
87 /*
88 * Fields:
89 * manual, mandatory, switch,
90 * option_name, var_name ,type,
91 * destination, callback,
92 * description
93 */
94 {false, false, false,
95 "seed", "r_seed", 'u',
96 (void *)&seed, NULL,
97 "A 32-bit integer seed value for the entropy device, such as "
98 "97229 (decimal), 0x17BCD (hex), or 0275715 (octal)"},
99 ARG_TABLE_ENDMARKER
100 };
101
102 native_add_command_line_opts(entropy_options);
103 }
104
105 NATIVE_TASK(add_fake_entropy_option, PRE_BOOT_1, 10);
106