/* * capsule_sig.h -- per-capsule Ed25519 signature verification * (Milestone 6, Phase 8). Deliberately kept separate from * capsule_validate.c: that function is already tested and its * signature/behavior stays untouched; this is a new, additive check * called alongside it, not folded into it. * * Enforced ONLY on CAPSULE_SIG_INVALID (2026-08-26, after landing * WARN-only and proving correct on all three architectures against both * a valid and a deliberately-corrupted capsule -- see FABRIC-3.md's * Milestone 6 writeup). CAPSULE_SIG_MISSING and CAPSULE_SIG_NO_ROOT_KEY * stay WARN-only, deliberately: MISSING is the normal state on every * machine without access to the offline signing key (CI, any other * checkout) -- refusing on it would brick boot everywhere but the one * machine that minted the key, not catch anything real. Only INVALID * (a signature that IS present but does not verify) is unambiguous * tampering/corruption evidence, safe to refuse on regardless of who's * building. */ #ifndef STARKERNEL_CAPSULE_SIG_H #define STARKERNEL_CAPSULE_SIG_H #include "starkernel/capsule.h" typedef enum { CAPSULE_SIG_OK = 0, /* has_sig=1, and it verifies */ CAPSULE_SIG_MISSING, /* has_sig=0 -- not signed at all */ CAPSULE_SIG_INVALID, /* has_sig=1 but verification failed */ CAPSULE_SIG_NO_ROOT_KEY, /* couldn't find/parse the embedded intermediate cert */ } CapsuleSigResult; /* * Verify capsule descs[index]'s Ed25519 signature against the embedded * snakeoil intermediate cert's public key (capsule name * "pki:snakeoil-intermediate.der", found and parsed once, cached for * every later call this boot -- the cert doesn't change mid-boot). * * descs/names/sigs must be the same three parallel arrays * (capsule_get_descriptors()/capsule_get_names()/capsule_get_signatures()), * desc_count their shared length, arena_base the payload arena * (capsule_get_arena()). index must be < desc_count. */ CapsuleSigResult capsule_verify_signature( const CapsuleDesc *descs, const CapsuleNameEntry *names, const CapsuleSigEntry *sigs, const uint8_t *arena_base, uint32_t desc_count, int index); /* Human-readable string for logging, mirroring * capsule_validate_result_str()'s existing shape. */ const char *capsule_sig_result_str(CapsuleSigResult result); #endif /* STARKERNEL_CAPSULE_SIG_H */