Files
LithosAnanake/include/starkernel/homeblocks_sig.h
T
Robert Allan JamesandClaude Sonnet 5 2c45744995 Implement homeblocks_sig_check(): the drive signature check (Phase 8)
Real, complete verification logic -- not yet wired to any write path.
homeblocks_sig_check(dev, sig_start_fblock, out_sig) reads the 4
consecutive 1KB blkio forth-blocks the 4KB header spans, verifies
magic -> version -> CRC-64 in order, returns HOMEBLOCKS_SIG_OK/_BLANK/
_BAD_VERSION/_BAD_CRC/_READ_ERROR. Reuses block_subsystem.c's existing
CRC-64/ISO (compute_crc64, previously static/file-local, now exposed
via block_subsystem.h) rather than a second CRC implementation --
same algorithm already proven via per-block checksums. Takes the
header's starting block as a plain parameter rather than resolving it
internally: verifies a signature given a location, finding that
location (GPT-partition-relative) stays the caller's job.

Verified against the actual shipped code, not a reimplementation: a
standalone host test links the real homeblocks_sig.c against a fake
in-memory blkio_dev and exercises all four outcomes -- blank media,
a correctly-minted header (round-trips drive_uuid/minted_time_ns), a
flipped CRC, an unrecognized version. All four pass. A full
QEMU-hotplug live test isn't proportionate yet since nothing calls
this function from the live kernel path -- wiring it into the attach
path is the next punch-list item. Clean zero-warning compile and
clean boot on all three architectures confirms no build/link
regression from exposing compute_crc64 and adding the new source
file to every kernel build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXjAPTEKrgY2Mrk25KoLDn
2026-08-26 07:05:37 -04:00

