From 158cbd6065e587154e40bfd1e9c9946076668b75 Mon Sep 17 00:00:00 2001 From: Michel Le Bihan Date: Wed, 18 Feb 2026 15:23:10 +0100 Subject: [PATCH] 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 --- ports/rp2/CMakeLists.txt | 1 + ports/rp2/lwip_inc/lwipopts.h | 4 ++-- ports/rp2/main.c | 20 -------------------- ports/rp2/mbedtls/mbedtls_port.c | 9 ++++++--- ports/rp2/modos.c | 8 ++++---- ports/rp2/mpconfigport.h | 4 ++-- 6 files changed, 15 insertions(+), 31 deletions(-) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index f10cf1a16d..8b37bce681 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -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 diff --git a/ports/rp2/lwip_inc/lwipopts.h b/ports/rp2/lwip_inc/lwipopts.h index da45a5735b..7900238d27 100644 --- a/ports/rp2/lwip_inc/lwipopts.h +++ b/ports/rp2/lwip_inc/lwipopts.h @@ -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 diff --git a/ports/rp2/main.c b/ports/rp2/main.c index 50946b0a5c..c67f404f61 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -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; -} diff --git a/ports/rp2/mbedtls/mbedtls_port.c b/ports/rp2/mbedtls/mbedtls_port.c index 521d815d2b..3d8ebcd35a 100644 --- a/ports/rp2/mbedtls/mbedtls_port.c +++ b/ports/rp2/mbedtls/mbedtls_port.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ #include +#include +#include #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; } diff --git a/ports/rp2/modos.c b/ports/rp2/modos.c index 0008854a16..d4ab2f0819 100644 --- a/ports/rp2/modos.c +++ b/ports/rp2/modos.c @@ -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); } diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index e809c6d5dc..fb2d599b91 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -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);