refactor(rng): move rng read data function to rng_ll.h and update docs of RNG source

This commit is contained in:
gaoxu
2026-05-13 15:09:55 +08:00
parent 3d7a643ff7
commit 07aaba7c7b
18 changed files with 338 additions and 22 deletions

View File

@@ -15,8 +15,8 @@ extern "C" {
/**
* @brief Enable an entropy source for RNG if RF subsystem is disabled
*
* @warning This function is not safe to use if any other subsystem is accessing the RF subsystem or
* the ADC at the same time!
* @warning If use ADC as entropy source, this function is not safe
* if any other subsystem is accessing the RF subsystem or the ADC at the same time!
*
* The exact internal entropy source mechanism depends on the chip in use but
* all SoCs use the SAR ADC to continuously mix random bits (an internal

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -7,7 +7,7 @@
#include "esp_log.h"
#include "bootloader_random.h"
#include "esp_cpu.h"
#include "soc/wdev_reg.h"
#include "hal/rng_ll.h"
#include "hal/rtc_timer_hal.h"
@@ -46,10 +46,10 @@
for (size_t i = 0; i < length; i++) {
#if !SOC_RTC_TIMER_V1
random = REG_READ(WDEV_RND_REG);
random = rng_ll_read_data();
start = esp_cpu_get_cycle_count();
do {
random ^= REG_READ(WDEV_RND_REG);
random ^= rng_ll_read_data();
now = esp_cpu_get_cycle_count();
} while (now - start < RNG_CPU_WAIT_CYCLE_NUM);
@@ -68,10 +68,10 @@
as-is, we repeatedly read the RNG register and XOR all
values.
*/
random = REG_READ(WDEV_RND_REG);
random = rng_ll_read_data();
start = esp_cpu_get_cycle_count();
do {
random ^= REG_READ(WDEV_RND_REG);
random ^= rng_ll_read_data();
now = esp_cpu_get_cycle_count();
} while (now - start < RNG_CPU_WAIT_CYCLE_NUM);
}

View File