176 lines
8.2 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) 20232025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* homeblocks_sig.h - Home-blocks drive signature format (FABRIC-3.md,
* Milestone 4, Phase 8 kickoff)
*
* Identifies and authenticates a physical thumb drive as a legitimate
* LithosAnanke home-blocks drive, before any write path touches it.
* Lives at the first 4KiB devblock of the drive's GPT metadata partition
* (the ~1GB partition decided 2026-08-22) -- this header's own format does
* not depend on the GPT parser that locates that partition; it is simply
* what gets written starting at that partition's first devblock, once
* something can find it.
*
* Mirrors two existing precedents exactly, not invented fresh:
* - CAPSULE_MAGIC_PACK's bit-packed magic (starkernel/capsule.h)
* - blk_volume_meta_t's magic+version+fields+pad-to-4096 structural
* convention (block_subsystem.h)
*
* Deliberately narrow in scope: this header identifies/authenticates the
* DRIVE only. It does not invent the on-drive block-map format (Milestone
* 3, still undesigned) or the credential/cert format (Milestone 6, blocked
* on a real CA that does not exist yet) -- it only reserves offset/size
* pointers to where those will attach, so this format does not need to be
* revisited when those get designed.
*/
#ifndef STARKERNEL_HOMEBLOCKS_SIG_H
#define STARKERNEL_HOMEBLOCKS_SIG_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*===========================================================================
* Magic Field Packing -- same bit layout convention as CAPSULE_MAGIC_PACK
*
* bits 0..31 : 'LAHB' (0x4248414C little-endian) -- LithosAnanke Home Blocks
* bits 32..39 : version (0 for v0)
* bits 40..63 : reserved (zero)
*===========================================================================*/
#define HOMEBLOCKS_SIG_MAGIC 0x4248414CULL /* 'LAHB', same little-endian ASCII
* packing as CAPSULE_DESC_MAGIC's 'CAPS' */
#define HOMEBLOCKS_SIG_VERSION_0 0
#define HOMEBLOCKS_SIG_PACK(ver) \
(HOMEBLOCKS_SIG_MAGIC | ((uint64_t)(ver) << 32))
#define HOMEBLOCKS_SIG_GET_MAGIC(m) ((uint32_t)((m) & 0xFFFFFFFFULL))
#define HOMEBLOCKS_SIG_GET_VERSION(m) ((uint8_t)(((m) >> 32) & 0xFF))
/*===========================================================================
* homeblocks_sig_t - drive signature header (exactly one 4KiB devblock)
*===========================================================================*/
typedef struct {
uint64_t magic; /* HOMEBLOCKS_SIG_PACK(...) */
uint8_t drive_uuid[16]; /* Unique per-mint instance id -- Phase 8 mints multiple
* distinct drives, needs something to tell them apart. */
uint64_t minted_time_ns; /* Monotonic timestamp at mint time. */
uint64_t metadata_devblocks; /* Size of this GPT metadata partition, in 4KiB devblocks --
* sanity/bounds check against the GPT entry once a parser
* exists. */
uint32_t cert_offset; /* Devblock offset within this partition where the CA-signed
* cert blob starts; 0 = not yet minted. Format not decided --
* Milestone 6's real CA does not exist yet. */
uint32_t cert_devblocks; /* Size reserved for the cert blob, in devblocks. */
uint32_t blockmap_offset; /* Devblock offset where the block-map starts; 0 = not yet
* minted. Format not decided -- Milestone 3, still open. */
uint32_t blockmap_devblocks; /* Size reserved for the block-map, in devblocks. */
uint64_t hdr_crc; /* REAL from day one, not a placeholder like
* blk_volume_meta_t's "unused yet" hdr_crc -- this header's
* whole job is gating a warn-and-refuse security check
* against blank/foreign/unrecognized media, so the crc has
* to actually work. Computed over every field above this
* one; callers must fill every other field before computing
* or verifying it. */
/* Padding to keep the header exactly one 4KiB devblock. */
uint8_t _pad[4096 - (
8 + /* magic */
16 + /* drive_uuid */
8 + /* minted_time_ns */
8 + /* metadata_devblocks */
4 + 4 + /* cert_offset, cert_devblocks */
4 + 4 + /* blockmap_offset, blockmap_devblocks */
8 /* hdr_crc */
)];
} homeblocks_sig_t;
/* C99-portable compile-time size assertion (no _Static_assert -- that's C11),
* same discipline stadium.h's own header-size checks already use. */
typedef char homeblocks_sig_size_check[(sizeof(homeblocks_sig_t) == 4096) ? 1 : -1];
/*===========================================================================
* Signature check (FABRIC-3.md, Milestone 4)
*===========================================================================*/
typedef enum {
HOMEBLOCKS_SIG_OK = 0, /* magic, version, and crc all check out */
HOMEBLOCKS_SIG_BLANK, /* magic does not match -- blank or foreign media */
HOMEBLOCKS_SIG_BAD_VERSION, /* magic matches, version unrecognized */
HOMEBLOCKS_SIG_BAD_CRC, /* magic+version match, crc fails -- corrupt or tampered */
HOMEBLOCKS_SIG_READ_ERROR /* could not read from the device at all */
} homeblocks_sig_result_t;
/* Forward-declared, not included here -- avoids a hard dependency from this
* small format header onto blkio.h's full device/vtable machinery for
* callers that only need the struct layout (e.g. a future minting tool). */
struct blkio_dev;
/*
* homeblocks_sig_check - Read and verify the drive signature header.
*
* Reads 4 consecutive 1KB "forth blocks" (dev->read()'s own unit) starting
* at sig_start_fblock into a local 4KB buffer and interprets it as a
* homeblocks_sig_t. Deliberately takes the starting block as a plain
* parameter rather than resolving it internally -- this function verifies a
* signature given a location; finding that location (GPT-partition-relative
* today, once a GPT parser exists) is the caller's job, not invented here.
*
* @param dev Open block device to read from.
* @param sig_start_fblock First of 4 consecutive forth-blocks holding the
* 4KB header.
* @param out_sig On HOMEBLOCKS_SIG_OK, populated with the verified
* header. Left unspecified on any other result.
* @return HOMEBLOCKS_SIG_OK, or the specific reason for refusal.
*/
homeblocks_sig_result_t homeblocks_sig_check(struct blkio_dev *dev,
uint32_t sig_start_fblock,
homeblocks_sig_t *out_sig);
/*
* homeblocks_sig_compute_crc - CRC-64 over every field of `sig` up to but
* not including hdr_crc itself and the trailing padding -- the same
* boundary homeblocks_sig_check() verifies against and any future minting
* code must use when writing a fresh header. Exposed publicly since both
* directions (check and future mint) need the identical computation.
*
* @param sig Header to checksum. hdr_crc and _pad are not read.
* @return The CRC-64 value that hdr_crc should hold for `sig` to verify.
*/
uint64_t homeblocks_sig_compute_crc(const homeblocks_sig_t *sig);
#ifdef __cplusplus
}
#endif
#endif /* STARKERNEL_HOMEBLOCKS_SIG_H */