/* * zuse_eligibility_list.h -- on-disk record format for Zuse's word/block * elevation eligibility list (FABRIC-2.md §H.5/§H.12 Phase 6): a simple * growable list of owner_pubkey[32] entries, no extra per-entry metadata * ("simple list, no extra metadata, unless we find a reason this won't * work"). Zuse checks this list before honoring any ELEVATE-REQUEST * (§H.7/§H.8) -- gating layer on top of the message-based elevation * trigger, not a replacement for it. * * Lives in the same top-of-device system-metadata fence as * zuse_genesis_marker_t (block_subsystem.h's blk_meta_zone_read()/ * write(), Phase 8/§C), one slot over: the genesis marker owns * devblock_from_top=0, this list starts at devblock_from_top=1. Growable * across multiple devblocks via a singly-linked chain (each devblock's * `next_devblock_from_top` points at the next one, ZULIST_NO_NEXT means * "this is the last devblock in the chain") -- entries are appended by * filling the current tail devblock, then chaining a fresh one out of the * already-reserved BLK_META_FENCE_INIT budget once it's full. No fence * growth logic is needed yet: only 2 of the 128 pre-reserved devblocks * are spoken for (0 = genesis marker, 1 = this list's head) and the * chain has 126 more slots to grow into before that budget itself would * need extending. * * Raw, unpacked 4 KiB devblock -- same convention as * zuse_genesis_marker_t/homeblocks_sig_t: real CRC from day one, this * gates a real security check, not a placeholder. */ #ifndef STARKERNEL_ZUSE_ELIGIBILITY_LIST_H #define STARKERNEL_ZUSE_ELIGIBILITY_LIST_H #include /* Packed via shifts, not a hand-computed hex literal -- see * zuse_genesis_marker.h's own note on this project's standing * numeric-constant convention. */ #define ZUSE_ELIGIBILITY_LIST_MAGIC \ ((uint32_t)'Z' | ((uint32_t)'E' << 8) | ((uint32_t)'L' << 16) | ((uint32_t)'G' << 24)) #define ZUSE_ELIGIBILITY_LIST_VERSION 1u /* devblock_from_top of this list's head devblock -- one past the genesis * marker's devblock_from_top=0. */ #define ZUSE_ELIGIBILITY_LIST_HEAD_DEVBLOCK 1u /* next_devblock_from_top value meaning "no further devblock -- this is * the tail of the chain." 0xFFFFFFFF can never be a real * devblock_from_top (BLK_META_FENCE_INIT is 128), so it is unambiguous. */ #define ZUSE_ELIGIBILITY_LIST_NO_NEXT 0xFFFFFFFFu /* How many owner_pubkey[32] entries fit in one devblock alongside the * header/crc/next-pointer overhead below. */ #define ZUSE_ELIGIBILITY_ENTRIES_PER_DEVBLOCK 127u typedef struct { uint32_t magic; /* ZUSE_ELIGIBILITY_LIST_MAGIC; anything else on * the head devblock means "list not created * yet" (blank/foreign bytes), not a * format-corruption error. A non-head devblock * is only ever read by following a real * next_devblock_from_top link, so its own * magic is still checked the same way to catch * a corrupt/foreign devblock mid-chain. */ uint32_t version; /* ZUSE_ELIGIBILITY_LIST_VERSION */ uint32_t count; /* Number of valid entries in this devblock's * own entries[] (0..ZUSE_ELIGIBILITY_ENTRIES_ * PER_DEVBLOCK), not a running total across the * whole chain. */ uint32_t next_devblock_from_top; /* Next devblock in the chain, or * ZUSE_ELIGIBILITY_LIST_NO_NEXT if this is the * tail. */ uint8_t entries[ZUSE_ELIGIBILITY_ENTRIES_PER_DEVBLOCK][32]; /* Ed25519 * public keys eligible for elevation. Only the * first `count` entries are meaningful. */ uint64_t crc; /* CRC-64/ISO (block_subsystem.h's * compute_crc64()) over every byte of this * struct up to (not including) this field. */ uint8_t _pad[4096 - (4 + 4 + 4 + 4 + (ZUSE_ELIGIBILITY_ENTRIES_PER_DEVBLOCK * 32) + 8)]; } zuse_eligibility_devblock_t; _Static_assert(sizeof(zuse_eligibility_devblock_t) == 4096, "zuse_eligibility_devblock_t must be exactly one 4 KiB devblock"); #endif /* STARKERNEL_ZUSE_ELIGIBILITY_LIST_H */