rp2: Switch all RNG sources from ROSC to pico_rand.

Replace the custom rosc_random_u8()/rosc_random_u32() implementation with
the pico_rand API from the Pico SDK. The RP2040 datasheet notes that ROSC
"does not meet the requirements of randomness for security systems because
it can be compromised", and the current 8-bit LFSR conditioning is not a
vetted algorithm under NIST SP 800-90B.

pico_rand uses various hardware RNG sources depending on the available
platform (including the RP2350 hardware TRNG) and is officially supported
and maintained as part of the Pico SDK.

This changes os.urandom(), the mbedTLS entropy source, the PRNG seed, and
the lwIP random function to all use pico_rand, and removes the custom ROSC
random functions from main.c.

Signed-off-by: Michel Le Bihan <michel@lebihan.pl>
This commit is contained in:
Michel Le Bihan
2026-02-18 15:23:10 +01:00
committed by Damien George
parent 9e2df2da29
commit 158cbd6065
6 changed files with 15 additions and 31 deletions

View File

@@ -236,6 +236,7 @@ set(PICO_SDK_COMPONENTS
pico_platform_compiler
pico_platform_panic
pico_platform_sections
pico_rand
pico_runtime
pico_runtime_init
pico_stdio

View File

@@ -9,11 +9,11 @@
#define LWIP_ND6_NUM_DESTINATIONS 4
#define LWIP_ND6_QUEUEING 0
#define LWIP_RAND() rosc_random_u32()
#define LWIP_RAND() get_rand_32()
// Include common lwIP configuration.
#include "extmod/lwip-include/lwipopts_common.h"
extern uint32_t rosc_random_u32(void);
#include "pico/rand.h"
#endif // MICROPY_INCLUDED_RP2_LWIP_LWIPOPTS_H

View File

@@ -53,7 +53,6 @@
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "pico/unique_id.h"
#include "hardware/structs/rosc.h"
#if MICROPY_PY_LWIP
#include "lwip/init.h"
#include "lwip/apps/mdns.h"
@@ -314,22 +313,3 @@ void MP_WEAK __assert_func(const char *file, int line, const char *func, const c
panic("Assertion failed");
}
#endif
#define POLY (0xD5)
uint8_t rosc_random_u8(size_t cycles) {
static uint8_t r;
for (size_t i = 0; i < cycles; ++i) {
r = ((r << 1) | rosc_hw->randombit) ^ (r & 0x80 ? POLY : 0);
mp_hal_delay_us_fast(1);
}
return r;
}
uint32_t rosc_random_u32(void) {
uint32_t value = 0;
for (size_t i = 0; i < 4; ++i) {
value = value << 8 | rosc_random_u8(32);
}
return value;
}

View File

@@ -24,6 +24,8 @@
* THE SOFTWARE.
*/
#include <py/mpconfig.h>
#include <py/misc.h>
#include <string.h>
#ifdef MICROPY_SSL_MBEDTLS
@@ -33,12 +35,13 @@
#include "mbedtls/platform_time.h"
#include "pico/aon_timer.h"
extern uint8_t rosc_random_u8(size_t cycles);
#include "pico/rand.h"
int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) {
*olen = len;
for (size_t i = 0; i < len; i++) {
output[i] = rosc_random_u8(8);
for (size_t i = 0; i < len; i += 8) {
uint64_t rand64 = get_rand_64();
memcpy(output + i, &rand64, MIN(len - i, 8));
}
return 0;
}

View File

@@ -25,15 +25,15 @@
*/
#include "py/runtime.h"
uint8_t rosc_random_u8(size_t cycles);
#include "pico/rand.h"
static mp_obj_t mp_os_urandom(mp_obj_t num) {
mp_int_t n = mp_obj_get_int(num);
vstr_t vstr;
vstr_init_len(&vstr, n);
for (int i = 0; i < n; i++) {
vstr.buf[i] = rosc_random_u8(8);
for (int i = 0; i < n; i += 8) {
uint64_t rand64 = get_rand_64();
memcpy(vstr.buf + i, &rand64, MIN(n - i, 8));
}
return mp_obj_new_bytes_from_vstr(&vstr);
}

View File

@@ -158,7 +158,7 @@
#define MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME (1)
#define MICROPY_PY_TIME_TIME_TIME_NS (1)
#define MICROPY_PY_TIME_INCLUDEFILE "ports/rp2/modtime.c"
#define MICROPY_PY_RANDOM_SEED_INIT_FUNC (rosc_random_u32())
#define MICROPY_PY_RANDOM_SEED_INIT_FUNC (get_rand_32())
#define MICROPY_PY_MACHINE (1)
#define MICROPY_PY_MACHINE_INCLUDEFILE "ports/rp2/modmachine.c"
#define MICROPY_PY_MACHINE_RESET (1)
@@ -292,7 +292,7 @@ typedef intptr_t mp_off_t;
#define BINARY_INFO_ID_MP_FROZEN 0x4a99d719
#define MICROPY_FROZEN_LIST_ITEM(name, file) bi_decl(bi_string(BINARY_INFO_TAG_MICROPYTHON, BINARY_INFO_ID_MP_FROZEN, name))
extern uint32_t rosc_random_u32(void);
#include "pico/rand.h"
extern void lwip_lock_acquire(void);
extern void lwip_lock_release(void);