mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
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) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
This commit is contained in:
parent
aa3157e234
commit
52e84e0c0a
6 changed files with 222 additions and 0 deletions
|
|
@ -26,6 +26,7 @@ ignore-words-list =
|
|||
BU,
|
||||
DAA,
|
||||
dout,
|
||||
ehr,
|
||||
emac,
|
||||
eeeprom,
|
||||
extint,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
================
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
185
arch/arm/src/rp23xx/rp23xx_rng.c
Normal file
185
arch/arm/src/rp23xx/rp23xx_rng.c
Normal file
|
|
@ -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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue