ASCON Suite
|
Applications should use the PRNG API to get random data. In particular, the ascon_random() function provides a quick method to get random data that has a uniform spread of entropy and has had any vendor watermarks or bias removed.
The functions in the backend TRNG API are how the library harvests entropy from the system, but that entropy should not be used directly by applications. It may be of poor quality or the CPU vendor may be untrustworthy.
The rest of this page is only of interest to people who want to port the library to a new microcontroller that has a built-in random number generator peripheral.
The library contains several TRNG backends for interfacing to the system's random number generator in the src/random
subdirectory:
Backend | Platforms</td |
dev-random | Linux, FreeBSD, OpenBSD, and other Unix-like systems with a /dev/urandom device. |
due | Arudino Due / SAM3X8E |
esp | ESP8266 and ESP32 modules |
none | Default if the platform is not recognised |
stm32 | STM32 platforms with the HAL_RNG_GenerateRandomNumber() function |
windows | Windows systems using the CryptGenRandom() function |
zephyr | Zephyr RTOS systems with either sys_csrand_get() or bt_rand() configured |
The file ascon-select-trng.h contains #ifdef
's to select the specific backend. You will need to modify this file when adding a new backend.
The "dev-random" backend will use the getrandom()
or genentropy()
functions instead of /dev/urandom, if one of those functions is present on the system.
On Arduino systems, the "none" backend will harvest a very small amount of entropy from the millis()
and micros()
functions but the result will not be very good against a determined adversary.
Patches welcome to add support for TRNG peripherals on other microcontrollers.
There are two separate TRNG API's declared in ascon-trng.h.
The first API is the function ascon_trng_generate() which generates a buffer of random bytes and returns them to the caller. This is called from the PRNG API in various places to request 256 bits of random data to initialize or re-seed the PRNG.
The following example is from the "esp" backend, which uses the Espressif SDK function esp_random()
to acquire 32-bit random values:
The ascon_trng_generate() function should return non-zero if the backend judges that the random noise source is good. If the noise source is not present or is inoperable for some reason, the function should return zero. Since it isn't possible to determine if esp_random()
is working correctly or not we have to simply assume that it works and return 1.
The second TRNG API defines the functions ascon_trng_init(), ascon_trng_free(), ascon_trng_generate_32(), ascon_trng_generate_64(), and ascon_trng_reseed(). These are used by masked ciphers to generate random masking material at a high data rate.
Whereas ascon_trng_generate() can take its time to generate high-quality random data, ascon_trng_generate_32() and ascon_trng_generate_64() must operate as fast as possible. In the case of the "esp" backend, the esp_random()
function is as fast as we're going to get:
On some platforms, the normal random source is too slow for masking. Such backends define ASCON_TRNG_MIXER
and implement a simple PRNG based on the ASCON permutation to stretch an initial seed out into an arbitrary amount of masking material. The mixer is implemented in the ascon-trng-mixer.c file.
On systems that use a mixer, the function ascon_trng_reseed() should request a new seed using the same method as ascon_trng_generate() and mix the new seed into the mixer state. This provides freshness to the random state over time when very large amounts of masking material are being generated. For the "esp", no re-seeding is required (or possible):
The "none" backend provides a weak function called ascon_trng_get_bytes() that allows the application to provide its own noise source if the library was unable to find a suitable backend:
The "none" backend will mix the noise data that comes from the application with system timers just in case the application noise source fails.
The escape hatch only works with the "none" backend. The weak function will be ignored if some other backend has been selected.