/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 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; relocated + GPT dropped §F.13/§F.8, * 2026-08-28) * * Identifies and authenticates a physical thumb drive as a legitimate * LithosAnanke home-blocks drive, before any write path touches it. * Lives at forth-block HOMEBLOCKS_SIG_START_FBLOCK (devblock 1) of the raw * device -- GPT partitioning was decided against permanently (§F.8): this * is the real, final on-disk location, not an interim stand-in. Devblock 0 * is left alone for the block-subsystem's own generic 'STFR'/v2 volume * header (block_subsystem.h) -- the two formats would otherwise collide * (§F.13, found while scoping BMAPREAD). * * 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 reserves offset/size pointers to where the cert * (CERTVERIFY, §F.7) and this identity's own personality/init source * (RUNCAP/MINT, §F.6/§F.8) attach, so this format doesn't need revisiting * when those get built -- it does not itself decide their content. */ #ifndef STARKERNEL_HOMEBLOCKS_SIG_H #define STARKERNEL_HOMEBLOCKS_SIG_H #include #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)) /* Where this header actually lives on a home-blocks drive: forth-block 4 * (devblock 1), NOT devblock 0 -- FABRIC-3.md §F.13, decided 2026-08-28. * Devblock 0 is reserved for the block-subsystem's own generic 'STFR'/v2 * volume header (block_subsystem.c); the two formats collide if both try * to occupy devblock 0 of the same raw device. GPT is permanently dropped * (§F.8) -- this is not an interim stand-in pending a GPT parser, it's the * real, final location. */ #define HOMEBLOCKS_SIG_START_FBLOCK 4u /*=========================================================================== * 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 the metadata region at the start of this raw * device (sig header + cert + identity-source regions), * in 4KiB devblocks -- everything past this is the owning * identity's own general block-storage pool directly (§F.6 * decision 3), no partition boundary involved. */ uint32_t cert_offset; /* Devblock offset from this device's start where this * identity's Zuse-signed cert blob starts (§F.7); 0 = not * yet minted. */ uint32_t cert_devblocks; /* Size reserved for the cert blob, in devblocks. */ uint32_t identity_src_offset; /* Devblock offset where this identity's own record * starts (RUNCAP/MINT, FABRIC-3.md §F.6/§F.8): first * devblock is a user_identity_seed_t, remainder is raw * FORTH personality/init source. Renamed from * blockmap_offset -- BMAPFMT (§F.4) repurposed blk_meta_t * instead of a centralized block-map, making the original * field unnecessary; this reuses the same reserved bytes * rather than adding new ones. 0 = not yet minted. */ uint32_t identity_src_devblocks; /* Size reserved for the identity record, 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 + /* identity_src_offset, identity_src_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, even though every real * caller now passes the same fixed HOMEBLOCKS_SIG_START_FBLOCK (GPT was * dropped, §F.8) -- keeps this function's own job (verify a signature * given a location) separate from callers deciding what that location is. * * @param dev Open block device to read from. * @param sig_start_fblock First of 4 consecutive forth-blocks holding the * 4KB header -- HOMEBLOCKS_SIG_START_FBLOCK for * every real caller today. * @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 */