DEV Community

yoctobyte
yoctobyte

Posted on

Adding hardware RNG to micropyton on ESP32

So began my quest. The ESP32 has hardware RNG support. And it runs Micropython, the best of all unless you really need a realtime-OS like Zephyr.

==Background
While busy studying RNG's, and hardware RNG's in particular (as anything else is considered pseudo-RNG). I was implementing such as a hardware RNG on a PC, using microphone input as 'atmospheric noise'. Aka entropy to seed a hardware RNG. Which worked, just fine to be honest. Take samples, take checksum, parity, hash, or anything you fancy. And have perfect random data. NIST tests confirm. It is adequate as entropy, and random.

Comes along this ESP32 i have for an entirely different and currently undisclosed project. But i do recall it having hardware RNG. So i dive into it. The hardware source of entropy is either radio frequency (RF), as in, 'enable wifi or bluetooth'. Or use an (internal) ADC on the (internal) voltage reference as source of entropy.

The rest of Espressif's documentation is unfortunately not that clear. Despite 200+ GPT4 queries and counting. As we understood it so far: When the Radio Frequency (RF) is enabled (WiFi, Bluetooth), we have plenty entropy. As alternative the internal voltage reference can be used. How to enable/disable either or both is not clear.

So, Selecting either, or testing which is used, is not provided by api.

Long story short. I spend some time to fabricate 2 dozen lines of code to modify micropython, to implement hardware RNG. It seems to work so far, but as said, there are side issues we need to address.

Not being able to use ADC is sometimes inacceptable. Forcing RF is acceptable from a software perspective, but draws extra power. And there seem no trivial way to select either. And there may be issues using RF while using it as source of entropy.

Anyways, i'm working on it. The current code https://github.com/yoctobyte/micropython/tree/esp32_hardware_rng exposes an (extra) 'esp32.rng()' function that returns a signed 32-bit integer. I intend to add functionality to enable and disable this 'bootloader_rng*' functionalitym, and implement the 'fill_buffer'.

But given dependences. I now understand why uP is hesitant to implement hardware RNG. You can have it. If. And if. And if not else. So when Both. Are undocumented.

Maybe i should learn to read Chinese so i can read Expressif's ESP32 datasheet in its native language.

Last not least, some benchmarks. It seems we can get about >90kB/s random data from the ESP32 using micropython. That is well within serial communication limits (about 1Mbs). It seems the expressif's random function is the main speed limitation. We can expect a maximum of about 1Mbps hardware random data out of an ESP32.

To be continued.

Top comments (0)