G.2 (v2.0.0): unified rng_get_bytes() entropy entry point; virtio-rng sole backend

The QEMU-verifiable slice of the real-hardware RNG driver (per FABRIC-3.md
§G.2). New include/starkernel/rng.h + src/starkernel/rng/rng.c provide the
single entropy entry point: rng_init() probes the backend set (v2.0.0:
virtio-rng only) and, on no backend, prints a loud boot-time warning while
rng_get_bytes() returns RNG_ERR_NO_BACKEND - never silently degrading to a
deterministic seed. The backend-selection switch in rng.c is the exact seam
v2.5.0's per-arch drivers (amd64 RDRAND, riscv64 Zkr, aarch64 peripheral) plug
into without touching the call path.

Consumers route through the unified layer instead of virtio-rng directly:
capsule_mint.c (identity seed + drive_uuid) and kernel_main.c phase 8
(rng_init()). virtio_rng.c stays as the sole backend. Built clean on
amd64/aarch64/riscv64. QEMU amd64 boot: POST 1012/0/0 + ok>, "rng: backend =
virtio-rng" + "entropy: ready", Zuse identity confirmed from thumbdrive -
mint/cert behavior unchanged.

FABRIC-3.md §G.2 v2.0.0 slice marked BUILT+VERIFIED.
This commit is contained in:
Robert Allan James
2026-08-29 09:57:17 -04:00
parent aee1ecaa8f
commit 09857b7228
8 changed files with 157 additions and 17 deletions
+4 -4
View File
@@ -16,7 +16,7 @@
#include "starkernel/user_identity_seed.h"
#include "starkernel/x509_ed25519.h"
#include "starkernel/ed25519.h"
#include "starkernel/virtio_rng.h"
#include "starkernel/rng.h"
#include "block_subsystem.h" /* compute_crc64() */
#include "blkio.h"
#include <string.h>
@@ -101,11 +101,11 @@ MintResult capsule_mint_identity(struct blkio_dev *dev, VM *issuer_vm,
/* issuer_vm==NULL is genesis mode (§F.21) -- no existing Zuse to
* require a cert from. */
if (issuer_vm && !issuer_vm->zuse_cert_installed) return MINT_ERR_NO_ZUSE_CERT;
if (!virtio_rng_ready()) return MINT_ERR_NO_ENTROPY;
if (!rng_ready()) return MINT_ERR_NO_ENTROPY;
/* Fresh identity keypair. */
uint8_t seed[32], pubkey[32];
if (virtio_rng_get_bytes(seed, sizeof(seed)) != 0) return MINT_ERR_NO_ENTROPY;
if (rng_get_bytes(seed, sizeof(seed)) != 0) return MINT_ERR_NO_ENTROPY;
ed25519_keygen(seed, pubkey);
if (out_pubkey) memcpy(out_pubkey, pubkey, 32);
if (out_seed) memcpy(out_seed, seed, 32);
@@ -114,7 +114,7 @@ MintResult capsule_mint_identity(struct blkio_dev *dev, VM *issuer_vm,
* the identity seed (§F.8 decision 3: "which physical drive," not
* "whose identity"). */
uint8_t drive_uuid[16];
if (virtio_rng_get_bytes(drive_uuid, sizeof(drive_uuid)) != 0)
if (rng_get_bytes(drive_uuid, sizeof(drive_uuid)) != 0)
return MINT_ERR_NO_ENTROPY;
uint32_t cert_devblock = 0;
+12 -12
View File
@@ -65,7 +65,7 @@ EFI_RUNTIME_SERVICES *g_sk_runtime_services = NULL;
#include "starkernel/repl.h"
#include "starkernel/pci.h"
#include "starkernel/virtio_blk.h"
#include "starkernel/virtio_rng.h"
#include "starkernel/rng.h"
#include "starkernel/virtio_input.h"
#include "starkernel/xhci_driver.h"
#include "block_subsystem.h"
@@ -590,20 +590,20 @@ static void kernel_main_deep(BootInfo *boot_info) {
}
}
/* Phase 8: virtio-rng entropy source. Real per-arch RNG doesn't cover
* all three architectures (amd64 RDRAND, riscv64 Zkr, but aarch64 has
* neither in QEMU's CPU models -- see vm_uuid.h's identical finding),
* so signing/keygen entropy comes from this paravirtualized device
* instead. Unconditional call site, same graceful-noop precedent as
* virtio_blk_find_artemis() above -- boot proceeds either way, the
* device is only required once something actually calls
* virtio_rng_get_bytes(). */
/* Phase 8: entropy. Real per-arch RNG doesn't cover all three
* architectures (amd64 RDRAND, riscv64 Zkr, but aarch64 has neither in
* QEMU's CPU models -- see vm_uuid.h's identical finding), so signing/
* keygen entropy comes from the unified rng_get_bytes() layer, whose
* v2.0.0 backend is the paravirtualized virtio-rng device. Unconditional
* call site, same graceful-noop precedent as virtio_blk_find_artemis()
* above -- boot proceeds either way, the device is only required once
* something actually calls rng_get_bytes(). */
{
int rrc = virtio_rng_init();
int rrc = rng_init();
if (rrc == 0) {
console_println("virtio-rng: ready");
console_println("entropy: ready");
} else {
console_println("virtio-rng: not available (continuing without)");
console_println("entropy: not available (continuing without)");
}
}
+60
View File
@@ -0,0 +1,60 @@
/*
StarKernel — Unified entropy layer (rng_get_bytes)
Single entropy entry point for the kernel; see include/starkernel/rng.h for
the contract and the probe-and-refuse-loudly discipline this implements.
v2.0.0: virtio-rng is the sole active backend (QEMU-only, uniform across all
three arches). The backend-selection switch in rng_get_bytes() is the exact
seam where the v2.5.0 real per-arch drivers (amd64 RDRAND, riscv64 Zkr,
aarch64 peripheral RNG) plug in without touching the call path.
*/
#ifndef __STARKERNEL__
#error "rng.c is kernel-only"
#endif
#include "starkernel/rng.h"
#include "starkernel/virtio_rng.h"
#include "starkernel/console.h"
/* Number of entropy backends known to this build. Each maps to one case in
* rng_init() and rng_get_bytes(). v2.0.0 has exactly one: virtio-rng. */
enum {
RNG_BACKEND_NONE = 0,
RNG_BACKEND_VIRTIO, /* virtio-rng (QEMU, all three arches) */
};
static int g_rng_backend = RNG_BACKEND_NONE;
int rng_init(void) {
/* Probe backends in priority order; first success wins. virtio-rng is
* the sole backend at v2.0.0; v2.5.0 adds real per-arch drivers here. */
if (virtio_rng_init() == 0) {
g_rng_backend = RNG_BACKEND_VIRTIO;
console_println("rng: backend = virtio-rng");
return 0;
}
/* Refuse loudly: never fall through to a deterministic seed. */
g_rng_backend = RNG_BACKEND_NONE;
console_println(
"rng: WARNING — no entropy backend available; rng_get_bytes() "
"will refuse (no deterministic seed fallback)");
return -1;
}
int rng_ready(void) {
return g_rng_backend != RNG_BACKEND_NONE;
}
int rng_get_bytes(uint8_t *buf, size_t n) {
switch (g_rng_backend) {
case RNG_BACKEND_VIRTIO:
return virtio_rng_get_bytes(buf, n);
default:
/* v2.5.0 real per-arch cases land here. No backend: refuse loudly,
* never return a deterministic throwaway. */
return RNG_ERR_NO_BACKEND;
}
}