v4.2.0: full (pure) post-quantum mode + critical dedup nonce fix
Add a native full post-quantum encryption mode and fix a critical keystream-reuse bug in deduplicated encrypted archives. Full post-quantum mode (--pq-only) - New envelope type 0x06 (ZUPT_ENC_PQ_ONLY): ML-KEM-768 (FIPS 203) as the sole key-establishment mechanism, with no classical X25519 component. Archive key = SHA3-512(ml_ss || ml_ct || "ZUPT-PQ-ONLY-v1"). - For compliance postures that require a single NIST-standardised PQ primitive with no classical KEM in the envelope (CNSA 2.0-style "PQ-only"). Hybrid --pq stays the recommended default; --pq-only has no classical fallback, so a break of ML-KEM-768 alone breaks it. - keygen --pq-only / keygen --pub --pq-only (ZPQK magic, 1200B pub / 3600B priv; not interchangeable with hybrid --pq keys). Wrong or tampered ciphertext is rejected via ML-KEM FO implicit rejection plus the HMAC-SHA256 Encrypt-then-MAC envelope. In-tree, default build. Security (critical): AES-256-CTR keystream reuse under --dedup - Dedup assigns block sequence 0 to every data block (the sentinel that keeps cross-file dedup references authenticating consistently). The per-block nonce was base_nonce XOR block_seq, so under --dedup every block collapsed to the same nonce, reusing the CTR keystream across distinct plaintexts (a many-time-pad). Each block now uses a fresh random 128-bit nonce stored in the block prefix and bound into the block MAC; block_seq is still bound as MAC AAD. Regression test: tests/test_dedup_nonce.sh. Re-encrypt any --dedup encrypted archives written by <= 4.1.0. Other - keygen --sdk / --box on a source-only build now fails with a clear message pointing to native --pq / --pq-only (or a WITH_SDK=1 build). - Documentation: README, SECURITY, THREAT_MODEL, man page, CHANGELOG, and all packaging recipes updated for the new mode and the security fix; version bumped to 4.2.0. Wire format v1.6 unchanged (0x06 is additive). Validation: make check 16/16, quick suite 11/11 (incl. PQ-only), dedup-nonce regression (all block nonces distinct), cppcheck clean.
This commit is contained in:
parent
31fa4028aa
commit
124958aea9
24 changed files with 811 additions and 123 deletions
|
|
@ -50,7 +50,7 @@
|
|||
#define ZUPT_PRODUCT_EXTENSION ".zupt" /* on-disk archive extension (kept stable) */
|
||||
#define ZUPT_PRODUCT_TAGLINE "Post-quantum backup compression"
|
||||
|
||||
#define ZUPT_VERSION_STRING "4.1.0"
|
||||
#define ZUPT_VERSION_STRING "4.2.0"
|
||||
/* Vendored codec release (upstream tag) — single source for display strings.
|
||||
* The codec's own VV_VERSION_* is its internal API version, not the release. */
|
||||
#define ZUPT_CODEC_RELEASE "2.60.4"
|
||||
|
|
@ -104,6 +104,7 @@
|
|||
#define ZUPT_ENC_PQ_SDK_V2 0x03 /* libzuptsdk v2 header: HKDF combiner + commitment + HPKE binding */
|
||||
#define ZUPT_ENC_PW_ARGON2 0x04 /* Password-based via libzuptsdk: Argon2id + XChaCha20-Poly1305 */
|
||||
#define ZUPT_ENC_PQ_BOX_V1 0x05 /* libpqvaptvupt sealed box: HKDF-SHA256 domain-separated combiner */
|
||||
#define ZUPT_ENC_PQ_ONLY 0x06 /* Full post-quantum: ML-KEM-768 only (no X25519), SHA3-512 KDF (v4.2.0) */
|
||||
|
||||
/* Argon2id KDF profile descriptor (v3.4.0).
|
||||
*
|
||||
|
|
@ -271,6 +272,7 @@ typedef struct {
|
|||
int pq_mode; /* 1 = post-quantum hybrid KEM mode */
|
||||
int sdk_mode; /* 1 = use libzuptsdk-backed v3 crypto (HKDF combiner + commitment + HPKE) */
|
||||
int box_mode; /* 1 = libpqvaptvupt sealed-box mode (ZUPT_ENC_PQ_BOX_V1) */
|
||||
int pqonly_mode; /* 1 = full post-quantum mode: ML-KEM-768 only (ZUPT_ENC_PQ_ONLY) */
|
||||
int dedup; /* 1 = block-level deduplication enabled */
|
||||
int kdf_legacy_pbkdf2; /* v2.4.1: 1 = force PBKDF2-SHA256 enc-header (compat with v2.4.0 and older readers). Default 0 = Argon2id. */
|
||||
char password[256];
|
||||
|
|
@ -484,6 +486,14 @@ int zupt_hybrid_encrypt_init(zupt_keyring_t *kr, const char *pubkeyfile,
|
|||
int zupt_hybrid_decrypt_init(zupt_keyring_t *kr, const char *privkeyfile,
|
||||
const uint8_t *enc_hdr, size_t enc_hdr_len);
|
||||
|
||||
/* ─── Full post-quantum crypto: ML-KEM-768 only, no X25519 (v4.2.0) ─── */
|
||||
int zupt_pq_keygen(const char *keyfile);
|
||||
int zupt_pq_export_pubkey(const char *privfile, const char *pubfile);
|
||||
int zupt_pq_encrypt_init(zupt_keyring_t *kr, const char *pubkeyfile,
|
||||
uint8_t *enc_hdr, size_t *enc_hdr_len);
|
||||
int zupt_pq_decrypt_init(zupt_keyring_t *kr, const char *privkeyfile,
|
||||
const uint8_t *enc_hdr, size_t enc_hdr_len);
|
||||
|
||||
/* ─── SDK-backed crypto (zupt v2.2+, libzuptsdk under the hood) ─── */
|
||||
int zupt_sdk_hybrid_keygen(const char *privkeyfile, const char *pubkeyfile);
|
||||
int zupt_sdk_hybrid_encrypt_init(zupt_keyring_t *kr, const char *pubkeyfile,
|
||||
|
|
|
|||
Loading…
Reference in a new issue