@@ -11,7 +11,7 @@
#include <sys/param.h>
#include "esp_attr.h"
#include "esp_cpu.h"
#include "soc/wdev_reg.h"
#include "hal/rng_ll.h"
#include "esp_private/esp_clk.h"
#include "soc/soc_caps.h"
#include "esp_log.h"
@@ -24,9 +24,6 @@
#if SOC_RNG_CLOCK_IS_INDEPENDENT
#include "hal/lp_clkrst_ll.h"
#if SOC_RNG_BUF_CHAIN_ENTROPY_SOURCE || SOC_RNG_RTC_TIMER_ENTROPY_SOURCE
#include "hal/rng_ll.h"
#endif
#endif
#if defined CONFIG_IDF_TARGET_ESP32S3
@@ -62,7 +59,7 @@ uint32_t IRAM_ATTR esp_random(void)
// Return a fixed pattern for bringup purposes
return 0x5A5A5A5A;
#else
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
/* The PRNG which implements the hardware RNG data register gets 2 bits
* of extra entropy from a hardware randomness source every APB clock cycle
* (provided WiFi or BT are enabled). To make sure entropy is not drained
* faster than it is added, this function needs to wait for at least 16 APB
@@ -71,7 +68,7 @@ uint32_t IRAM_ATTR esp_random(void)
*
* As a (probably unnecessary) precaution to avoid returning the
* RNG state as-is, the result is XORed with additional
* WDEV_RND_REG reads while waiting.
* hardware RNG register reads while waiting.
*/
/* This code does not run in a critical section, so CPU frequency switch may
@@ -88,7 +85,7 @@ uint32_t IRAM_ATTR esp_random(void)
for (size_t i = 0; i < sizeof(result); i++) {
do {
ccount = esp_cpu_get_cycle_count();
result ^= REG_READ(WDEV_RND_REG);
result ^= rng_ll_read_data();
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * APB_CYCLE_WAIT_NUM);
#if SOC_RTC_TIMER_SUPPORTED
uint32_t current_rtc_timer_counter = (rtc_timer_hal_get_cycle_count(0) & 0xFF);
@@ -96,7 +93,7 @@ uint32_t IRAM_ATTR esp_random(void)
#endif
}
last_ccount = ccount;
return result ^ REG_READ(WDEV_RND_REG);
return result ^ rng_ll_read_data();
#endif // CONFIG_ESP_BRINGUP_BYPASS_RANDOM_SETTING
}

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/wdev_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(WDEV_RND_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/syscon_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(RNG_DATA_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/syscon_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(RNG_DATA_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,6 +8,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "soc/soc.h"
#include "soc/lpperi_reg.h"
#include "soc/lpperi_struct.h"
#include "hal/lp_clkrst_ll.h"
@@ -17,6 +19,16 @@
extern "C" {
#endif
/**
* @brief Read random data from RNG
*
* @return 32-bit random data
*/
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(LPPERI_RNG_DATA_SYNC_REG);
}
/**
* @brief Enable or disable RNG sampling.
*

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/lpperi_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(LPPERI_RNG_DATA_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/lpperi_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(LPPERI_RNG_DATA_SYNC_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/lpperi_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(LPPERI_RNG_DATA_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/lpperi_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(LPPERI_RNG_DATA_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/wdev_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
// return REG_READ(WDEV_RND_REG); // TODO: IDF-12265
return 0;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "hal/config.h"
#include "soc/soc.h"
#include "soc/lp_system_reg.h"
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
#include "soc/trng_reg.h"
#else
#include "soc/lp_system_reg.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
return REG_READ(RNG_DATA_REG);
#else
return REG_READ(LP_SYSTEM_REG_RNG_DATA_REG);
#endif
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/wdev_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(WDEV_RND_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/wdev_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(WDEV_RND_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#include "soc/trng_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rng_ll_read_data(void)
{
return REG_READ(TRNG_CRC_SYNC_DATA_REG);
}
#ifdef __cplusplus
}
#endif

View File

@@ -12,11 +12,15 @@ Every 32-bit value that the system reads from the RNG_DATA_REG register of the r
.. only:: SOC_WIFI_SUPPORTED or SOC_IEEE802154_SUPPORTED or SOC_BT_SUPPORTED
- Thermal noise comes from the high-speed ADC or SAR ADC or both. Whenever the high-speed ADC or SAR ADC is enabled, bit streams will be generated and fed into the random number generator through an XOR logic gate as random seeds.
- Noise comes from the high-speed ADC, the SAR ADC, or both. When the high-speed ADC or SAR ADC is enabled, the generated bit streams are fed into the random number generator through an XOR logic gate as random seeds.
.. only:: not SOC_WIFI_SUPPORTED and not SOC_IEEE802154_SUPPORTED and not SOC_BT_SUPPORTED
.. only:: esp32p4
- Thermal noise comes from the SAR ADC. Whenever the SAR ADC is enabled, bit streams will be generated and fed into the random number generator through an XOR logic gate as random seeds.
- Thermal noise comes from count values generated by the ring oscillator (BUF_CHAIN) implemented with BUF_CELL, together with the SAR ADC entropy source. Both act as entropy sources to generate random numbers.
.. only:: esp32s31
- Thermal noise comes from multiple entropy sources, including the ring oscillator (BUF_CHAIN) implemented with BUF_CELL, the RFADC, the SAR ADC, and the 40 MHz clock. Their outputs are continuously processed through CRC32 calculations and fed into the random number generator.
.. only:: not esp32

View File

@@ -14,9 +14,13 @@
- 热噪声来自高速 ADC、SAR ADC 或两者。当高速 ADC 或 SAR ADC 被启用时,会生成比特流,并作为随机种子通过 XOR 逻辑门输入到随机数生成器中。
.. only:: not SOC_WIFI_SUPPORTED and not SOC_IEEE802154_SUPPORTED and not SOC_BT_SUPPORTED
.. only:: esp32p4
- 热噪声来自 SAR ADC。当 SAR ADC 被启用时,会生成比特流,并作为随机种子通过 XOR 逻辑门输入到随机数生成器中
- 热噪声来自缓存单元 BUF_CELL 实现的环形振荡器 BUF_CHAIN 生成的计数值,以及 SAR ADC 熵源, 二者共同作为熵源生成随机数
.. only:: esp32s31
- 热噪声来自多个熵源包括缓存单元BUF_CELL实现的环形振荡器BUF_CHAIN、RFADC、SAR ADC 以及 40 MHz 时钟。这些熵源的输出会持续经过 CRC32 计算处理后输入到随机数生成器中。
.. only:: not esp32