Random Number Generation¶
The hardware RNG produces true random numbers under any of the following conditions:
RF subsystem is enabled (i.e. Wi-Fi or Bluetooth are enabled).
While the ESP-IDF Second stage bootloader is running. This is because the default ESP-IDF bootloader implementation calls
bootloader_random_enable()when the bootloader starts, and
bootloader_random_disable()before executing the app.
When any of these conditions are true, samples of physical noise are continuously mixed into the internal hardware RNG state to provide entropy. Consult the ESP32-C3 Technical Reference Manual > Random Number Generator (RNG) [PDF] chapter for more details.
If none of the above conditions are true, the output of the RNG should be considered pseudo-random only.
During startup, ESP-IDF bootloader temporarily enables a non-RF entropy source (internal reference voltage noise) that provides entropy for any first boot key generation. However, after the app starts executing then normally only pseudo-random numbers are available until Wi-Fi or Bluetooth are initialized.
To re-enable the entropy source temporarily during app startup, or for an application that does not use Wi-Fi or Bluetooth, call the function
bootloader_random_enable() to re-enable the internal entropy source. The function
bootloader_random_disable() must be called to disable the entropy source again before using ADC, Wi-Fi or Bluetooth.
The entropy source enabled during the boot process by the ESP-IDF Second Stage Bootloader will seed the internal RNG state with some entropy. However, the internal hardware RNG state is not large enough to provide a continuous stream of true random numbers. This is why a continuous entropy source must be enabled whenever true random numbers are required.
If an application requires a source of true random numbers but it is not possible to permanently enable a hardware entropy source, consider using a strong software DRBG implementation such as the mbedTLS CTR-DRBG or HMAC-DRBG, with an initial seed of entropy from hardware RNG true random numbers.
ESP32-C3 RNG contains a secondary entropy source, based on sampling an asynchronous 8MHz internal oscillator (see the Technical Reference Manual for details). This entropy source is always enabled in ESP-IDF and continuously mixed into the RNG state by hardware. In testing, this secondary entropy source was sufficient to pass the Dieharder random number test suite without the main entropy source enabled (test input was created by concatenating short samples from a continuously resetting ESP32-C3). However, it is currently only guaranteed that true random numbers will be produced when the main entropy source is also enabled as described above.
Get one random 32-bit word from hardware RNG.
If Wi-Fi or Bluetooth are enabled, this function returns true random numbers. In other situations, if true random numbers are required then consult the ESP-IDF Programming Guide “Random Number Generation” section for necessary prerequisites.
This function automatically busy-waits to ensure enough external entropy has been introduced into the hardware RNG state, before returning a new random number. This delay is very short (always less than 100 CPU cycles).
Random value between 0 and UINT32_MAX
esp_fill_random(void *buf, size_t len)¶
Fill a buffer with random bytes from hardware RNG.
This function is implemented via calls to esp_random(), so the same constraints apply.
buf: Pointer to buffer to fill with random numbers.
len: Length of buffer in bytes
Enable an entropy source for RNG if RF is disabled.
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 noise reading) into the HWRNG. Consult the SoC Technical Reference Manual for more information.
Can also be used from app code early during operation, if true random numbers are required before RF is initialised. Consult ESP-IDF Programming Guide “Random Number Generation” section for details.
Disable entropy source for RNG.
Disables internal entropy source. Must be called after bootloader_random_enable() and before RF features, ADC, or I2S (ESP32 only) are initialized.
Consult the ESP-IDF Programming Guide “Random Number Generation” section for details.
bootloader_fill_random(void *buffer, size_t length)¶
Fill buffer with ‘length’ random bytes.
If this function is being called from app code only, and never from the bootloader, then it’s better to call esp_fill_random().
buffer: Pointer to buffer
length: This many bytes of random data will be copied to buffer
A compatible version of the Linux
getrandom() function is also provided for ease of porting:
#include <sys/random.h> ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
This function is implemented by calling
flags argument is ignored, this function is always non-blocking but the strength of any random numbers is dependent on the same conditions described above.
Return value is -1 (with
errno set to
EFAULT) if the
buf argument is NULL, and equal to