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>
159 lines
7.3 KiB
C
159 lines
7.3 KiB
C
/*
|
||
StarForth — Steady-State Virtual Machine Runtime
|
||
|
||
Copyright (c) 2023–2025 Robert A. James
|
||
All rights reserved.
|
||
|
||
Licensed under the StarForth License, Version 1.0
|
||
*/
|
||
|
||
/**
|
||
* capsule_zuse_boot.h - Thumbdrive-resident Zuse genesis/attach
|
||
* (FABRIC-2.md §F.20/§F.21). Replaces kernel_main.c's old one-shot
|
||
* block-fence mint-or-load: Zuse's own identity now lives only on her
|
||
* own minted thumbdrive, never system-resident. Since USB attach
|
||
* detection only happens inside the idle loop (sk_repl_idle(), not at
|
||
* a fixed point in the boot sequence), this runs per-attach from there
|
||
* instead of once at boot.
|
||
*/
|
||
|
||
#ifndef STARKERNEL_CAPSULE_ZUSE_BOOT_H
|
||
#define STARKERNEL_CAPSULE_ZUSE_BOOT_H
|
||
|
||
#ifdef __STARKERNEL__
|
||
|
||
#include "starkernel/homeblocks_sig.h"
|
||
#include "vm.h"
|
||
|
||
struct blkio_dev;
|
||
|
||
/** What a just-attached drive is to Zuse (capsule_zuse_boot_check()). */
|
||
typedef enum {
|
||
ZUSE_DRIVE_NOT_HERS = 0, /* another identity's, foreign, corrupt, or no genesis and not blank */
|
||
ZUSE_DRIVE_HERS, /* the genesis marker's drive: its identity record checks out */
|
||
ZUSE_DRIVE_GENESIS /* no genesis marker yet, and the drive is blank: eligible */
|
||
} zuse_drive_t;
|
||
|
||
/**
|
||
* capsule_zuse_boot_check - The check capsule_zuse_boot_try_attach() makes,
|
||
* with no VM: the v3 path and the v4 boot both use it
|
||
* (docs/v4.0.0/plans/2026-10-26-engine-step4-identity-gate.md, D1).
|
||
* Reads the genesis marker from the block subsystem's metadata fence and,
|
||
* when there is one, the drive's own identity record (magic, version,
|
||
* CRC-64, public key against the marker's). Writes nothing.
|
||
*
|
||
* @param seed, pubkey Zuse's seed and public key, filled in only for
|
||
* ZUSE_DRIVE_HERS.
|
||
*/
|
||
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]);
|
||
|
||
/**
|
||
* capsule_zuse_boot_root_pubkey - Zuse's public key from the genesis
|
||
* marker. Returns 0 with @p pubkey filled in, or -1 (no genesis yet, or the
|
||
* marker fails its checks; @p pubkey untouched).
|
||
*/
|
||
int capsule_zuse_boot_root_pubkey(uint8_t pubkey[32]);
|
||
|
||
/**
|
||
* capsule_zuse_boot_try_attach - Try to genesis-mint or authenticate
|
||
* Zuse from a just-attached drive.
|
||
*
|
||
* No-op if mama_vm->zuse_cert_installed is already 1 (Zuse already has a
|
||
* real identity this boot, from an earlier attach). Otherwise:
|
||
* - No genesis marker yet in the fence, drive reads HOMEBLOCKS_SIG_BLANK:
|
||
* mint Zuse's own identity onto it (capsule_mint_identity(), genesis
|
||
* mode), record the pubkey in the fence, install the cert, and
|
||
* re-run ACL-ZUSE-BOOT (zuse.4th) so zuse_session activates exactly
|
||
* like it always has for a same-boot-installed cert.
|
||
* - Genesis marker present, drive reads HOMEBLOCKS_SIG_OK: read its
|
||
* own user_identity_seed_t, compare pubkey against the marker: if it
|
||
* matches, install the cert and re-run ACL-ZUSE-BOOT the same way.
|
||
* If it doesn't match, this is some other identity's drive -- no-op
|
||
* here, that's a regular attach for BINDSTEP to handle later.
|
||
* - Anything else (foreign/corrupt media, no marker and non-blank
|
||
* drive): no-op.
|
||
*
|
||
* @param dev The just-attached, already-open block device.
|
||
* @param sig_rc homeblocks_sig_check()'s own result for this attach.
|
||
* @param sig The checked homeblocks_sig_t (only meaningful if
|
||
* sig_rc == HOMEBLOCKS_SIG_OK; may be NULL otherwise).
|
||
* @param mama_vm Hera's own VM (zuse_cert_seed/installed/session live
|
||
* here; also the target of the ACL-ZUSE-BOOT re-run).
|
||
*/
|
||
void capsule_zuse_boot_try_attach(struct blkio_dev *dev,
|
||
homeblocks_sig_result_t sig_rc,
|
||
const homeblocks_sig_t *sig,
|
||
VM *mama_vm);
|
||
|
||
/**
|
||
* capsule_zuse_boot_logout - End Zuse's session when her own attached
|
||
* drive detaches (FABRIC-2.md §I.8, re-scoped 2026-09-04: no identity is
|
||
* different here -- Zuse logs out on device removal exactly like a
|
||
* WIREBIND user does, not via a Stadium-patron TTL. She has no separate
|
||
* VM or blocks of her own, so unlike capsule_wirebind_eject()/
|
||
* _unclean_detach() there is no flush step to skip on the abrupt path --
|
||
* one function covers both the graceful (EJECT) and abrupt (hot-unplug)
|
||
* call sites identically.
|
||
*
|
||
* No-op if `dev` isn't the device currently tracked as Zuse's own (nothing
|
||
* to do -- some other identity's drive is what's leaving, or nothing is
|
||
* attached at all) -- FABRIC-3.md §VII follow-on, 2026-09-06: this doc
|
||
* comment always claimed that no-op, but the check itself was missing
|
||
* until now (the function took no device parameter at all) -- confirmed
|
||
* live as a real bug once genuine multi-device attach made it reachable
|
||
* (detaching an unrelated device logged Zuse out too). Clears
|
||
* mama_vm->zuse_session only -- zuse_cert_installed and the cert itself
|
||
* stay put, permanently, per vm_zuse_cert_install()'s own one-way design;
|
||
* re-attaching her own drive re-authenticates via
|
||
* capsule_zuse_boot_try_attach() without re-minting anything.
|
||
*
|
||
* @param mama_vm Hera's own VM (zuse_session lives here).
|
||
* @param dev The device that just detached -- compared against the one
|
||
* tracked as hers; every other value is a no-op.
|
||
*/
|
||
void capsule_zuse_boot_logout(VM *mama_vm, struct blkio_dev *dev);
|
||
|
||
/**
|
||
* capsule_zuse_boot_attached_dev - The device currently tracked as Zuse's
|
||
* own, or NULL if she isn't attached this boot. FABRIC-3.md §VII follow-on,
|
||
* 2026-09-06: exists so an explicit, operator-initiated logout (EJECT,
|
||
* mama_forth_words.c) can pass her own device back into
|
||
* capsule_zuse_boot_logout() without needing to already know it -- unlike
|
||
* the abrupt hot-unplug path, EJECT isn't reacting to any specific
|
||
* device's detach event, so there is no other device value available at
|
||
* that call site to check against.
|
||
*/
|
||
struct blkio_dev *capsule_zuse_boot_attached_dev(void);
|
||
|
||
/**
|
||
* capsule_zuse_boot_load_root_pubkey - Populate mama_vm->zuse_root_pubkey/
|
||
* zuse_root_pubkey_known from the persistent genesis-marker fence
|
||
* (zuse_genesis_marker_t, block_subsystem.h's blk_meta_zone_read()),
|
||
* independently of whether Zuse's own thumbdrive is attached this boot.
|
||
*
|
||
* Call once, early -- as soon as the block subsystem and Artemis's own
|
||
* resident storage are up (the fence lives there, not on any removable
|
||
* drive) -- from kernel_main.c. No-op (leaves zuse_root_pubkey_known 0)
|
||
* if no genesis has ever happened yet (no marker in the fence): there is
|
||
* no root identity to verify against, so no WIREBIND identity could have
|
||
* a cert chained to one either.
|
||
*
|
||
* Deliberately does not touch zuse_cert_installed/zuse_cert_seed/
|
||
* zuse_cert_pubkey -- that triple stays reserved for Zuse's own live,
|
||
* authenticated session (capsule_zuse_boot_try_attach()), gating MINT
|
||
* (needs her private seed). This function only ever loads her already-
|
||
* public key, for WIREBIND cert *verification* (capsule_wirebind.c),
|
||
* which needs nothing else -- see zuse_root_pubkey_known's own doc
|
||
* comment (vm.h) for the full reasoning.
|
||
*
|
||
* @param mama_vm Hera's own VM (zuse_root_pubkey/_known live here).
|
||
*/
|
||
void capsule_zuse_boot_load_root_pubkey(VM *mama_vm);
|
||
|
||
#endif /* __STARKERNEL__ */
|
||
|
||
#endif /* STARKERNEL_CAPSULE_ZUSE_BOOT_H */
|