Phase 8 C (5/n): Zuse's cert wired to the fence -- first-boot mint works

Replaces the crashed NVRAM approach entirely. New
include/starkernel/zuse_cert_devblock.h: a standalone on-disk record
(magic + version + 32-byte seed + 32-byte pubkey + a real CRC-64/ISO
from day one, same discipline homeblocks_sig_t established) occupying
devblock_from_top=0 of the fence. Its own header, not inlined at the
boot call site, since the still-open MINT word will be a second
consumer of this exact format.

kernel_main.c's mint-or-load logic now reads the fence, installs an
existing valid cert, or mints fresh via virtio_rng+ed25519_keygen and
writes it. Runs right after virtio_rng_init(), before
capsule_birth_mama() -- unlike the crashed NVRAM attempt, raw block I/O
against Artemis's already-proven device has no boot-timing risk, so the
earlier "re-invoke ACL-ZUSE-BOOT after Mama birth" workaround is gone;
ACL.4th's self-activating ACL-ZUSE-BOOT sees a correct cert on its one
ordinary pass.

Verified independently across every real scenario, never trusting the
kernel's own report: fresh mint decodes correctly on disk with a CRC
confirmed by a from-scratch Python re-implementation of the algorithm;
a reboot without reformatting loads back byte-for-byte identical
seed/pubkey (genuinely "mint once, ever"); a pre-fence volume refuses
cleanly (no crash, no silent data loss, honest "not persistent"
reporting); the real, untouched disk/artemis.img exercises the same
graceful-refusal path identically on all three architectures.

