diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index d21b36fdcf..6948524972 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -122,6 +122,7 @@ PSEUDOMODULES += posix_headers PSEUDOMODULES += printf_float PSEUDOMODULES += prng PSEUDOMODULES += prng_% +PSEUDOMODULES += fortuna_reseed PSEUDOMODULES += qmc5883l_int PSEUDOMODULES += riotboot_% PSEUDOMODULES += rtt_cmd diff --git a/sys/Kconfig b/sys/Kconfig index 94626af3b9..4366c4aff2 100644 --- a/sys/Kconfig +++ b/sys/Kconfig @@ -70,6 +70,10 @@ config MODULE_LIBSTDCPP depends on HAS_CPP select MODULE_CPP +config MODULE_ATOMIC_UTILS + bool "Atomic access utility functions" + depends on TEST_KCONFIG + config MODULE_SYS bool default y diff --git a/sys/Makefile.dep b/sys/Makefile.dep index 82fbd63306..4615997397 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -419,7 +419,10 @@ ifneq (,$(filter random,$(USEMODULE))) USEMODULE += fortuna USEMODULE += hashes USEMODULE += crypto - USEMODULE += xtimer + ifneq (,$(filter fortuna_reseed,$(USEMODULE))) + USEMODULE += atomic_utils + USEMODULE += xtimer + endif endif ifneq (,$(filter prng_tinymt32,$(USEMODULE))) diff --git a/sys/random/Kconfig b/sys/random/Kconfig index 21aaaabc67..df2559d9c6 100644 --- a/sys/random/Kconfig +++ b/sys/random/Kconfig @@ -19,14 +19,21 @@ choice RANDOM_IMPLEMENTATION default MODULE_PRNG_HWRNG if HAS_PERIPH_HWRNG default MODULE_PRNG_TINYMT32 -config MODULE_PRNG_FORTUNA +menuconfig MODULE_PRNG_FORTUNA bool "Fortuna" select MODULE_HASHES - select MODULE_XTIMER select MODULE_FORTUNA select MODULE_CRYPTO select MODULE_CRYPTO_AES_128 +if MODULE_PRNG_FORTUNA + +config MODULE_FORTUNA_RESEED + bool "Reseed prng according to FORTUNA_RESEED_INTERVAL_MS" + select MODULE_XTIMER + select MODULE_ATOMIC_UTILS +endif + config MODULE_PRNG_HWRNG bool "Hardware RNG" depends on HAS_PERIPH_HWRNG diff --git a/sys/random/fortuna.c b/sys/random/fortuna.c index b7e4ee31c9..9146c0ecb2 100644 --- a/sys/random/fortuna.c +++ b/sys/random/fortuna.c @@ -21,7 +21,6 @@ #include "log.h" #include "mutex.h" - #include "fortuna/fortuna.h" /** diff --git a/sys/random/fortuna/fortuna.c b/sys/random/fortuna/fortuna.c index 1e3f197219..97726d6abf 100644 --- a/sys/random/fortuna/fortuna.c +++ b/sys/random/fortuna/fortuna.c @@ -6,8 +6,16 @@ */ #include - #include "fortuna.h" +#include "kernel_defines.h" +#if FORTUNA_RESEED_INTERVAL_MS > 0 && IS_USED(MODULE_FORTUNA_RESEED) +#include "atomic_utils.h" +#if IS_USED(MODULE_ZTIMER_MSEC) +#include "ztimer.h" +#else +#include "xtimer.h" +#endif +#endif /** * @brief Helper to increment the 128-bit counter (see section 9.4). @@ -137,6 +145,31 @@ static int fortuna_pseudo_random_data(fortuna_state_t *state, uint8_t *out, return 0; } +#if FORTUNA_RESEED_INTERVAL_MS > 0 && IS_USED(MODULE_FORTUNA_RESEED) +void _reseed_callback(void *arg) +{ + fortuna_state_t *state = (fortuna_state_t *) arg; + state->needs_reseed = 1; +} + +static void _reseed_timer_set(fortuna_state_t *state) +{ + atomic_store_u8(&state->needs_reseed, 0); +#if IS_USED(MODULE_ZTIMER_MSEC) + ztimer_set(ZTIMER_MSEC, &state->reseed_timer, FORTUNA_RESEED_INTERVAL_MS); +#else + xtimer_set(&state->reseed_timer, FORTUNA_RESEED_INTERVAL_MS * US_PER_MS); +#endif +} + +static void _reseed_timer_init(fortuna_state_t *state) { + /* initialize reseed timer */ + state->reseed_timer.callback = _reseed_callback; + state->reseed_timer.arg = state; + _reseed_timer_set(state); +} +#endif + /* * Corresponds to section 9.4.1 and 9.5.4. */ @@ -149,9 +182,9 @@ int fortuna_init(fortuna_state_t *state) sha256_init(&state->pools[i].ctx); } -#if FORTUNA_RESEED_INTERVAL - /* set last reseed to ensure initial time diff is correct */ - state->last_reseed = xtimer_now_usec64(); +#if FORTUNA_RESEED_INTERVAL_MS > 0 && IS_USED(MODULE_FORTUNA_RESEED) + /* reseed time init if required */ + _reseed_timer_init(state); #endif #if FORTUNA_LOCK @@ -174,9 +207,9 @@ int fortuna_random_data(fortuna_state_t *state, uint8_t *out, size_t bytes) #endif /* reseed the generator if needed, before returning data */ -#if FORTUNA_RESEED_INTERVAL +#if FORTUNA_RESEED_INTERVAL_MS > 0 && IS_USED(MODULE_FORTUNA_RESEED) if (state->pools[0].len >= FORTUNA_MIN_POOL_SIZE && - (xtimer_now_usec64() - state->last_reseed) > FORTUNA_RESEED_INTERVAL) { + atomic_load_u8(&state->needs_reseed)) { #else if (state->pools[0].len >= FORTUNA_MIN_POOL_SIZE) { #endif @@ -196,8 +229,8 @@ int fortuna_random_data(fortuna_state_t *state, uint8_t *out, size_t bytes) fortuna_reseed(state, buf, len); -#if FORTUNA_RESEED_INTERVAL - state->last_reseed = xtimer_now_usec64(); +#if FORTUNA_RESEED_INTERVAL_MS > 0 && IS_USED(MODULE_FORTUNA_RESEED) + _reseed_timer_set(state); #endif #if FORTUNA_CLEANUP diff --git a/sys/random/fortuna/fortuna.h b/sys/random/fortuna/fortuna.h index 2283ebd16d..ada7e50a81 100644 --- a/sys/random/fortuna/fortuna.h +++ b/sys/random/fortuna/fortuna.h @@ -27,8 +27,14 @@ #ifndef FORTUNA_H #define FORTUNA_H -#include "xtimer.h" #include "mutex.h" +#if FORTUNA_RESEED_INTERVAL_MS > 0 && IS_USED(MODULE_FORTUNA_RESEED) +#if IS_USED(MODULE_ZTIMER_MSEC) +#include "ztimer.h" +#else +#include "xtimer.h" +#endif +#endif #include "crypto/aes.h" #include "hashes/sha256.h" @@ -63,13 +69,17 @@ extern "C" { #define FORTUNA_SEED_SIZE (64U) #endif +#if IS_USED(MODULE_FORTUNA_RESEED) || DOXYGEN /** * @brief Reseed interval in us. After this interval, the PRNG must be * reseeded. Per section 9.5.5, the recommended value is 100ms. Set to * zero to disable this security feature. + * + * @note Requires `fortuna_reseed` module. */ -#ifndef FORTUNA_RESEED_INTERVAL -#define FORTUNA_RESEED_INTERVAL (0) +#ifndef FORTUNA_RESEED_INTERVAL_MS +#define FORTUNA_RESEED_INTERVAL_MS 100 +#endif #endif /** @@ -138,12 +148,17 @@ typedef struct { fortuna_generator_t gen; fortuna_pool_t pools[FORTUNA_POOLS]; uint32_t reseeds; -#if FORTUNA_RESEED_INTERVAL > 0 - uint64_t last_reseed; -#endif #if FORTUNA_LOCK mutex_t lock; #endif +#if FORTUNA_RESEED_INTERVAL_MS > 0 && IS_USED(MODULE_FORTUNA_RESEED) +#if IS_USED(MODULE_ZTIMER_MSEC) + ztimer_t reseed_timer; +#else + xtimer_t reseed_timer; +#endif + uint8_t needs_reseed; +#endif } fortuna_state_t; /**