Repository navigation
Bare metal: a key is made only from a hardware generator - #1051
Conversation
… are read under a lock Three faults in the bare-metal random sources, found reading them now that the boards are real (#658 left the Pi's open question for a board). Fail closed. A board with no working generator -- the Pi 4's RNG200 not answering, the PolarFire's nonce service refusing, a QEMU virt without virtio-rng -- handed libsec's key generators, #c/notquiterandom and #c/random a counter stirred with the time, after one line on the console. The PolarFire did the same if its service stopped after boot. On a board that means a driver or map at fault; on a Pi 5, which no emulator models, it could mean nothing else. hwrandom now never makes bytes up: it returns -1 when the machine has no generator. genrandom, prng and prngtry, which all six boards copied, move to os/port/random.c, wait for real bytes and say why every five seconds; prngtry answers -1 at once, as libsec.h says it does. The machine still boots and talks to the network: devcons.c's seedrand, behind nrand's port and sequence numbers, no longer reads the pool. The word "insecurerandom" on the command line gives an emulator the labelled counter; the harness passes it to raspi4b and qemu-icicle.dts says it. Locks. The Pi 3 and Pi 4 drivers tested for a word and read it with no lock, on four cores with preemption: two readers could both see one word waiting and both read it, and what an empty FIFO reads as is not documented. The test and the read are now one step under an ilock. The RNG200's health test. It reports a failed NIST test in its interrupt status; nothing read it. As Linux's iproc-rng200 does, a failure now resets the block before another word is taken. The driver moves to os/bcm/rng200.c for the Pi 4 and the Pi 5, at the board's RNG200REGS; the BCM2837 leaves it out. Tests: a virt boot with no virtio-rng reaches its shell, refuses key material and #c/random alike and says why; with insecurerandom both answer and the counter is labelled. raspi4b and the Icicle Kit check the label. Refs: INFR-404 INFR-342 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0195u6z4TJx1xi2fTM3X596h
…rerandom The release card's Pi 4 boot under QEMU failed on #1051 (bcm2711 job): QEMU's raspi4b models no RNG200, so the machine has no entropy source, and the kernel now makes no key on such a machine. The first-boot login waited for one, and so did DNS, whose query ids come from /dev/random -- the profile names the LLM server, so the serial shell never answered. A board has the generator, so the card is right as it is: its cmdline.txt does not say insecurerandom, and must not. The emulator lacks it, so the word goes on QEMU's command line, as baremetal_test.sh's raspi4b boots already do. raspi3b models the BCM2835's generator and is unchanged. Reproduced locally (QEMU 9.2.4, the repo's patches): rpi4b 12/3 before, 15/0 after; rpi3bplus 15/0. The changelog and os/port/random.c said a machine with no generator "still uses the network": the kernel's does, and DNS waits. Now they say so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0195u6z4TJx1xi2fTM3X596h
|
iOS Build & Simulator Test is red here, and it is not this PR's.
The earlier red, on the bcm2711 job, was this PR's: the release's Pi 4 card was booted under a QEMU with no RNG200, and d580729 fixes it. Generated by Claude Code |
#1037, #1038, #1039 and #1040 merged around the registry (#1036), so master's devletters_test failed: #K prof, #X vm, #x bench, #z wmsz and #h tfa were in use and still "reserved" here. Their rows are in use; #P is arch only; #b, #w and #F are free here, at their precedents' meanings, #w and #F now reserved for a watchdog and flash. The planned moves are the moves made. tools/devletters.py --check: PASS, 36 letters in use across 20 builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T5tjh7MFpJjYJnvTT33utv (cherry picked from commit d147d1b)
|
Linux AMD64 Host Tests (1) is red with two failures, and neither is this PR's. Master's head, 62ce2a6, fails the same shard with the same two tests (job).
Generated by Claude Code |
|
macOS ARM64 Build & Test went red on d580729, but none of its build or test steps failed. The one failed step is "Upload macOS build artifacts" (step 20): The wallet persistence lines in that log are marked non-fatal in CI, and master's passing run of this job prints the same ones. That head has been superseded by 87c4d6d, which runs the job again. I can't re-run jobs from this session; the integration gets a 403. Generated by Claude Code |
|
macOS ARM64 Build & Test and iOS Build & Simulator Test never ran on 87c4d6d. GitHub cancelled both after 15 minutes: "The job was not acquired by Runner of type hosted even after multiple attempts," with a macOS arm64 capacity warning. Neither has a result to judge. They need a re-run. I can't trigger one from this session, because the integration gets a 403. The rest of CI on this head: every bare-metal job passed (bcm2837, bcm2711 with the card boot, virt, and both RISC-V jobs). Generated by Claude Code |
|
Linux AMD64 SDL3 GUI Build & Test timed out on 87c4d6d, and the base is red in the same step.
No fix exists that I can port. I can't re-run the job from this session. Generated by Claude Code |
The Pi 5 takes the shared generator, os/bcm/rng200.c, by naming where it is, and loses its own copy of what os/port/random.c now owns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0195u6z8JjsAy9yrE5TqKxzx
docs/DEVICE-LETTERS.md: master's, from #1052, which makes the same five-row update this branch made to get devletters_test passing (prof #K, vm #X, bench #x, wmsz #z, tfa #h). tools/devletters.py --check passes. The merge also brings in #1052 and #1053, which fix the master failures this PR showed in Host Tests (1) and the SDL3 GUI job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0195u6z6W3TbdAx7jg6RqhYy
The Pi 5 half of #1051 (keys from a hardware generator alone), which integ/pi5-all took in its merge of it (462c72b) and the soaked build ran: the board's own random.c goes, the RNG200's registers are named for ../bcm/rng200.c, and the README says so. Master has #1051 but not this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0195u6z8JjsAy9yrE5TqKxzx
Summary
On bare metal, a key is now made only from a hardware generator. A board whose generator is missing or not working used to hand libsec's key generators,
#c/notquiterandomand#c/randoma predictable counter after one console line. It now fails closed. The Pi's generators are also read under a lock, and the RNG200's own health-test flags are now heeded.This follows up the open question left in #658, now that the Pi boards are real. Refs: INFR-404, INFR-342 (F2/F4).
Changes
os/port/random.cnow ownsgenrandom,prngandprngtry, which all six boards had copied.genrandomwaits for real bytes and says why every five seconds.prngtryanswers -1 at once with no generator, aslibsec.hdocuments.hwrandomcontract: bytes (>0), dry (0), or no generator (-1). It never makes bytes up.insecurerandomon the boot command line gives an emulator a labelled counter. The harness passes it to QEMU'sraspi4b, andos/mpfs/qemu-icicle.dtssets it. A board'scmdline.txtmust not.os/port/devcons.c: the seed behindnrand, used for port and TCP sequence numbers, no longer reads the pool, so networking never waits.os/bcm/rng200.c(new) is shared by the Pi 4 and, once its port merges, the Pi 5. It sits at the board'sRNG200REGS, reads a word under a lock, and resets the block when the NIST-fail or lockout flag is set, as Linux'siproc-rng200does.os/bcm2711/random.cis removed. The BCM2837 leaves the file out.os/bcm2837/random.c: the check for a word and its read are one step under a lock, and the spin counter is per call.os/mpfs/random.c: -1 when the nonce service refused at boot. If the service stops later, keys wait instead of switching silently to the counter.os/virt/random.c,os/riscvvirt/random.c: -1 with no source. Calls before the probe read as dry.docs/TLS-ENTROPY.md(whose opening table was stale),docs/BAREMETAL-BOARD-INTERFACE.md, and the board READMEs.Testing
Run locally under QEMU: 9.2.4 with the repo's patches for AArch64, 8.2 for RISC-V.
tests/host/baremetal_test.sh: 527 passed, 1 failed, 1 skipped.fsck.fatimage check.tests/host/baremetal_riscv64_test.sh: 70 passed, 0 failed, 0 skipped./dev/notquiterandomand/dev/randomwait and say why; no counter appears; nothing panics. Withinsecurerandom, both answer and the counter is labelled.raspi4breaches the Lucifer desktop withinsecurerandomand checks the label. So does the Icicle Kit.feat/pi5-portwith this merged, plus a small patch) builds with the shared driver.Not verified:
insecurerandom. Only virt checks the refusal.Checklist
.disbuild artifacts committed fromappl/ortests/Follow-ups (not in this PR)
os/bcm2712/random.c, addRNG200REGS) belongs onfeat/pi5-portonce it takes this.🤖 Generated with Claude Code
https://claude.ai/code/session_0195u6z4TJx1xi2fTM3X596h