/* meow_sig.h — .mpk 签名块格式(MPK_SIGNATURE_DESIGN §3.1)+ 被签消息构造(§3.1)。 * * .mpk = [ tar.gz bytes ......................... ] [ meow_sig_block(定长 LE)] * * meow_sig_block(packed,总长 MEOW_SIG_BLOCK_LEN): * char magic[8]; "MEOWSIG1" * uint8_t alg; 1 = ed25519 * uint8_t flags; 0 * uint16_t pad; (0) * char package[64]; 权威包名(== app.json.package == 文件名茎) * uint8_t payload_sha256[32];sha256(整个 .mpk 去掉尾部 footer 的其余字节) * uint8_t sig[64]; Ed25519(pk, msg) * uint32_t msg_len; 实际签名的 msg 字节数(LE) * uint32_t block_len; 本块总长(LE;= MEOW_SIG_BLOCK_LEN) * * 被签消息 msg = "MEOWSIG1" || alg(1B) || package_len(4B,LE) || package || payload_sha256(32B)。 * 本文件由 meow_verify 与 meow_sign 共用(meow_sign 用相对路径 include)。 */ #ifndef MEOW_SIG_H #define MEOW_SIG_H #include #include #define MEOW_SIG_MAGIC "MEOWSIG1" #define MEOW_SIG_MAGIC_LEN 8 #define MEOW_SIG_ALG_ED25519 1 #define MEOW_SIG_PKG_MAX 64 #define MEOW_SIG_SHA256_LEN 32 #define MEOW_SIG_SIG_LEN 64 typedef struct __attribute__((packed)) { uint8_t magic[MEOW_SIG_MAGIC_LEN]; uint8_t alg; uint8_t flags; uint16_t pad; char package[MEOW_SIG_PKG_MAX]; uint8_t payload_sha256[MEOW_SIG_SHA256_LEN]; uint8_t sig[MEOW_SIG_SIG_LEN]; uint32_t msg_len; uint32_t block_len; } meow_sig_block_t; #define MEOW_SIG_BLOCK_LEN (sizeof(meow_sig_block_t)) /* 定长 180 */ /* 按字节读取 LE 的 uint32(避免 packed 解引用对齐告警) */ static inline uint32_t meow_le32(const uint8_t *p) { return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); } static inline void meow_le32_put(uint8_t *p, uint32_t v) { p[0] = (uint8_t)(v & 0xff); p[1] = (uint8_t)((v >> 8) & 0xff); p[2] = (uint8_t)((v >> 16) & 0xff); p[3] = (uint8_t)((v >> 24) & 0xff); } #define MEOW_SIG_MSG_MAX (MEOW_SIG_MAGIC_LEN + 1 + 4 + MEOW_SIG_PKG_MAX + MEOW_SIG_SHA256_LEN) /* 按设计构造被签消息 msg = "MEOWSIG1" || alg(1B) || package_len(4B,LE) || package || payload_sha256(32B)。 * 返回 msg 字节数。签名端与验签端必须用同一构造(meow_sign / meow_verify 共用)。 */ static inline unsigned meow_sig_msg_build(char *out, const char *package, const uint8_t payload_sha256[MEOW_SIG_SHA256_LEN]) { unsigned pkg_len = (unsigned)strlen(package); if (pkg_len > MEOW_SIG_PKG_MAX) pkg_len = MEOW_SIG_PKG_MAX; unsigned o = 0; memcpy(out + o, MEOW_SIG_MAGIC, MEOW_SIG_MAGIC_LEN); o += MEOW_SIG_MAGIC_LEN; out[o++] = MEOW_SIG_ALG_ED25519; meow_le32_put((uint8_t *)out + o, (uint32_t)pkg_len); o += 4; memcpy(out + o, package, pkg_len); o += pkg_len; memcpy(out + o, payload_sha256, MEOW_SIG_SHA256_LEN); o += MEOW_SIG_SHA256_LEN; return o; } #endif /* MEOW_SIG_H */