From 7adb50b9019fcb295ea2b61f49cdf9e51a21b304 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Tue, 29 Apr 2025 12:23:21 +0200 Subject: [PATCH] cpu/esp32/periph/hwrng: enable/disable bootloader RNG If the ADC SAR is used, the Bootloader RNG must not be enabled before the random numbers are actually required. The reason is that the Bootloader RNG uses the noise of the ADC SAR reference voltage as a non-RF entropy source. The calibration of the ADC SAR does not work correctly in this case. Therefore, the Bootloader RNG is only enabled if random numbers are really required. --- cpu/esp32/periph/hwrng.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/cpu/esp32/periph/hwrng.c b/cpu/esp32/periph/hwrng.c index 9048a5ce99..c1eae7fb47 100644 --- a/cpu/esp32/periph/hwrng.c +++ b/cpu/esp32/periph/hwrng.c @@ -25,25 +25,15 @@ #include "bootloader_random.h" #include "esp_random.h" -#include "soc/wdev_reg.h" - -#define RNG_DATA_REG (*(volatile uint32_t *)RNG_DATA_REG_ADDR) void hwrng_init(void) { - if (!IS_USED(MODULE_WIFI_ANY)) { - /* - * The hardware RNG generates random numbers uses the noise in the - * RF system of the WiFi or the BT interface as entropy source. - * If both are disabled, the random number generator just returns - * pseudo-random numbers. - * However, the bootloader use an internal non-RF entropy source, - * the internal reference voltage noise. This can be re-enabled - * after startup as entropy source for applications that don't - * use the WiFi or the BT interface. - */ - bootloader_random_enable(); - } + /* If the ADC SAR is used, the Bootloader RNG must not be enabled before + * the random numbers are actually required. The reason is that the + * Bootloader RNG uses the noise of the ADC SAR reference voltage as + * a non-RF entropy source. The calibration of the ADC SAR does not + * work correctly in this case. Therefore, the Bootloader RNG is only + * enabled if random numbers are really required. */ } /** @@ -56,10 +46,22 @@ void hwrng_init(void) */ void hwrng_read(void *buf, unsigned int num) { + if (!IS_USED(MODULE_ESP_WIFI_ANY) && !IS_USED(MODULE_ESP_BLE)) { + /* enable the Bootloader RNG if WiFi and BT are not used */ + bootloader_random_enable(); + } + esp_fill_random(buf, num); + + if (!IS_USED(MODULE_ESP_WIFI_ANY) && !IS_USED(MODULE_ESP_BLE)) { + /* disable the Bootloader RNG to ensure that ADC SAR calibration works */ + bootloader_random_disable(); + } } uint32_t hwrand(void) { - return esp_random(); + uint32_t rand; + hwrng_read(&rand, 4); + return rand; }