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:
co-authored by
Claude Sonnet 5
parent
6e9c1d3bc2
commit
a8692681a8
+44
@@ -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,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. -->
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user