Phase 8's core arc is now functionally complete: real entropy -> real
signing -> real anti-file block-native persistence -> a first-boot mint
that survives reboots. Still open: the ongoing MINT word for minting
additional regular users. Documented in FABRIC-3.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U14ET9CWAtbQMbYqomKgXd
This commit is contained in:
Robert Allan James
2026-08-26 20:40:05 -04:00
co-authored by Claude Sonnet 5
parent 6e9c1d3bc2
commit a8692681a8
10 changed files with 54388 additions and 1 deletions
+44
View File
@@ -608,6 +608,50 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
these new accessors (the zone exists and works; nothing writes Zuse's cert into it yet), and
the `MINT` word itself.
**Step 3 (Zuse's cert wired to the fence), done 2026-08-26 -- first-boot mint-then-load is
real, end to end.** New `include/starkernel/zuse_cert_devblock.h`: a small, standalone
on-disk record format (`zuse_cert_devblock_t` -- magic + version + 32-byte seed + 32-byte
pubkey + a real CRC-64/ISO from day one, same "real from day one" discipline
`homeblocks_sig_t` already established, since this gates a real security check) occupying
devblock_from_top=0 of the fence. Deliberately its own header, not inlined at the boot-time
call site: the still-open `MINT` word will be a second consumer of this exact format later.
`kernel_main.c`'s mint-or-load logic moved from the crashed NVRAM approach to this: read
devblock 0 of the fence, and if magic/version/CRC all check out, install the existing
cert; otherwise, if `virtio_rng` is ready, mint a fresh one (Phase A+B) and write it. Runs
right after `virtio_rng_init()`, well before `capsule_birth_mama()` -- unlike the crashed
NVRAM attempt, raw block I/O against Artemis's already-proven virtio-blk device has no
boot-timing risk at all, so the earlier "re-invoke `ACL-ZUSE-BOOT` after Mama birth"
workaround is no longer needed; `ACL.4th`/`zuse.4th`'s self-activating `ACL-ZUSE-BOOT` sees
a correctly-populated cert on its one, ordinary first pass.
**Verified live, independently, across every real scenario, never trusting the kernel's own
report:**
- **Fresh mint** (blank `disk/artemis-metafence-fresh.img`): boot logs `Zuse: minted, fuse
blown`; the on-disk record at the exact expected physical offset independently decodes to
magic bytes `b'ZUSE'`, version 1, a real 32-byte seed and pubkey, and a CRC that an
independent from-scratch Python re-implementation of the exact CRC-64/ISO algorithm
(table generation included, not just the check) confirms byte-for-byte.
- **Reload** (reboot the same now-minted image, no reformat): boot logs `Zuse: cert loaded
from block fence`; the on-disk seed and pubkey are byte-for-byte identical to the first
boot's -- genuinely "mint once, ever," not a silent re-mint.
- **Graceful refusal on a pre-fence volume** (`disk/artemis-metafence-test.img`,
`meta_fence_blocks=0`): `blk_meta_zone_read`/`write` both correctly refuse (no space to
read or write), so the kernel mints a cert for RAM/this-boot-only use and honestly reports
`Zuse: minted but fence write FAILED (not persistent)` -- no crash, no silent data loss,
no corruption of a device with no fence at all.
- **Real disk regression check:** the same graceful-refusal path exercised identically
against the real, untouched `disk/artemis.img` (which has no fence yet either) on all
three architectures -- clean boot, conservation intact, no panics, `disk/artemis.img`
itself reverted afterward (no committed churn).
**Phase 8's core arc is now functionally complete:** real entropy (Phase A) → real signing
(Phase B) → real, anti-file, block-native persistence (Phase C) → a working first-boot mint
that survives reboots. **Still open:** the ongoing `S" name" MINT` word for an authenticated
Zuse session to mint additional regular users (needs `zuse_cert_devblock_t`-format certs
signed by Zuse's own key, not just installed) -- the real remaining piece of the original
vision.
### From FABRIC-2.md §X, Milestone 5 — Console/VM key-match binding
- [ ] Settle the still-open question: reuse `ACL-PIN`/`acl_allow` directly, or build a
+1 -1
View File
@@ -1,5 +1,5 @@
# Capsule Block Manifest — Auto-generated
<!-- Generated by mkcapsule --manifest 2026-08-26T23:37:35Z -->
<!-- Generated by mkcapsule --manifest 2026-08-27T00:36:05Z -->
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
<!-- Hand-written justifications and immutability notes live -->
<!-- in MANIFEST.md alongside this auto-generated index. -->
+46
View File
@@ -0,0 +1,46 @@
/*
* zuse_cert_devblock.h -- on-disk record format for Zuse's cert, stored
* in devblock_from_top=0 of the top-of-device system-metadata fence
* (block_subsystem.h's blk_meta_zone_read()/write(), Phase 8, FABRIC-3.md
* §C). Raw, unpacked 4 KiB devblock -- same convention as the volume
* header itself (magic + version + fields + pad-to-4096, real CRC from
* day one, matching homeblocks_sig_t's own precedent for exactly this
* reason: this gates a real security check, not a placeholder).
*
* Deliberately its own header, not inlined at the one call site that
* uses it today (kernel_main.c's first-boot mint-or-load): the ongoing
* `MINT` word (still open, FABRIC-3.md) will be a second consumer of
* this exact format later, and the format should be stable and
* documented once rather than ad-hoc.
*/
#ifndef STARKERNEL_ZUSE_CERT_DEVBLOCK_H
#define STARKERNEL_ZUSE_CERT_DEVBLOCK_H
#include <stdint.h>
/* Packed via shifts, not a hand-computed hex literal -- this project's
* own standing lesson about hand-derived numeric constants in this
* class of code (see FABRIC-3.md's Ed25519/scalar25519 writeups). */
#define ZUSE_CERT_DEVBLOCK_MAGIC \
((uint32_t)'Z' | ((uint32_t)'U' << 8) | ((uint32_t)'S' << 16) | ((uint32_t)'E' << 24))
#define ZUSE_CERT_DEVBLOCK_VERSION 1u
typedef struct {
uint32_t magic; /* ZUSE_CERT_DEVBLOCK_MAGIC; anything else means
* "not a real cert yet" (blank/foreign bytes),
* not a format-corruption error */
uint32_t version; /* ZUSE_CERT_DEVBLOCK_VERSION */
uint8_t seed[32]; /* Ed25519 seed -- the private identity */
uint8_t pubkey[32]; /* Ed25519 public key derived from seed at mint time */
uint64_t crc; /* CRC-64/ISO (block_subsystem.h's compute_crc64())
* over every byte of this struct up to (not
* including) this field -- real from day one,
* this gates a real security check */
uint8_t _pad[4096 - (4 + 4 + 32 + 32 + 8)];
} zuse_cert_devblock_t;
_Static_assert(sizeof(zuse_cert_devblock_t) == 4096,
"zuse_cert_devblock_t must be exactly one 4 KiB devblock");
#endif /* STARKERNEL_ZUSE_CERT_DEVBLOCK_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+58
View File
@@ -67,6 +67,7 @@ EFI_RUNTIME_SERVICES *g_sk_runtime_services = NULL;
#include "starkernel/virtio_blk.h"
#include "starkernel/virtio_rng.h"
#include "starkernel/ed25519.h"
#include "starkernel/zuse_cert_devblock.h"
#include "starkernel/virtio_input.h"
#include "starkernel/xhci_driver.h"
#include "block_subsystem.h"
@@ -630,6 +631,63 @@ static void kernel_main_deep(BootInfo *boot_info) {
}
}
/* Phase 8: Zuse first-boot mint-then-load, via the top-of-device
* system-metadata fence (block_subsystem.h's blk_meta_zone_read()/
* write(), FABRIC-3.md Phase 8 §C) -- NOT UEFI NVRAM. An earlier
* NVRAM-based attempt page-faulted inside OVMF's variable service on
* a real flash write (root-caused, documented, reverted); raw block
* I/O against Artemis's already-proven virtio-blk device has none of
* that risk and needs no runtime-services timing care at all. Runs
* here, before capsule_birth_mama() below, so ACL.4th/zuse.4th's
* self-activating ACL-ZUSE-BOOT sees a populated cert on its one,
* ordinary first pass -- no re-invocation workaround needed this
* time. "Mint once, ever": a valid ZUSE_CERT_DEVBLOCK_MAGIC record
* in the fence means a prior boot already minted -- load it back
* rather than generating a new one. Graceful no-op if there's no
* disk-backed device or no entropy source; Zuse simply won't
* authenticate this boot. */
{
zuse_cert_devblock_t rec;
int found = 0;
if (blk_meta_zone_read(0, (uint8_t *)&rec) == 0 &&
rec.magic == ZUSE_CERT_DEVBLOCK_MAGIC &&
rec.version == ZUSE_CERT_DEVBLOCK_VERSION) {
uint64_t want_crc = compute_crc64((const uint8_t *)&rec, offsetof(zuse_cert_devblock_t, crc));
if (want_crc == rec.crc) found = 1;
}
VM *zuse_vm = (VM *)mama_vm;
if (found) {
if (vm_zuse_cert_install(zuse_vm, rec.seed, rec.pubkey) == 0) {
console_println("Zuse: cert loaded from block fence");
}
} else if (virtio_rng_ready()) {
uint8_t seed[32];
if (virtio_rng_get_bytes(seed, sizeof(seed)) == 0) {
uint8_t pubkey[32];
ed25519_keygen(seed, pubkey);
if (vm_zuse_cert_install(zuse_vm, seed, pubkey) == 0) {
zuse_cert_devblock_t wrec;
memset(&wrec, 0, sizeof(wrec));
wrec.magic = ZUSE_CERT_DEVBLOCK_MAGIC;
wrec.version = ZUSE_CERT_DEVBLOCK_VERSION;
memcpy(wrec.seed, seed, 32);
memcpy(wrec.pubkey, pubkey, 32);
wrec.crc = compute_crc64((const uint8_t *)&wrec, offsetof(zuse_cert_devblock_t, crc));
if (blk_meta_zone_write(0, (const uint8_t *)&wrec) == 0) {
console_println("Zuse: minted, fuse blown");
} else {
console_println("Zuse: minted but fence write FAILED (not persistent)");
}
}
} else {
console_println("Zuse: entropy read failed, not minted this boot");
}
} else {
console_println("Zuse: no cert and no entropy source, not minted this boot");
}
}
/* item 4.3.5c: virtio-keyboard-pci, riscv64 only today. Unconditional
* call site, same as virtio_blk_find_artemis() above -- the function
* itself no-ops with a console message on architectures/boards where