diff --git a/ports/stm32/rng.c b/ports/stm32/rng.c index e70eafae71..b23941998a 100644 --- a/ports/stm32/rng.c +++ b/ports/stm32/rng.c @@ -60,4 +60,30 @@ STATIC mp_obj_t pyb_rng_get(void) { } MP_DEFINE_CONST_FUN_OBJ_0(pyb_rng_get_obj, pyb_rng_get); +#else // MICROPY_HW_ENABLE_RNG + +// For MCUs that don't have an RNG we still need to provide a rng_get() function, +// eg for lwIP. A pseudo-RNG is not really ideal but we go with it for now. We +// don't want to use urandom's pRNG because then the user won't see a reproducible +// random stream. + +// Yasmarang random number generator by Ilya Levin +// http://www.literatecode.com/yasmarang +STATIC uint32_t pyb_rng_yasmarang(void) { + static uint32_t pad = 0xeda4baba, n = 69, d = 233; + static uint8_t dat = 0; + + pad += dat + d * n; + pad = (pad << 3) + (pad >> 29); + n = pad | 2; + d ^= (pad << 31) + (pad >> 1); + dat ^= (char)pad ^ (d >> 8) ^ 1; + + return pad ^ (d << 5) ^ (pad >> 18) ^ (dat << 1); +} + +uint32_t rng_get(void) { + return pyb_rng_yasmarang(); +} + #endif // MICROPY_HW_ENABLE_RNG