| /* |
| * Copyright (c) 2018 Oticon A/S |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| * |
| * Pseudo-random entropy generator for the ARCH_POSIX architecture: |
| * Following the principle of reproducibility of the native_posix board |
| * this entropy device will always generate the same random sequence when |
| * initialized with the same seed |
| * |
| * This entropy source should only be used for testing. |
| */ |
| |
| #define DT_DRV_COMPAT zephyr_native_posix_rng |
| |
| #include <zephyr/device.h> |
| #include <zephyr/drivers/entropy.h> |
| #include <zephyr/init.h> |
| #include <zephyr/sys/util.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <zephyr/arch/posix/posix_trace.h> |
| #include "soc.h" |
| #include "cmdline.h" /* native_posix command line options header */ |
| #include "nsi_host_trampolines.h" |
| #include "fake_entropy_native_bottom.h" |
| |
| static unsigned int seed = 0x5678; |
| static bool seed_random; |
| static bool seed_set; |
| |
| static int entropy_native_posix_get_entropy(const struct device *dev, |
| uint8_t *buffer, |
| uint16_t length) |
| { |
| ARG_UNUSED(dev); |
| |
| while (length) { |
| /* |
| * Note that only 1 thread (Zephyr thread or HW models), runs at |
| * a time, therefore there is no need to use random_r() |
| */ |
| long value = nsi_host_random(); |
| |
| size_t to_copy = MIN(length, sizeof(long int)); |
| |
| memcpy(buffer, &value, to_copy); |
| buffer += to_copy; |
| length -= to_copy; |
| } |
| |
| return 0; |
| } |
| |
| static int entropy_native_posix_get_entropy_isr(const struct device *dev, |
| uint8_t *buf, |
| uint16_t len, uint32_t flags) |
| { |
| ARG_UNUSED(flags); |
| |
| /* |
| * entropy_native_posix_get_entropy() is also safe for ISRs |
| * and always produces data. |
| */ |
| entropy_native_posix_get_entropy(dev, buf, len); |
| |
| return len; |
| } |
| |
| static int entropy_native_posix_init(const struct device *dev) |
| { |
| ARG_UNUSED(dev); |
| if (seed_set || seed_random || |
| IS_ENABLED(CONFIG_FAKE_ENTROPY_NATIVE_POSIX_SEED_BY_DEFAULT)) { |
| entropy_native_seed(seed, seed_random); |
| } |
| posix_print_warning("WARNING: " |
| "Using a test - not safe - entropy source\n"); |
| return 0; |
| } |
| |
| static const struct entropy_driver_api entropy_native_posix_api_funcs = { |
| .get_entropy = entropy_native_posix_get_entropy, |
| .get_entropy_isr = entropy_native_posix_get_entropy_isr |
| }; |
| |
| DEVICE_DT_INST_DEFINE(0, |
| entropy_native_posix_init, NULL, |
| NULL, NULL, |
| PRE_KERNEL_1, CONFIG_ENTROPY_INIT_PRIORITY, |
| &entropy_native_posix_api_funcs); |
| |
| static void seed_was_set(char *argv, int offset) |
| { |
| ARG_UNUSED(argv); |
| ARG_UNUSED(offset); |
| seed_set = true; |
| } |
| |
| static void add_fake_entropy_option(void) |
| { |
| static struct args_struct_t entropy_options[] = { |
| { |
| .option = "seed", |
| .name = "r_seed", |
| .type = 'u', |
| .dest = (void *)&seed, |
| .call_when_found = seed_was_set, |
| .descript = "A 32-bit integer seed value for the entropy device, such as " |
| "97229 (decimal), 0x17BCD (hex), or 0275715 (octal)" |
| }, |
| { |
| .is_switch = true, |
| .option = "seed-random", |
| .type = 'b', |
| .dest = (void *)&seed_random, |
| .descript = "Seed the random generator from /dev/urandom. " |
| "Note your test may not be reproducible if you set this option" |
| }, |
| ARG_TABLE_ENDMARKER |
| }; |
| |
| native_add_command_line_opts(entropy_options); |
| } |
| |
| NATIVE_TASK(add_fake_entropy_option, PRE_BOOT_1, 10); |