Skip to content

arch/arm/imxrt: add a CAAM-backed /dev/random driver - #20205

Merged
acassis merged 1 commit into
apache:masterfrom
royzah:imxrt-caam-rng
Sep 22, 2026
Merged

acassis merged 1 commit into
apache:masterfrom
royzah:imxrt-caam-rng

Conversation

@royzah

@royzah royzah commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The i.MX RT117x has a hardware random number generator inside CAAM and nothing in NuttX registers it, so up_randompool_initialize() is never seeded from hardware. There is no CAAM, TRNG or RNG driver anywhere in arch/arm/src/imxrt, and the RT117x headers describe the block only as an address-map comment.

File What it does
imxrt_caam.c job ring zero, and RNG state handle instantiation when the boot ROM has not done it
imxrt_rng.c /dev/random and /dev/urandom on top of it
hardware/rt117x/imxrt117x_caam.h job ring and RNG4 registers
imxrt_periphclks.h the CAAM clock gate, which had no helper

Instantiation retries with a longer entropy sample until the self test passes, which is how NXP's own code finds a value that holds across voltage and temperature.

imxrt_rng.c is the sibling of the i.MX9 driver in #20191: same health checks, same FIPS 140-2 continuous test, and the same refusal to return a short read and call it entropy.

Scoped to RT117x, the family that carries CAAM.

Impact

New driver, default n. Nothing changes for a board that does not select IMXRT_RNG.

Provenance of the register definitions

The i.MX RT1170 Reference Manual Rev. 5 describes CAAM in one page of features (section 7.7) and carries no register detail, so the header was built from NXP's own drivers for this block and cross-checked three ways.

Fact Source
General block 0x4044_0000, job ring 0 0x4045_0000 RT1170 RM Rev. 5, system memory map
Clock gate LPCG 40 RT1170 RM Rev. 5, clk_enable_caam
RNG4 offsets 0x600/0x610/0x618/0x61c/0x6c0 and their bits agree across NXP u-boot, NXP Linux and OP-TEE
Job ring offsets, and the high-word-first base address order for a 32-bit CAAM agree across NXP u-boot and OP-TEE

@github-actions github-actions Bot added Arch: arm Issues related to ARM (32-bit) architecture Size: L The size of the change in this PR is large labels Sep 20, 2026
@github-actions

github-actions Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@acassis

acassis commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

@royzah please signed your PR and also add Assisted-by: AI Vendor/Model used

@royzah
royzah force-pushed the imxrt-caam-rng branch 2 times, most recently from 4f27ea0 to b332fc0 Compare September 21, 2026 16:02
The part has a hardware random number generator and nothing registers
it, so up_randompool_initialize() is never seeded from hardware. There
is no CAAM, TRNG or RNG driver anywhere in arch/arm/src/imxrt, and the
RT117x headers describe the block only as an address-map comment.

imxrt_caam.c brings up job ring zero and instantiates the RNG state
handle when the boot ROM has not, retrying with a longer entropy sample
until the self test passes. imxrt_rng.c registers /dev/random and
/dev/urandom on top, and is the i.MX9 driver's sibling: same health
checks, same FIPS 140-2 continuous test, same refusal to return a short
read and call it entropy.

The instantiation descriptor posts no job ring completion, so the state
handle is what reports it, and the ring is taken back to a known state
to latch it. Job ring zero is started and the cache and watchdog bits
set first: RDSTA and JRSTART both read zero out of reset on this part.

Scoped to RT117x, which is the family that carries CAAM.

Built for imxrt1170-evk:nsh with the driver on, and for imxrt1060-evk:nsh
to confirm the shared clock-gate header still builds without it.

Run on an FMU-v6X-RT (i.MX RT1176): /dev/random and /dev/urandom both
return, the first read after a cold boot included, and five consecutive
reads are distinct.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
@royzah
royzah marked this pull request as ready for review September 22, 2026 03:28
@royzah

royzah commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Tried this on real hardware and it turned up a bug the build could never catch.

Board is an FMU-v6X-RT, i.MX RT1176, running plain NuttX nsh.

The instantiate descriptor just never answers on the job ring. The driver took that as a failure, so the first read always came back -ETIMEDOUT even though the RNG was actually fine. Generate jobs do answer, so every read after the first one worked and hid the whole thing.

Straight out of reset:

rdsta   = 0x00000000    RNG not instantiated
jrstart = 0x00000000    no job ring started

Before:

nsh> hexdump /dev/random count=32
nsh: hexdump: read failed: 110
nsh> cat /dev/ttyS1
imxrt_caam_run: ERROR: job ring did not answer      x25, one per entropy delay
imxrt_caam_rng_init: ERROR: RNG would not instantiate

So now it trusts the state handle instead of the ring, and resets the ring to latch it. Also starts job ring zero and sets the cache and watchdog bits first, since the boot ROM does neither.

After, first read on a cold boot:

nsh> hexdump /dev/random count=32
/dev/random at 00000000:
0000: 8f ae 90 3a a2 8a b8 5b ba d6 1c b2 2e 7e 87 71
0010: 48 45 f6 e0 02 9b c0 fe 3b 38 d9 14 be 3e 61 ed

Five reads in a row, all different, urandom the same. Rebased on master too.

Built imxrt1170-evk:nsh with the driver on, and imxrt1060-evk:nsh without it to check the shared clock-gate header. nxstyle clean.

@acassis @xiaoxiang781216 review welcome

royzah added a commit to tiiuae/px4-firmware that referenced this pull request Sep 22, 2026
The board had no entropy configuration at all: no CONFIG_DEV_RANDOM, no
CONFIG_DEV_URANDOM, nothing arch-backed. up_randompool_initialize() was
never seeded from hardware, so every session key on this board came from
a pool that is identical at every boot.

The RT1176 carries a CAAM. Pin NuttX to a base with the job ring and RNG
driver backported from apache/nuttx#20205 and turn it on here.
IMXRT_RNG selects IMXRT_CAAM and ARCH_HAVE_RNG, and the driver is the
sole provider of devrandom_register(), so CRYPTO_RANDOM_POOL stays off.

CAAM bring-up is lazy, on the first read, so this cannot affect boot.
royzah added a commit to tiiuae/px4-firmware that referenced this pull request Sep 22, 2026
The board had no entropy configuration at all: no CONFIG_DEV_RANDOM, no
CONFIG_DEV_URANDOM, nothing arch-backed. up_randompool_initialize() was
never seeded from hardware, so every session key on this board came from
a pool that is identical at every boot.

The RT1176 carries a CAAM. Pin NuttX to a base with the job ring and RNG
driver backported from apache/nuttx#20205 and turn it on here.
IMXRT_RNG selects IMXRT_CAAM and ARCH_HAVE_RNG, and the driver is the
sole provider of devrandom_register(), so CRYPTO_RANDOM_POOL stays off.

CAAM bring-up is lazy, on the first read, so this cannot affect boot.
@acassis
acassis merged commit 44a3873 into apache:master Sep 22, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Size: L The size of the change in this PR is large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants