Master The Pico WiFi: Random Numbers |
Written by Harry Fairhead & Mike James | ||||||
Monday, 11 March 2024 | ||||||
Page 5 of 5
Pico SDK RandomnessThe mbedtls library has a facility to combine multiple sources of entropy, but the Pico SDK has opted not to implement this. Instead the SDK 1.5 includes a new set of random functions which combine a range of different sources of entropy. There are three new functions:
which return random numbers with the specified number of bits. The 64-bit numbers are used to generate 32- and 128-bit numbers by throwing away the top 32 bits and calling the function twice respectively. For an example of using get_rand_128 see the AES ECB program later in this chapter. The 64-bit generator uses an entropy pooling approach with three sources:
You can disable them, and even configure how they are used, via a number of defines, but apart from turning the ROSC off if it is being used by the processor you are well advised to leave them at their default values. Each of the sources is hashed before being used to improve its statistical properties and is then applied to the output of a high quality PRNG. The PRNG is seeded using random bits gathered when the random number functions are first used – this is slow and can take up to 1ms to seed the PRNG. After this random number generation takes between 10 and 20µs. The entropy sources used for seeding are different from generating random numbers:
You can configure the entropy sources used for seeding separately from those used for subsequent random number generation. The pico_rand library can be used standalone, but note that if you really need pseudo random numbers this isn’t what you want – use the standard rand function instead with a suitable seed. The pico_rand library passes all of the NIST tests but only if you are using SDK 1.51 or you manually patch an error in SDK 1.50. SDK 1.50 contains an error which causes the random numbers to be biased towards zero. To correct this edit: pico/pico-sdk/src/rp2_common/pico_rand/rand.c to change line 275: local_rng_state.r[which] &= splitmix64(bus_counter_value); to read: local_rng_state.r[which] ^= splitmix64(bus_counter_value); That is, change & to ^. Do not use pico_rand without this correction. What is interesting is that pico_rand doesn’t perform significantly differently to the simple ROSC-based generator given earlier, but its complexity and sophistication probably inspire more confidence. The random number function that mbedtls uses, as defined in #include <string.h> #include "pico/platform.h" #include "pico/rand.h" /* Function to feed mbedtls entropy. */ int mbedtls_hardware_poll(void *data __unused, unsigned char *output, size_t len, size_t *olen) { *olen = 0; while(*olen < len) { uint64_t rand_data = get_rand_64(); size_t to_copy = MIN(len, sizeof(rand_data)); memcpy(output + *olen, &rand_data, to_copy); *olen += to_copy; } return 0; } Random numbers are the foundation of good security, but what you do with them also matters. In Chapter but not in this extract
Summary
Master the Raspberry Pi Pico in C:
|
||||||
Last Updated ( Monday, 11 March 2024 ) |