From d6881de3b3f70e51a8ea1882bd43e03b2bb7554b Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Fri, 2 Dec 2022 11:41:10 -0600 Subject: [PATCH] random: Change testing random generator The old random timer test was not random-looking enough on some platforms. Replace with new test which is psuedo-xoshiro. The generator is still deterministic and does not depend on entropy at all, but should look more random for testing. Change name of generator tree-wide also. Signed-off-by: Declan Snyder --- doc/services/crypto/random/index.rst | 6 +-- .../boards/nrf5340dk_nrf5340_cpuapp.conf | 2 +- subsys/random/CMakeLists.txt | 4 +- subsys/random/Kconfig | 7 ++-- .../random/{rand32_timer.c => rand32_test.c} | 40 +++++++++++++++---- .../crypto/rand32/prj_sw_random_systimer.conf | 2 +- tests/net/lib/mqtt_publisher/prj_tls.conf | 2 +- tests/ztest/base/prj_verbose_0.conf | 2 +- 8 files changed, 44 insertions(+), 21 deletions(-) rename subsys/random/{rand32_timer.c => rand32_test.c} (67%) diff --git a/doc/services/crypto/random/index.rst b/doc/services/crypto/random/index.rst index 0e281c5b083..151eab84674 100644 --- a/doc/services/crypto/random/index.rst +++ b/doc/services/crypto/random/index.rst @@ -47,9 +47,9 @@ An override of the default value can be specified in the SOC or board The random number generators available include: -:kconfig:option:`CONFIG_TIMER_RANDOM_GENERATOR` - enables number generator based on system timer clock. This number - generator is not random and used for testing only. +:kconfig:option:`CONFIG_RANDOM_TEST_GENERATOR` + This number generator is not random and used for testing only. + This generator does not depend on entropy. :kconfig:option:`CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR` enables a random number generator that uses the enabled hardware diff --git a/samples/subsys/usb/hid-cdc/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/subsys/usb/hid-cdc/boards/nrf5340dk_nrf5340_cpuapp.conf index 48384ea0232..71903faf717 100644 --- a/samples/subsys/usb/hid-cdc/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/subsys/usb/hid-cdc/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -1,2 +1,2 @@ CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_TIMER_RANDOM_GENERATOR=y +CONFIG_RANDOM_TEST_GENERATOR=y diff --git a/subsys/random/CMakeLists.txt b/subsys/random/CMakeLists.txt index 3bacc9b014f..e9a30aa67fe 100644 --- a/subsys/random/CMakeLists.txt +++ b/subsys/random/CMakeLists.txt @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 if (CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR OR - CONFIG_TIMER_RANDOM_GENERATOR OR + CONFIG_RANDOM_TEST_GENERATOR OR CONFIG_XOSHIRO_RANDOM_GENERATOR) zephyr_library() zephyr_library_sources_ifdef(CONFIG_USERSPACE rand32_handlers.c) @@ -17,10 +17,10 @@ endif() # XOROSHIRO builds the XOSHIRO implementation because a Kconfig choice cannot # select another choice as a means of deprecating the symbol. Swapping out the # implementation lets out-of-tree users still build until the symbol is removed. -zephyr_library_sources_ifdef(CONFIG_TIMER_RANDOM_GENERATOR rand32_timer.c) zephyr_library_sources_ifdef(CONFIG_XOROSHIRO_RANDOM_GENERATOR rand32_xoshiro128.c) zephyr_library_sources_ifdef(CONFIG_XOSHIRO_RANDOM_GENERATOR rand32_xoshiro128.c) zephyr_library_sources_ifdef(CONFIG_CTR_DRBG_CSPRNG_GENERATOR rand32_ctr_drbg.c) +zephyr_library_sources_ifdef(CONFIG_RANDOM_TEST_GENERATOR rand32_test.c) if (CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR OR CONFIG_HARDWARE_DEVICE_CS_GENERATOR) zephyr_library_sources(rand32_entropy_device.c) diff --git a/subsys/random/Kconfig b/subsys/random/Kconfig index d945bbbcec0..cebcc313a31 100644 --- a/subsys/random/Kconfig +++ b/subsys/random/Kconfig @@ -40,13 +40,12 @@ choice RNG_GENERATOR_CHOICE to support random request then select that. Otherwise, select the XOSHIRO algorithm -config TIMER_RANDOM_GENERATOR +config RANDOM_TEST_GENERATOR bool "System timer clock based number generator" depends on TEST_RANDOM_GENERATOR help - This options enables number generator based on system timer - clock. This number generator is not random and used for - testing only. + This number generator is not random and used only for testing. + Does not rely on an entropy driver, so can be used without entropy. config ENTROPY_DEVICE_RANDOM_GENERATOR bool "Use entropy driver to generate random numbers" diff --git a/subsys/random/rand32_timer.c b/subsys/random/rand32_test.c similarity index 67% rename from subsys/random/rand32_timer.c rename to subsys/random/rand32_test.c index d680b39d618..15559b4200a 100644 --- a/subsys/random/rand32_timer.c +++ b/subsys/random/rand32_test.c @@ -14,21 +14,44 @@ * provide a random number generator. */ +#include #include #include #include -#include #include +#include #if defined(__GNUC__) -/* - * Symbols used to ensure a rapid series of calls to random number generator - * return different values. - */ -static atomic_val_t _rand32_counter; +/* seed the state with pseudo-random data */ +static uint32_t state[4] = {0, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278}; + +static struct k_spinlock rand_state_lock; + +static inline uint32_t rotl(const uint32_t x, int k) +{ + return (x << k) | (x >> (32 - k)); +} + +static uint32_t xoshiro128_next(void) +{ + const uint32_t result = rotl(state[0] + state[3], 7) + state[0]; + const uint32_t t = state[1] << 9; + + k_spinlock_key_t lock_key = k_spin_lock(&rand_state_lock); + + state[2] ^= state[0]; + state[3] ^= state[1]; + state[1] ^= state[2]; + state[0] ^= state[3]; + + state[2] ^= t; + state[3] = rotl(state[3], 11); -#define _RAND32_INC 1000000003U + k_spin_unlock(&rand_state_lock, lock_key); + + return result; +} /** * @brief Get a 32 bit random number @@ -41,7 +64,7 @@ static atomic_val_t _rand32_counter; */ uint32_t z_impl_sys_rand32_get(void) { - return k_cycle_get_32() + atomic_add(&_rand32_counter, _RAND32_INC); + return xoshiro128_next(); } /** @@ -68,4 +91,5 @@ void z_impl_sys_rand_get(void *dst, size_t outlen) outlen -= blocksize; } } + #endif /* __GNUC__ */ diff --git a/tests/crypto/rand32/prj_sw_random_systimer.conf b/tests/crypto/rand32/prj_sw_random_systimer.conf index 2adbee9e418..dcdcbdbaad8 100644 --- a/tests/crypto/rand32/prj_sw_random_systimer.conf +++ b/tests/crypto/rand32/prj_sw_random_systimer.conf @@ -3,4 +3,4 @@ CONFIG_ZTEST_NEW_API=y CONFIG_LOG=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_TIMER_RANDOM_GENERATOR=y +CONFIG_RANDOM_TEST_GENERATOR=y diff --git a/tests/net/lib/mqtt_publisher/prj_tls.conf b/tests/net/lib/mqtt_publisher/prj_tls.conf index 9e575d1bc07..e97e2af1e57 100644 --- a/tests/net/lib/mqtt_publisher/prj_tls.conf +++ b/tests/net/lib/mqtt_publisher/prj_tls.conf @@ -2,7 +2,7 @@ CONFIG_NETWORKING=y CONFIG_NET_TCP=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_TIMER_RANDOM_GENERATOR=y +CONFIG_RANDOM_TEST_GENERATOR=y CONFIG_NET_ARP=y CONFIG_NET_L2_ETHERNET=y diff --git a/tests/ztest/base/prj_verbose_0.conf b/tests/ztest/base/prj_verbose_0.conf index 4f00bd038ad..db75e96ecce 100644 --- a/tests/ztest/base/prj_verbose_0.conf +++ b/tests/ztest/base/prj_verbose_0.conf @@ -4,7 +4,7 @@ CONFIG_ZTEST_ASSERT_VERBOSE=0 CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_TIMER_RANDOM_GENERATOR=y +CONFIG_RANDOM_TEST_GENERATOR=y CONFIG_ZTEST_SHUFFLE=y CONFIG_ZTEST_SHUFFLE_SUITE_REPEAT_COUNT=2