This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 52e84e0c0a4 arch/arm/rp23xx: Add hardware TRNG driver for /dev/random.
52e84e0c0a4 is described below
commit 52e84e0c0a4be5dfad8c16577bea4f30f27aeaa2
Author: Marco Casaroli <[email protected]>
AuthorDate: Fri Jul 24 22:06:29 2026 +0200
arch/arm/rp23xx: Add hardware TRNG driver for /dev/random.
Add a driver for the rp2350 hardware true random number generator.
Enabling CONFIG_RP23XX_RNG selects ARCH_HAVE_RNG and builds the driver,
which registers /dev/random (and /dev/urandom when CONFIG_DEV_URANDOM
selects the architecture source, DEV_URANDOM_ARCH). Each read enables
the entropy source, waits for a valid 192-bit entropy holding register
(EHR) sample, reads the six 32-bit EHR words, and repeats until the
request is satisfied.
Document the TRNG on the rp23xx platform page.
Assisted-by: Claude Opus 4.8 (1M context) <[email protected]>
Signed-off-by: Marco Casaroli <[email protected]>
---
.codespellrc | 1 +
Documentation/platforms/arm/rp23xx/index.rst | 19 +++
arch/arm/src/rp23xx/CMakeLists.txt | 4 +
arch/arm/src/rp23xx/Kconfig | 9 ++
arch/arm/src/rp23xx/Make.defs | 4 +
arch/arm/src/rp23xx/rp23xx_rng.c | 185 +++++++++++++++++++++++++++
6 files changed, 222 insertions(+)
diff --git a/.codespellrc b/.codespellrc
index d22ff556a14..14770824d32 100644
--- a/.codespellrc
+++ b/.codespellrc
@@ -26,6 +26,7 @@ ignore-words-list =
BU,
DAA,
dout,
+ ehr,
emac,
eeeprom,
extint,
diff --git a/Documentation/platforms/arm/rp23xx/index.rst
b/Documentation/platforms/arm/rp23xx/index.rst
index 779c8f4e1be..d91ad4cade5 100644
--- a/Documentation/platforms/arm/rp23xx/index.rst
+++ b/Documentation/platforms/arm/rp23xx/index.rst
@@ -41,6 +41,7 @@ Flash ROM Boot Working Does not require boot2 from
pico-sdk
If picotool is available a nuttx.uf2 file will
be created
SRAM Boot Working Requires external SWD debugger
PSRAM Working Three modes of heap allocation described below
+TRNG Working Hardware RNG at /dev/random and /dev/urandom
============== ============ =====
Installation
@@ -203,6 +204,24 @@ GPIO 0 and 1 pins must be connected to the device such as
USB-serial converter.
The `usbnsh` configuration provides the console access by USB CDC/ACM serial
device. The console is available by using a terminal software on the USB host.
+TRNG
+====
+
+The rp2350 has a hardware true random number generator (TRNG). Enabling
+``RP23XX_RNG`` builds the driver and selects ``ARCH_HAVE_RNG``, which in turn
+makes ``DEV_RANDOM`` available.
+
+With ``DEV_RANDOM`` enabled the driver registers ``/dev/random``. Enabling
+``DEV_URANDOM`` additionally registers ``/dev/urandom``; when a hardware RNG is
+present the architecture source (``DEV_URANDOM_ARCH``) is selected by default,
+so ``/dev/urandom`` is served from the same TRNG rather than a software PRNG.
+
+Each read collects entropy from the TRNG's 192-bit entropy holding register
+(EHR): the source is enabled, the driver waits for ``TRNG_VALID``, reads the
+six 32-bit EHR words, and repeats until the request is satisfied. For
example::
+
+ nsh> dd if=/dev/random of=/dev/console bs=16 count=1
+
Supported Boards
================
diff --git a/arch/arm/src/rp23xx/CMakeLists.txt
b/arch/arm/src/rp23xx/CMakeLists.txt
index b67f08039aa..77449ea491d 100644
--- a/arch/arm/src/rp23xx/CMakeLists.txt
+++ b/arch/arm/src/rp23xx/CMakeLists.txt
@@ -60,6 +60,10 @@ if(CONFIG_RP23XX_I2C)
list(APPEND SRCS rp23xx_i2c.c)
endif()
+if(CONFIG_RP23XX_RNG)
+ list(APPEND SRCS rp23xx_rng.c)
+endif()
+
if(CONFIG_RP23XX_I2C_SLAVE)
list(APPEND SRCS rp23xx_i2c_slave.c)
endif()
diff --git a/arch/arm/src/rp23xx/Kconfig b/arch/arm/src/rp23xx/Kconfig
index cbeba7bbaa7..05907356d4c 100644
--- a/arch/arm/src/rp23xx/Kconfig
+++ b/arch/arm/src/rp23xx/Kconfig
@@ -740,6 +740,15 @@ endif # SPISD Configuration
# ADC Configuration
#####################################################################
+config RP23XX_RNG
+ bool "Enable hardware TRNG (/dev/random)"
+ default n
+ select ARCH_HAVE_RNG
+ ---help---
+ Enable the RP2350 hardware true random number generator.
Provides
+ /dev/random (and /dev/urandom when CONFIG_DEV_URANDOM selects
the
+ architecture source) via the TRNG entropy register (EHR).
+
config RP23XX_ADC
bool "Enable ADC Support"
default n
diff --git a/arch/arm/src/rp23xx/Make.defs b/arch/arm/src/rp23xx/Make.defs
index 00421248049..36100cd47f7 100644
--- a/arch/arm/src/rp23xx/Make.defs
+++ b/arch/arm/src/rp23xx/Make.defs
@@ -64,6 +64,10 @@ ifeq ($(CONFIG_RP23XX_I2C),y)
CHIP_CSRCS += rp23xx_i2c.c
endif
+ifeq ($(CONFIG_RP23XX_RNG),y)
+CHIP_CSRCS += rp23xx_rng.c
+endif
+
ifeq ($(CONFIG_RP23XX_I2C_SLAVE),y)
CHIP_CSRCS += rp23xx_i2c_slave.c
endif
diff --git a/arch/arm/src/rp23xx/rp23xx_rng.c b/arch/arm/src/rp23xx/rp23xx_rng.c
new file mode 100644
index 00000000000..e2c7bca54f0
--- /dev/null
+++ b/arch/arm/src/rp23xx/rp23xx_rng.c
@@ -0,0 +1,185 @@
+/****************************************************************************
+ * arch/arm/src/rp23xx/rp23xx_rng.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/mutex.h>
+#include <nuttx/drivers/drivers.h>
+
+#include "arm_internal.h"
+#include "hardware/rp23xx_trng.h"
+
+#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* The TRNG delivers entropy 192 bits (six 32-bit EHR words) at a time. */
+
+#define RP23XX_TRNG_EHR_WORDS 6
+#define RP23XX_TRNG_EHR_BYTES (RP23XX_TRNG_EHR_WORDS * sizeof(uint32_t))
+
+/* TRNG_VALID.EHR_VALID: the EHR holds a fresh 192-bit sample. */
+
+#define RP23XX_TRNG_EHR_VALID (1 << 0)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t rp23xx_rng_read(struct file *filep, char *buffer,
+ size_t buflen);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static mutex_t g_rng_lock = NXMUTEX_INITIALIZER;
+
+static const struct file_operations g_rngops =
+{
+ NULL, /* open */
+ NULL, /* close */
+ rp23xx_rng_read, /* read */
+ NULL, /* write */
+ NULL, /* seek */
+ NULL, /* ioctl */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp23xx_rng_read
+ *
+ * Description:
+ * Fill 'buffer' with 'buflen' bytes of hardware entropy. Enables the ring
+ * -oscillator source, then repeatedly waits for a valid 192-bit EHR and
+ * copies it out until the request is satisfied.
+ *
+ ****************************************************************************/
+
+static ssize_t rp23xx_rng_read(struct file *filep, char *buffer,
+ size_t buflen)
+{
+ size_t nread = 0;
+ int ret;
+
+ ret = nxmutex_lock(&g_rng_lock);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ /* Enable the entropy source. */
+
+ putreg32(1, RP23XX_TRNG_RND_SOURCE_ENABLE);
+
+ while (nread < buflen)
+ {
+ uint32_t ehr[RP23XX_TRNG_EHR_WORDS];
+ size_t chunk;
+ int i;
+
+ /* Wait for the next 192-bit sample to become valid. */
+
+ while ((getreg32(RP23XX_TRNG_TRNG_VALID) & RP23XX_TRNG_EHR_VALID) == 0)
+ {
+ }
+
+ for (i = 0; i < RP23XX_TRNG_EHR_WORDS; i++)
+ {
+ ehr[i] = getreg32(RP23XX_TRNG_EHR_DATA(i));
+ }
+
+ /* Acknowledge the sample so the engine collects the next one. */
+
+ putreg32(0xffffffff, RP23XX_TRNG_RNG_ICR);
+
+ chunk = buflen - nread;
+ if (chunk > RP23XX_TRNG_EHR_BYTES)
+ {
+ chunk = RP23XX_TRNG_EHR_BYTES;
+ }
+
+ memcpy(buffer + nread, ehr, chunk);
+ nread += chunk;
+ }
+
+ /* Leave the source disabled to save power. */
+
+ putreg32(0, RP23XX_TRNG_RND_SOURCE_ENABLE);
+
+ nxmutex_unlock(&g_rng_lock);
+ return (ssize_t)nread;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: devrandom_register
+ *
+ * Description:
+ * Register /dev/random, backed by the RP2350 hardware TRNG. Called
+ * automatically from drivers_initialize() when CONFIG_DEV_RANDOM is set.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_RANDOM
+void devrandom_register(void)
+{
+ register_driver("/dev/random", &g_rngops, 0444, NULL);
+}
+#endif
+
+/****************************************************************************
+ * Name: devurandom_register
+ *
+ * Description:
+ * Register /dev/urandom, backed by the same hardware TRNG. Called from
+ * drivers_initialize() when CONFIG_DEV_URANDOM selects the arch source.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_URANDOM_ARCH
+void devurandom_register(void)
+{
+ register_driver("/dev/urandom", &g_rngops, 0444, NULL);
+}
+#endif
+
+#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */