Files
LithosAnanke/kernel/src/capsule/capsule_zuse_boot.c
T
rajamesandClaude Opus 5.5 75785fb025 refactor(kernel): Zuse's drive check without a VM
capsule_zuse_boot_check() makes the check capsule_zuse_boot_try_attach()
made -- the genesis marker, the drive's identity record (magic, version,
CRC-64, public key) -- and says HERS, GENESIS or NOT_HERS, with no VM;
capsule_zuse_boot_root_pubkey() reads the marker's key. try_attach and
load_root_pubkey call them; their behaviour and messages are unchanged.
The v4 boot will make the same check (identity gate plan, D1).

Shown on v3 (system=v3, amd64): the minted pair, "Zuse: identity
confirmed" and [zuse@Hera] ok> (logs/20261026-083603); a blank pair,
"Zuse: genesis minted onto attached thumbdrive" (logs/20261026-084729).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 08:48:17 -04:00

236 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
Licensed under the StarForth License, Version 1.0
*/
#ifndef __STARKERNEL__
#error "capsule_zuse_boot.c is kernel-only"
#endif
#include "starkernel/capsule_zuse_boot.h"
#include "starkernel/capsule_mint.h"
#include "starkernel/zuse_genesis_marker.h"
#include "starkernel/user_identity_seed.h"
#include "starkernel/console.h"
#include "block_subsystem.h" /* compute_crc64(), blk_meta_zone_read/write */
#include "blkio.h"
#include <string.h>
#include <stddef.h>
/* FABRIC-3.md §VII follow-on, 2026-09-06: g_zuse_attached_this_device was a
* bare boolean under the single-USB-device constraint (§F.8) -- "a detach
* event is hers" needed no device comparison because only one device could
* ever be attached at all. That premise is stale (FABRIC-3.md §VII, the
* xHCI/BOT driver now supports genuine simultaneous multi-device attach) --
* confirmed live during this session's own 8-identity verification: with
* Zuse's drive and a WIREBIND target both attached, detaching the *target*
* incorrectly logged Zuse out too, because capsule_zuse_boot_logout() had
* no way to tell "some other device detached" from "my own device
* detached." g_zuse_attached_dev is the fix, mirroring capsule_wirebind.c's
* own g_wirebind_attached_dev precedent exactly -- the boolean stays (still
* useful as a fast "is she attached at all" check) but logout now also
* requires the departing device to match. */
static int g_zuse_attached_this_device = 0;
static struct blkio_dev *g_zuse_attached_dev = (struct blkio_dev *) 0;
/* Read exactly one devblock (4096 bytes) at devblock offset `devblock`,
* as 4 consecutive 1KiB forth-block reads -- mirrors capsule_runcap.c's
* and homeblocks_sig_check()'s own read convention. */
static int read_devblock(struct blkio_dev *dev, uint32_t devblock, uint8_t *buf4096) {
uint32_t base = devblock * 4u;
for (uint32_t i = 0; i < 4u; i++) {
if (blkio_read((blkio_dev_t *)dev, base + i,
buf4096 + (size_t)i * BLKIO_FORTH_BLOCK_SIZE) != BLKIO_OK) {
return -1;
}
}
return 0;
}
static int genesis_marker_read(zuse_genesis_marker_t *out) {
if (blk_meta_zone_read(0, (uint8_t *)out) != 0) return -1;
if (out->magic != ZUSE_GENESIS_MARKER_MAGIC) return -1;
if (out->version != ZUSE_GENESIS_MARKER_VERSION) return -1;
uint64_t want_crc = compute_crc64((const uint8_t *)out, offsetof(zuse_genesis_marker_t, crc));
if (want_crc != out->crc) return -1;
return 0;
}
static void install_and_activate(VM *mama_vm, struct blkio_dev *dev,
const uint8_t seed[32], const uint8_t pubkey[32]) {
/* vm_zuse_cert_install() is deliberately one-way (returns -1, no-op,
* once vm->zuse_cert_installed is already 1) -- that's a real
* security property (the cert/pubkey must never be re-installed or
* swapped) and stays untouched here. Its return is NOT used to gate
* ACL-ZUSE-BOOT below anymore (FABRIC-2.md §I.8, re-scoped
* 2026-09-04): re-authenticating after capsule_zuse_boot_logout()
* needs ACL-ZUSE-BOOT to re-run and re-set zuse_session even when
* the cert itself was already installed from an earlier boot-time
* attach -- gating it on install's success/failure made re-login
* impossible, since a second install always fails by design. */
vm_zuse_cert_install(mama_vm, seed, pubkey);
/* Real defect found live 2026-09-22 verifying FABRIC-3.6.md task 3.9:
* capsule_zuse_boot_load_root_pubkey() is the only other writer of
* zuse_root_pubkey_known, and it only runs once, at Artemis's
* boot-time virtio-blk attach (kernel_main.c) -- before genesis mint
* has happened on a fresh artemis.img, so it finds no marker yet and
* leaves the flag 0. Nothing re-triggers it after genesis mint
* completes. Silent result: capsule_wirebind_try_attach()'s own
* `if (!mama_vm->zuse_root_pubkey_known) return;` gate (this file's
* sibling function) then refuses every identity attach for the rest
* of the boot, with no message at all -- exactly the failure mode
* FABRIC-3.5.md SXXXV.0 names. Fixed at the source: the pubkey this
* function was just handed (from genesis mint, above, or from an
* already-Zuse re-attach, below) IS the root pubkey -- activate it
* directly here instead of relying on a disk re-read that may never
* happen this session. Matches vm_zuse_cert_install()'s own one-way
* idempotence (harmless to set twice). */
memcpy(mama_vm->zuse_root_pubkey, pubkey, 32);
mama_vm->zuse_root_pubkey_known = 1;
/* zuse.4th's ACL-ZUSE-BOOT self-activated once already at Mama's own
* birth, when no cert was installed yet (the thumbdrive wasn't
* attached at that early, one-shot point) -- ACL-PIN only blocks
* *redefinition*, not re-execution, so re-running the same policy
* word here is the correct, already-designed way to activate
* zuse_session now that a cert genuinely exists. No new C-side auth
* logic; policy stays in ACL.4th/zuse.4th per this project's own
* convention. */
vm_interpret(mama_vm, "ACL-ZUSE-BOOT");
g_zuse_attached_this_device = 1;
g_zuse_attached_dev = dev;
/* Decided 2026-09-05: no console for the running system unless a
* thumbdrive is present. Zuse's own login is not special here --
* "nothing special about zuse as a user except zuse has no ACLs,"
* per direct instruction. Revised 2026-09-06: no longer calls
* sk_console_mark_login() (a one-way sticky flag) -- the gate is now a
* live check (sk_console_identity_present(), repl.c) driven directly
* by mama_vm->zuse_session, which vm_interpret(mama_vm,
* "ACL-ZUSE-BOOT") above already sets. Nothing to call here anymore. */
}
/* The check, with no VM (split out 2026-10-26 so the v4 boot makes the same
* one: docs/v4.0.0/plans/2026-10-26-engine-step4-identity-gate.md, D1). */
zuse_drive_t capsule_zuse_boot_check(struct blkio_dev *dev,
homeblocks_sig_result_t sig_rc,
const homeblocks_sig_t *sig,
uint8_t seed[32], uint8_t pubkey[32]) {
zuse_genesis_marker_t marker;
if (!dev) return ZUSE_DRIVE_NOT_HERS;
if (genesis_marker_read(&marker) != 0) {
/* no marker: a blank drive is eligible for genesis, nothing else is */
return sig_rc == HOMEBLOCKS_SIG_BLANK ? ZUSE_DRIVE_GENESIS : ZUSE_DRIVE_NOT_HERS;
}
/* Marker present: genesis already happened, on some thumbdrive.
* Only this drive if it is that drive. */
if (sig_rc != HOMEBLOCKS_SIG_OK || !sig) return ZUSE_DRIVE_NOT_HERS;
if (sig->identity_src_offset == 0 || sig->identity_src_devblocks < 1) return ZUSE_DRIVE_NOT_HERS;
user_identity_seed_t idrec;
if (read_devblock(dev, sig->identity_src_offset, (uint8_t *)&idrec) != 0) return ZUSE_DRIVE_NOT_HERS;
/* Same magic -> version -> CRC-64 discipline as genesis_marker_read():
* this record carries Zuse's private key (the seed), so a corrupt or
* format-mismatched record must be refused, never loaded -- a bad CRC
* could otherwise install a garbage seed as Zuse's identity. */
if (idrec.magic != USER_IDENTITY_SEED_MAGIC) return ZUSE_DRIVE_NOT_HERS;
if (idrec.version != USER_IDENTITY_SEED_VERSION) return ZUSE_DRIVE_NOT_HERS;
uint64_t want_crc = compute_crc64((const uint8_t *)&idrec,
offsetof(user_identity_seed_t, crc));
if (want_crc != idrec.crc) return ZUSE_DRIVE_NOT_HERS;
if (memcmp(idrec.pubkey, marker.zuse_pubkey, 32) != 0) return ZUSE_DRIVE_NOT_HERS; /* not Zuse's drive */
memcpy(seed, idrec.seed, 32);
memcpy(pubkey, idrec.pubkey, 32);
return ZUSE_DRIVE_HERS;
}
int capsule_zuse_boot_root_pubkey(uint8_t pubkey[32]) {
zuse_genesis_marker_t marker;
if (genesis_marker_read(&marker) != 0) return -1; /* no genesis yet */
memcpy(pubkey, marker.zuse_pubkey, 32);
return 0;
}
void capsule_zuse_boot_try_attach(struct blkio_dev *dev,
homeblocks_sig_result_t sig_rc,
const homeblocks_sig_t *sig,
VM *mama_vm) {
uint8_t seed[32], pubkey[32];
zuse_drive_t which;
if (!dev || !mama_vm) return;
/* FABRIC-2.md §I.8, re-scoped 2026-09-04: gate on zuse_session, not
* zuse_cert_installed. zuse_cert_installed never clears (one-way,
* see install_and_activate()'s own comment) and would permanently
* block re-authentication after a logout; zuse_session does clear
* (capsule_zuse_boot_logout()), which is exactly the "already have
* Zuse THIS SESSION" check this early-return is actually for. */
if (mama_vm->zuse_session) return;
which = capsule_zuse_boot_check(dev, sig_rc, sig, seed, pubkey);
if (which == ZUSE_DRIVE_GENESIS) {
MintResult r = capsule_mint_identity(dev, (VM *)0, "Zuse", "zuse",
(const char *)0, (const char *)0,
pubkey, seed,
MINT_PERSONALITY_DEFAULT, /* Zuse is the superuser -- never restricted */
1 /* sig_rc already confirmed BLANK above */);
if (r != MINT_OK) {
console_println("Zuse: genesis mint failed");
return;
}
zuse_genesis_marker_t wm;
memset(&wm, 0, sizeof(wm));
wm.magic = ZUSE_GENESIS_MARKER_MAGIC;
wm.version = ZUSE_GENESIS_MARKER_VERSION;
memcpy(wm.zuse_pubkey, pubkey, 32);
wm.crc = compute_crc64((const uint8_t *)&wm, offsetof(zuse_genesis_marker_t, crc));
if (blk_meta_zone_write(0, (const uint8_t *)&wm) != 0) {
console_println("Zuse: genesis minted but fence marker write FAILED (not persistent)");
} else {
console_println("Zuse: genesis minted onto attached thumbdrive");
}
install_and_activate(mama_vm, dev, seed, pubkey);
return;
}
if (which != ZUSE_DRIVE_HERS) return;
console_println("Zuse: identity confirmed from attached thumbdrive");
install_and_activate(mama_vm, dev, seed, pubkey);
}
void capsule_zuse_boot_logout(VM *mama_vm, struct blkio_dev *dev) {
if (!mama_vm || !g_zuse_attached_this_device) return;
/* The device actually detaching must be hers -- see g_zuse_attached_dev's
* own doc comment above. A different device (a WIREBIND target,
* general-purpose USB use) detaching while her own drive stays
* attached must not touch her session at all. */
if (dev != g_zuse_attached_dev) return;
mama_vm->zuse_session = 0;
g_zuse_attached_this_device = 0;
g_zuse_attached_dev = (struct blkio_dev *) 0;
console_println("Zuse: session ended -- reattach to re-authenticate");
}
struct blkio_dev *capsule_zuse_boot_attached_dev(void) {
return g_zuse_attached_this_device ? g_zuse_attached_dev : (struct blkio_dev *) 0;
}
void capsule_zuse_boot_load_root_pubkey(VM *mama_vm) {
if (!mama_vm || mama_vm->zuse_root_pubkey_known) return;
if (capsule_zuse_boot_root_pubkey(mama_vm->zuse_root_pubkey) != 0) return; /* no genesis yet -- nothing to load */
mama_vm->zuse_root_pubkey_known = 1;
}