/* * user_identity_seed.h -- on-disk record format for a minted user * identity's own keypair and profile (FABRIC-3.md §F.8/§F.20), stored in * the first devblock of a home-blocks drive's identity_src region * (homeblocks_sig_t.identity_src_offset). The devblocks that follow it * (identity_src_offset+1 .. identity_src_offset+identity_src_devblocks-1) * hold this identity's own raw FORTH personality/init source, read by * RUNCAP (capsule_runcap.h) at birth. * * Same raw-devblock, magic+version+fields+pad-to-4096, real-CRC-from- * day-one convention as zuse_cert_devblock_t (zuse_cert_devblock.h) and * homeblocks_sig_t -- a new, dedicated type rather than reusing * zuse_cert_devblock_t, per this project's "give real-shaped data its * own header" convention (Zuse's own record has no analogous public * cert field; a regular user's does, stored separately in the cert * region MINT also writes -- see homeblocks_sig_t.cert_offset). * * full_name/username/email/phone (added §F.20, 2026-08-28): deliberately * NOT encoded into the DER cert's Subject field -- that would mean * building a real X.509 RDNSequence (AttributeTypeAndValue, OIDs for * commonName/emailAddress, PrintableString/UTF8String tagging), well * past this project's own stated "deliberately NOT a general ASN.1/X.509 * parser [or builder]" scope (x509_ed25519.h). This human-readable * profile data isn't security-relevant the way pubkey/serial are (those * two alone are what CERTVERIFY/BINDSTEP actually check) -- it travels * alongside the keypair in this plain record instead. email/phone are * nullable (empty string, first byte 0x00); full_name/username are not. */ #ifndef STARKERNEL_USER_IDENTITY_SEED_H #define STARKERNEL_USER_IDENTITY_SEED_H #include #define USER_IDENTITY_SEED_MAGIC \ ((uint32_t)'U' | ((uint32_t)'I' << 8) | ((uint32_t)'D' << 16) | ((uint32_t)'S' << 24)) #define USER_IDENTITY_SEED_VERSION 2u #define USER_IDENTITY_FULL_NAME_MAX 64u #define USER_IDENTITY_USERNAME_MAX 32u #define USER_IDENTITY_EMAIL_MAX 64u #define USER_IDENTITY_PHONE_MAX 24u typedef struct { uint32_t magic; /* USER_IDENTITY_SEED_MAGIC; anything else means * "not yet minted" (blank/foreign bytes), not a * format-corruption error. */ uint32_t version; /* USER_IDENTITY_SEED_VERSION */ uint8_t seed[32]; /* Ed25519 seed -- this identity's own private key. * Regular users are thumbdrive-resident (unlike * Zuse's system-resident one) -- this is the * only copy. */ uint8_t pubkey[32]; /* Ed25519 public key derived from seed at mint * time -- same value the cert region's * SubjectPublicKeyInfo holds. */ char full_name[USER_IDENTITY_FULL_NAME_MAX]; /* NUL-terminated, required. */ char username[USER_IDENTITY_USERNAME_MAX]; /* NUL-terminated, required. */ char email[USER_IDENTITY_EMAIL_MAX]; /* NUL-terminated; empty = null. */ char phone[USER_IDENTITY_PHONE_MAX]; /* NUL-terminated; empty = null. */ 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 + 32 + 32 + USER_IDENTITY_FULL_NAME_MAX + USER_IDENTITY_USERNAME_MAX + USER_IDENTITY_EMAIL_MAX + USER_IDENTITY_PHONE_MAX + 8)]; } user_identity_seed_t; typedef char user_identity_seed_size_check[ (sizeof(user_identity_seed_t) == 4096) ? 1 : -1]; #endif /* STARKERNEL_USER_IDENTITY_SEED_H */