Phase 8 C (2/n): expand cert storage; NVRAM persistence crashed, reverted
Cert storage expanded from the old 16-byte placeholder to a real 32-byte seed + 32-byte pubkey. vm_zuse_cert_install() now has a kernel-side duplicate in src/starkernel/vm/vm_core.c -- the kernel build's VM_EXCLUDE list drops src/vm.c entirely (same reason vm_set_base() already has two independent copies), so the hosted-only version added earlier this session was never actually linked into the kernel. FORTH-side ZUSE-CERT-LO@/HI@ replaced with ZUSE-PUBKEY@ (i -- u) over the public half only; ACL-ZUSE-BOOT now checks ZUSE-CERT-INSTALLED? before authenticating instead of unconditionally. Attempted NVRAM-based persistence (GetVariable/SetVariable) for the first-boot mint flow: page-faulted inside OVMF's variable service (CR2 in the flash MMIO window). Moving the call site to match the one proven-safe existing SetVariable call site in this codebase produced the identical crash -- not a timing issue. Localized with debug markers (one boot): GetVariable works; SetVariable with real data never returns. The existing "working" precedent call is actually a delete-of-nonexistent-variable (size=0, data=NULL), a cheaper path that never touches flash, so it proved nothing about real writes. Root cause: this kernel's VMM never maps the region OVMF's variable service needs for real flash writes -- a genuine gap in UEFI runtime- services support, not Zuse-specific, and not obviously fixable in a 3-arch-uniform way (flash window location is firmware/arch-specific). Independently, storing the raw seed in RUNTIME_ACCESS NVRAM would have been a real security defect regardless of the crash -- readable by any later-loaded UEFI app or the booted OS. Reverted to a known-safe state: all NVRAM/mint code removed from kernel_main.c, init.4th's ACL.4th line back to its documented commented-out default. Verified clean compile and clean boot on all three architectures. Cert storage expansion (the part that works) stays. A dedicated system-identity disk (virtio-blk, already proven for writes via Artemis) is the recommended next substrate -- not yet decided or built. Full investigation 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
f223a31cec
commit
e5cbc71f46
@@ -21,6 +21,7 @@
|
||||
#error "__STARKERNEL__ must be defined for kernel build"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "uefi.h"
|
||||
#include "console.h"
|
||||
#include "arch.h"
|
||||
@@ -65,6 +66,7 @@ EFI_RUNTIME_SERVICES *g_sk_runtime_services = NULL;
|
||||
#include "starkernel/pci.h"
|
||||
#include "starkernel/virtio_blk.h"
|
||||
#include "starkernel/virtio_rng.h"
|
||||
#include "starkernel/ed25519.h"
|
||||
#include "starkernel/virtio_input.h"
|
||||
#include "starkernel/xhci_driver.h"
|
||||
#include "block_subsystem.h"
|
||||
|
||||
@@ -266,6 +266,22 @@ void vm_set_base(VM* vm, unsigned b)
|
||||
vm->base = (cell_t)b; /* host mirror */
|
||||
}
|
||||
|
||||
/* Kernel-side copy of src/vm.c's vm_zuse_cert_install() -- the kernel
|
||||
* build excludes src/vm.c entirely (VM_EXCLUDE in Makefile.starkernel;
|
||||
* see vm_set_base() above for the same duplication pattern already
|
||||
* established), so any src/vm.c function the kernel needs to call gets
|
||||
* its own copy here. See src/vm.c's version for the full rationale
|
||||
* (why this is a VM struct field with no FORTH word, not a CONSTANT). */
|
||||
int vm_zuse_cert_install(VM* vm, const uint8_t seed[32], const uint8_t pubkey[32])
|
||||
{
|
||||
if (!vm) return -1;
|
||||
if (vm->zuse_cert_installed) return -1;
|
||||
memcpy(vm->zuse_cert_seed, seed, 32);
|
||||
memcpy(vm->zuse_cert_pubkey, pubkey, 32);
|
||||
vm->zuse_cert_installed = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ====================== VM init / teardown ======================= */
|
||||
void vm_cleanup(VM* vm)
|
||||
{
|
||||
|
||||
@@ -118,7 +118,8 @@ void vm_set_base(VM* vm, unsigned b)
|
||||
/* vm_tick* and heartbeat functions moved to vm_time.c */
|
||||
|
||||
/**
|
||||
* @brief One-time write of the Zuse cert value (blows the fuse).
|
||||
* @brief One-time write of the Zuse cert (seed + derived pubkey) -- blows
|
||||
* the fuse.
|
||||
*
|
||||
* Deliberately not backed by a dictionary CONSTANT: ACL-PIN only blocks
|
||||
* redefinition (vm_create_word shadowing), not a >BODY-then-store on the
|
||||
@@ -127,17 +128,17 @@ void vm_set_base(VM* vm, unsigned b)
|
||||
* corresponding FORTH store word closes that path entirely -- see
|
||||
* FABRIC-3.md's Milestone 4 mint-then-pin writeup for the finding.
|
||||
*
|
||||
* @param vm VM instance.
|
||||
* @param lo Cert value, low half.
|
||||
* @param hi Cert value, high half.
|
||||
* @return 0 on success; -1 if already installed (fuse already blown).
|
||||
* @param vm VM instance.
|
||||
* @param seed Ed25519 seed, 32 bytes (the private identity).
|
||||
* @param pubkey Ed25519 public key derived from seed, 32 bytes.
|
||||
* @return 0 on success; -1 if already installed (fuse already blown).
|
||||
*/
|
||||
int vm_zuse_cert_install(VM* vm, uint64_t lo, uint64_t hi)
|
||||
int vm_zuse_cert_install(VM* vm, const uint8_t seed[32], const uint8_t pubkey[32])
|
||||
{
|
||||
if (!vm) return -1;
|
||||
if (vm->zuse_cert_installed) return -1;
|
||||
vm->zuse_cert_lo = lo;
|
||||
vm->zuse_cert_hi = hi;
|
||||
memcpy(vm->zuse_cert_seed, seed, 32);
|
||||
memcpy(vm->zuse_cert_pubkey, pubkey, 32);
|
||||
vm->zuse_cert_installed = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -793,17 +793,31 @@ static void starforth_word_zuse_authenticate(VM *vm)
|
||||
vm->zuse_session = 1;
|
||||
}
|
||||
|
||||
/* ZUSE-CERT-LO@ ( -- lo ) Read-only: no FORTH store word exists or should
|
||||
* exist -- the cert is written exactly once, in C, via vm_zuse_cert_install(). */
|
||||
static void starforth_word_zuse_cert_lo_fetch(VM *vm)
|
||||
/* ZUSE-PUBKEY@ ( i -- u ) Read-only: fetch 8-byte little-endian chunk i
|
||||
* (0..3) of Zuse's 32-byte Ed25519 public key as one cell. Out-of-range i
|
||||
* pushes 0 and sets vm->error rather than faulting. No FORTH word can
|
||||
* write these bytes or read the seed -- the cert is written exactly once,
|
||||
* in C, via vm_zuse_cert_install(); this is a read-only window onto the
|
||||
* PUBLIC half only. */
|
||||
static void starforth_word_zuse_pubkey_fetch(VM *vm)
|
||||
{
|
||||
vm_push(vm, (cell_t)vm->zuse_cert_lo);
|
||||
}
|
||||
|
||||
/* ZUSE-CERT-HI@ ( -- hi ) See ZUSE-CERT-LO@. */
|
||||
static void starforth_word_zuse_cert_hi_fetch(VM *vm)
|
||||
{
|
||||
vm_push(vm, (cell_t)vm->zuse_cert_hi);
|
||||
if (vm->dsp < 0) {
|
||||
log_message(LOG_ERROR, "ZUSE-PUBKEY@: stack underflow");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
cell_t i = vm_pop(vm);
|
||||
if (i < 0 || i > 3) {
|
||||
vm_push(vm, 0);
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
const uint8_t *p = &vm->zuse_cert_pubkey[i * 8];
|
||||
cell_t chunk = 0;
|
||||
for (int b = 7; b >= 0; b--) {
|
||||
chunk = (chunk << 8) | (cell_t)p[b];
|
||||
}
|
||||
vm_push(vm, chunk);
|
||||
}
|
||||
|
||||
/* ZUSE-CERT-INSTALLED? ( -- flag ) -1 if the one-time cert fuse has been
|
||||
@@ -846,8 +860,7 @@ void register_starforth_words(VM* vm)
|
||||
register_word(vm, "RANDOM", starforth_word_random);
|
||||
register_word(vm, "WAIT", starforth_word_wait);
|
||||
register_word(vm, "ZUSE-AUTHENTICATE", starforth_word_zuse_authenticate);
|
||||
register_word(vm, "ZUSE-CERT-LO@", starforth_word_zuse_cert_lo_fetch);
|
||||
register_word(vm, "ZUSE-CERT-HI@", starforth_word_zuse_cert_hi_fetch);
|
||||
register_word(vm, "ZUSE-PUBKEY@", starforth_word_zuse_pubkey_fetch);
|
||||
register_word(vm, "ZUSE-CERT-INSTALLED?", starforth_word_zuse_cert_installed_query);
|
||||
register_word(vm, "HEARTBEAT-TICKS@", starforth_word_heartbeat_ticks);
|
||||
|
||||
@@ -867,8 +880,7 @@ void register_starforth_words(VM* vm)
|
||||
register_word(vm, "RANDOM", starforth_word_random);
|
||||
register_word(vm, "WAIT", starforth_word_wait);
|
||||
register_word(vm, "ZUSE-AUTHENTICATE", starforth_word_zuse_authenticate);
|
||||
register_word(vm, "ZUSE-CERT-LO@", starforth_word_zuse_cert_lo_fetch);
|
||||
register_word(vm, "ZUSE-CERT-HI@", starforth_word_zuse_cert_hi_fetch);
|
||||
register_word(vm, "ZUSE-PUBKEY@", starforth_word_zuse_pubkey_fetch);
|
||||
register_word(vm, "ZUSE-CERT-INSTALLED?", starforth_word_zuse_cert_installed_query);
|
||||
register_word(vm, "HEARTBEAT-TICKS@", starforth_word_heartbeat_ticks);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user