diff --git a/Makefile b/Makefile index 8069e83..4d7fbb6 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ ZUPT_SOURCES = src/zupt_main.c src/zupt_format.c src/zupt_lz.c src/zupt_lzh.c \ src/zupt_x25519.c src/zupt_mlkem.c src/zupt_cpuid.c src/zupt_mlock.c \ src/zupt_filetype.c src/zupt_disk.c src/zupt_dedup.c -# --- Optional vendored libraries (libzuptsdk + libpqvaptvupt) --- +# --- Optional vendored libraries (libvuptsdk + libpqvaptvupt) --- # # These are PREBUILT shared libraries shipped only as binaries (no source), so # they are NOT part of the source tree and a distro/source build must not need @@ -72,21 +72,38 @@ ZUPT_SOURCES = src/zupt_main.c src/zupt_format.c src/zupt_lz.c src/zupt_lzh.c \ # ML-KEM-768 + X25519 via --pq). The SDK-backed modes (--pq-sdk, --pq-box, and # the Argon2id password KDF) compile to "unsupported" stubs in that case. # -# Set WITH_SDK=1 (with the vendored libs present under vendor/) to enable them. +# libvuptsdk is the renamed libzuptsdk (git.securityops.co/cristiancmoises/ +# libvuptsdk); only the .so filename/SONAME changed (libzuptsdk.so.2 -> +# libvuptsdk.so.2), the C API (zuptsdk_* symbols, zuptsdk.h) is unchanged. +# +# WITH_SDK=1 links libvuptsdk (--pq-sdk + Argon2id password KDF). WITH_PQBOX=1 +# links the SEPARATE libpqvaptvupt (--pq-box sealed box); it is independent of +# WITH_SDK because the two are different upstream libraries. Enable either or +# both, given the corresponding vendored .so is present. WITH_SDK ?= 0 ifeq ($(WITH_SDK),1) -ZUPTSDK_DIR ?= vendor/zuptsdk +ZUPTSDK_DIR ?= vendor/vuptsdk ZUPTSDK_ABS := $(abspath $(ZUPTSDK_DIR)) CFLAGS += -DZUPT_WITH_SDK -I$(ZUPTSDK_DIR)/include -PQVV_DIR ?= vendor/pqvaptvupt -CFLAGS += -I$(PQVV_DIR)/include LDFLAGS += -L$(ZUPTSDK_DIR) -Wl,-rpath,$(ZUPTSDK_ABS) -Wl,-rpath,'$$ORIGIN/$(ZUPTSDK_DIR)' -LDLIBS += -lzuptsdk -PQVV_ABS := $(abspath $(PQVV_DIR)) -LDFLAGS += -L$(PQVV_DIR) -Wl,-rpath,$(PQVV_ABS) -Wl,-rpath,'$$ORIGIN/$(PQVV_DIR)' +# libvuptsdk pulls in OpenSSL 3 (libcrypto) and Argon2; the final link must be +# able to resolve those transitive symbols. On a distro they are on the default +# library path; on Guix pass their -L via `guix shell openssl argon2`. Override +# SDK_DEPLIBS= if your SDK build has different runtime deps. +SDK_DEPLIBS ?= -lcrypto -largon2 +LDLIBS += -lvuptsdk $(SDK_DEPLIBS) # Installed layout: vendored libs live in $(PREFIX)/lib/$(TARGET)/ — give the # binary a matching relative rpath so `make install` is self-contained. LDFLAGS += -Wl,-rpath,'$$ORIGIN/../lib/vaptvupt' +endif + +WITH_PQBOX ?= 0 +ifeq ($(WITH_PQBOX),1) +PQVV_DIR ?= vendor/pqvaptvupt +PQVV_ABS := $(abspath $(PQVV_DIR)) +CFLAGS += -DZUPT_WITH_PQBOX -I$(PQVV_DIR)/include +LDFLAGS += -L$(PQVV_DIR) -Wl,-rpath,$(PQVV_ABS) -Wl,-rpath,'$$ORIGIN/$(PQVV_DIR)' +LDFLAGS += -Wl,-rpath,'$$ORIGIN/../lib/vaptvupt' LDLIBS += -lpqvaptvupt endif @@ -218,7 +235,7 @@ audit-licenses: -not -path './build/*' \ -not -path './build_obj/*' \ -not -path './sdk/build/*' \ - -not -path './vendor/zuptsdk/include/*'); do \ + -not -path './vendor/vuptsdk/include/*'); do \ BASE=$$(basename "$$f"); \ case "$$BASE" in \ vv_*|vaptvupt*) \ @@ -331,9 +348,12 @@ install: $(TARGET) # the source tree). ifeq ($(WITH_SDK),1) $(Q)mkdir -p $(DESTDIR)$(PREFIX)/lib/vaptvupt - $(Q)install -m 755 vendor/zuptsdk/libzuptsdk.so.2.0.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libzuptsdk.so.2.0.0 - $(Q)ln -sf libzuptsdk.so.2.0.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libzuptsdk.so.2 - $(Q)ln -sf libzuptsdk.so.2.0.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libzuptsdk.so + $(Q)install -m 755 vendor/vuptsdk/libvuptsdk.so.2.0.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libvuptsdk.so.2.0.0 + $(Q)ln -sf libvuptsdk.so.2.0.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libvuptsdk.so.2 + $(Q)ln -sf libvuptsdk.so.2.0.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libvuptsdk.so +endif +ifeq ($(WITH_PQBOX),1) + $(Q)mkdir -p $(DESTDIR)$(PREFIX)/lib/vaptvupt $(Q)install -m 755 vendor/pqvaptvupt/libpqvaptvupt.so.0.6.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libpqvaptvupt.so.0.6.0 $(Q)ln -sf libpqvaptvupt.so.0.6.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libpqvaptvupt.so.0 $(Q)ln -sf libpqvaptvupt.so.0.6.0 $(DESTDIR)$(PREFIX)/lib/vaptvupt/libpqvaptvupt.so diff --git a/gui/src/zupt_gui.py b/gui/src/zupt_gui.py index e3adc0b..fada5b3 100644 --- a/gui/src/zupt_gui.py +++ b/gui/src/zupt_gui.py @@ -194,7 +194,7 @@ ZUPT_VER_SHORT, ZUPT_VER_NUMBER, ZUPT_VER_FULL = _get_version() # ── Detect build capabilities from `version` (and `help` as fallback) ── # -# The default build is SOURCE-ONLY: the libzuptsdk-backed modes (Argon2id +# The default build is SOURCE-ONLY: the libvuptsdk-backed modes (Argon2id # KDF, --pq-sdk, --pq-box) are absent and fail with exit 1. Offering them in # the UI is the #1 reason "functions don't work". We detect what THIS binary # actually supports and build the encryption UI around it: @@ -212,7 +212,7 @@ def _get_caps(): for line in blob.splitlines(): low = line.lower() if low.startswith("build:"): - sdk = ("full" in low) and ("libzuptsdk" in low) + sdk = ("full" in low) and ("vuptsdk" in low) elif low.startswith("kdf:"): default_kdf = "Argon2id" if "argon2id (default)" in low else "PBKDF2-SHA256" if "--pq-only" in line: diff --git a/src/zupt_crypto_pqbox.c b/src/zupt_crypto_pqbox.c index c865782..395b2c4 100644 --- a/src/zupt_crypto_pqbox.c +++ b/src/zupt_crypto_pqbox.c @@ -33,7 +33,7 @@ */ #include "zupt.h" -#ifdef ZUPT_WITH_SDK +#ifdef ZUPT_WITH_PQBOX #include "zupt_keccak.h" #include "pqvaptvupt.h" #include @@ -182,7 +182,7 @@ int zupt_pqbox_decrypt_init(zupt_keyring_t *kr, const char *privkeyfile, return 0; } -#else /* !ZUPT_WITH_SDK */ +#else /* !ZUPT_WITH_PQBOX */ /* Source-only build (no vendored libpqvaptvupt binary). The --pq-box sealed-box * mode is unavailable; use native --pq (ML-KEM-768 + X25519) instead, or rebuild @@ -212,4 +212,4 @@ int zupt_pqbox_decrypt_init(zupt_keyring_t *kr, const char *privkeyfile, return pqbox_unavailable("--pq-box decryption (this archive needs it)"); } -#endif /* ZUPT_WITH_SDK */ +#endif /* ZUPT_WITH_PQBOX */ diff --git a/src/zupt_main.c b/src/zupt_main.c index ed7f1b0..e93dcec 100644 --- a/src/zupt_main.c +++ b/src/zupt_main.c @@ -92,8 +92,8 @@ static void usage(void) { " --comment-file Read comment from file (max 4096 bytes).\n" " --pq Post-quantum HYBRID encryption (ML-KEM-768 + X25519) [recommended]\n" " --pq-only FULL post-quantum encryption (ML-KEM-768 only, no classical layer)\n" - " --pq-sdk Post-quantum encryption via libzuptsdk (WITH_SDK=1 builds only)\n" - " --pq-box Post-quantum sealed box via libpqvaptvupt (WITH_SDK=1 builds only)\n" + " --pq-sdk Post-quantum encryption via libvuptsdk (WITH_SDK=1 builds only)\n" + " --pq-box Post-quantum sealed box via libpqvaptvupt (WITH_PQBOX=1 builds only)\n" " --dedup, -D Block-level deduplication\n" " --solid Solid mode (single stream)\n" " -y, --force Overwrite an existing non-.zupt file as the output archive\n" @@ -108,7 +108,7 @@ static void usage(void) { " -p, --password Decryption password\n" " --pq Post-quantum HYBRID decryption (ML-KEM-768 + X25519)\n" " --pq-only FULL post-quantum decryption (ML-KEM-768 only)\n" - " --pq-sdk Post-quantum decryption via libzuptsdk (WITH_SDK=1 builds only)\n" + " --pq-sdk Post-quantum decryption via libvuptsdk (WITH_SDK=1 builds only)\n" " --pq-box Post-quantum sealed-box decryption (libpqvaptvupt)\n" " -v, --verbose Verbose output\n" " -t, --threads Thread count for decompression\n" @@ -119,8 +119,8 @@ static void usage(void) { " -k Source private keyfile (with --pub)\n" " (default) Generate HYBRID keypair (ML-KEM-768 + X25519) for --pq\n" " --pq-only Generate FULL post-quantum keypair (ML-KEM-768 only) for --pq-only\n" - " --sdk, --pq-sdk Generate SDK v2 keypair (libzuptsdk; WITH_SDK=1 builds only)\n" - " --box, --pq-box Generate pq-box keypair (libpqvaptvupt; WITH_SDK=1 builds only)\n" + " --sdk, --pq-sdk Generate SDK v2 keypair (libvuptsdk; WITH_SDK=1 builds only)\n" + " --box, --pq-box Generate pq-box keypair (libpqvaptvupt; WITH_PQBOX=1 builds only)\n" " Use each key with its matching mode.\n" "\n" "Directories are traversed recursively.\n" @@ -219,8 +219,16 @@ int main(int argc, char **argv) { "Encryption: AES-256-CTR + HMAC-SHA256\n" #ifdef ZUPT_WITH_SDK "KDF: Argon2id (default) / PBKDF2-SHA256 %d iter (--kdf pbkdf2)\n" - "Post-quantum: --pq hybrid (ML-KEM-768 + X25519), --pq-only (ML-KEM-768), --pq-sdk/--pq-box (libzuptsdk)\n" - "Build: full (libzuptsdk: Argon2id, --pq-sdk, --pq-box available)\n" + "Post-quantum: --pq hybrid (ML-KEM-768 + X25519), --pq-only (ML-KEM-768), --pq-sdk (libvuptsdk)" +#ifdef ZUPT_WITH_PQBOX + ", --pq-box (libpqvaptvupt)" +#endif + "\n" + "Build: full (libvuptsdk: Argon2id, --pq-sdk" +#ifdef ZUPT_WITH_PQBOX + ", --pq-box" +#endif + " available)\n" #else "KDF: PBKDF2-SHA256 %d iter (default; Argon2id needs WITH_SDK=1)\n" "Post-quantum: --pq hybrid (ML-KEM-768 + X25519), --pq-only (ML-KEM-768 only) — FIPS 203 + RFC 7748\n" @@ -976,7 +984,7 @@ int main(int argc, char **argv) { if (zupt_sdk_hybrid_keygen(outfile, pubfile) != 0) { fprintf(stderr, "Error: SDK-v2 key generation is unavailable in this build.\n" - " --pq-sdk needs libzuptsdk, which is not part of the source-only\n" + " --pq-sdk needs libvuptsdk, which is not part of the source-only\n" " build. For post-quantum keys use one of the native modes:\n" " vaptvupt keygen -o key # hybrid ML-KEM-768 + X25519 (--pq)\n" " vaptvupt keygen --pq-only -o key # full PQ, ML-KEM-768 only (--pq-only)\n" diff --git a/vendor/vuptsdk/include/vaptvupt.h b/vendor/vuptsdk/include/vaptvupt.h index 48b6d8d..340aa3f 100644 --- a/vendor/vuptsdk/include/vaptvupt.h +++ b/vendor/vuptsdk/include/vaptvupt.h @@ -2,7 +2,7 @@ * VaptVupt Codec — Next-generation lossless compression * Public API and data structures * - * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-License-Identifier: AGPL-3.0-or-later * Copyright 2026 Cristian. * Zero dependencies. Pure C11. */ diff --git a/vendor/vuptsdk/include/vaptvupt_api.h b/vendor/vuptsdk/include/vaptvupt_api.h index f19c85f..260f207 100644 --- a/vendor/vuptsdk/include/vaptvupt_api.h +++ b/vendor/vuptsdk/include/vaptvupt_api.h @@ -1,6 +1,6 @@ /* * VaptVupt — Zupt Integration API - * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-License-Identifier: AGPL-3.0-or-later * Copyright 2026 Cristian. * * ZUPT-COMPAT: This is the API that Zupt calls. It wraps the internal diff --git a/vendor/vuptsdk/include/vv_ans.h b/vendor/vuptsdk/include/vv_ans.h index 86f1f03..324c72e 100644 --- a/vendor/vuptsdk/include/vv_ans.h +++ b/vendor/vuptsdk/include/vv_ans.h @@ -1,5 +1,5 @@ /* - * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-License-Identifier: AGPL-3.0-or-later * * VaptVupt — tANS Entropy Codec (v2: sparse header + 4-way interleaved) * diff --git a/vendor/vuptsdk/include/vv_huffman.h b/vendor/vuptsdk/include/vv_huffman.h index dafdd1e..5ffdc56 100644 --- a/vendor/vuptsdk/include/vv_huffman.h +++ b/vendor/vuptsdk/include/vv_huffman.h @@ -1,5 +1,5 @@ /* - * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-License-Identifier: AGPL-3.0-or-later * * VaptVupt — Canonical Huffman Codec * diff --git a/vendor/vuptsdk/include/vv_platform.h b/vendor/vuptsdk/include/vv_platform.h index 45590f2..c4b1f78 100644 --- a/vendor/vuptsdk/include/vv_platform.h +++ b/vendor/vuptsdk/include/vv_platform.h @@ -4,7 +4,7 @@ * Provides unified abstractions for compiler intrinsics used throughout * the codebase. Supports GCC, Clang, MSVC, and Intel compilers. * - * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-License-Identifier: AGPL-3.0-or-later */ #ifndef VV_PLATFORM_H diff --git a/vendor/vuptsdk/include/zupt.h b/vendor/vuptsdk/include/zupt.h index a97cd6d..7ef31a1 100644 --- a/vendor/vuptsdk/include/zupt.h +++ b/vendor/vuptsdk/include/zupt.h @@ -30,7 +30,7 @@ #define zupt_mkdir(p) mkdir(p, 0755) #endif -#define ZUPT_VERSION_STRING "2.2.3" +#define ZUPT_VERSION_STRING "2.2.2" #define ZUPT_FORMAT_MAJOR 1 #define ZUPT_FORMAT_MINOR 4 @@ -62,8 +62,8 @@ /* Encryption types (stored in encryption header block) */ #define ZUPT_ENC_PBKDF2 0x01 /* Password-based: PBKDF2 → AES-256-CTR + HMAC */ #define ZUPT_ENC_PQ_HYBRID 0x02 /* ML-KEM-768 + X25519 hybrid KEM (legacy XOR+SHA3) */ -#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_SDK_V2 0x03 /* libvuptsdk v2 header: HKDF combiner + commitment + HPKE binding */ +#define ZUPT_ENC_PW_ARGON2 0x04 /* Password-based via libvuptsdk: Argon2id + XChaCha20-Poly1305 */ /* Block types */ #define ZUPT_BLOCK_DATA 0x00 @@ -173,7 +173,7 @@ typedef struct { int level; uint32_t block_size; uint16_t codec_id; int verbose, encrypt, quiet, solid, threads; int pq_mode; /* 1 = post-quantum hybrid KEM mode */ - int sdk_mode; /* 1 = use libzuptsdk-backed v3 crypto (HKDF combiner + commitment + HPKE) */ + int sdk_mode; /* 1 = use libvuptsdk-backed v3 crypto (HKDF combiner + commitment + HPKE) */ int dedup; /* 1 = block-level deduplication enabled */ char password[256]; char keyfile[ZUPT_MAX_PATH]; /* Path to .zupt-key file */ @@ -329,7 +329,7 @@ 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); -/* ─── SDK-backed crypto (zupt v2.2+, libzuptsdk under the hood) ─── */ +/* ─── SDK-backed crypto (zupt v2.2+, libvuptsdk 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, uint8_t *enc_hdr, size_t *enc_hdr_len); diff --git a/vendor/vuptsdk/include/zupt_mlkem.h b/vendor/vuptsdk/include/zupt_mlkem.h index d928916..1d8bb3d 100644 --- a/vendor/vuptsdk/include/zupt_mlkem.h +++ b/vendor/vuptsdk/include/zupt_mlkem.h @@ -21,6 +21,7 @@ #define ZUPT_MLKEM_H #include +#include #define MLKEM_K 3 #define MLKEM_N 256 @@ -46,7 +47,8 @@ int zupt_mlkem768_keygen(uint8_t pk[MLKEM_PUBLICKEYBYTES], * ct: output ciphertext (1088 bytes) * ss: output shared secret (32 bytes) * pk: input public key (1184 bytes) - * Returns 0 on success. */ + * Returns 0 on success, non-zero if pk fails the FIPS 203 §7.2 + * encapsulation-key modulus check (malformed key). */ int zupt_mlkem768_encaps(uint8_t ct[MLKEM_CIPHERTEXTBYTES], uint8_t ss[MLKEM_SSBYTES], const uint8_t pk[MLKEM_PUBLICKEYBYTES]); @@ -62,4 +64,14 @@ int zupt_mlkem768_decaps(uint8_t ss[MLKEM_SSBYTES], const uint8_t ct[MLKEM_CIPHERTEXTBYTES], const uint8_t sk[MLKEM_SECRETKEYBYTES]); +/* FIPS 203 §7.2 encapsulation-key check (modulus check). + * Returns 0 iff `ek` is `len`==1184 bytes and every 12-bit coefficient is + * reduced mod q. Non-zero => malformed key; do not encapsulate against it. */ +int zupt_mlkem768_check_ek(const uint8_t *ek, size_t len); + +/* FIPS 203 §7.3 decapsulation-key check (hash check). + * Returns 0 iff `dk` is `len`==2400 bytes and the embedded H(ek) matches the + * SHA3-256 of the embedded encapsulation key. Non-zero => corrupt/forged key. */ +int zupt_mlkem768_check_dk(const uint8_t *dk, size_t len); + #endif diff --git a/vendor/vuptsdk/include/zuptsdk.h b/vendor/vuptsdk/include/zuptsdk.h index f30ea6c..3704342 100644 --- a/vendor/vuptsdk/include/zuptsdk.h +++ b/vendor/vuptsdk/include/zuptsdk.h @@ -1,10 +1,10 @@ /* - * libzuptsdk — Public C ABI for the Zupt backup compression library + * libvuptsdk — Public C ABI for the Zupt backup compression library * * Copyright (c) 2026 Cristian Cezar Moisés * SPDX-License-Identifier: AGPL-3.0-or-later * - * Repository: https://git.securityops.co/cristiancmoises/zupt + * Repository: https://github.com/cristiancmoises/zupt * Website: https://zupt.securityops.co * Contact: zupt@riseup.net * @@ -15,7 +15,7 @@ * is gated behind the linker version tag ZUPTSDK_1.0. New symbols may be * added in minor versions (1.1, 1.2, ...) under new tags (ZUPTSDK_1.1, ...). * Existing symbols will never change signature within v1.x. Breaking - * changes require a major version bump (libzuptsdk.so.2). + * changes require a major version bump (libvuptsdk.so.2). * * No symbol prefixed with anything other than `zuptsdk_` or `ZUPTSDK_` is * part of this ABI. Do not link against internal `zupt_*` symbols even if diff --git a/vendor/vuptsdk/include/zuptsdk_easy.h b/vendor/vuptsdk/include/zuptsdk_easy.h index ff6d666..13d7577 100644 --- a/vendor/vuptsdk/include/zuptsdk_easy.h +++ b/vendor/vuptsdk/include/zuptsdk_easy.h @@ -1,5 +1,5 @@ /* - * zuptsdk easy.h — high-level API for drop-in encryption. + * vuptsdk easy.h — high-level API for drop-in encryption. * SPDX-License-Identifier: AGPL-3.0-or-later * * Goal: 3 lines of code to encrypt/decrypt anything in any language. diff --git a/vendor/vuptsdk/include/zuptsdk_metrics.h b/vendor/vuptsdk/include/zuptsdk_metrics.h index 66695a9..2df710c 100644 --- a/vendor/vuptsdk/include/zuptsdk_metrics.h +++ b/vendor/vuptsdk/include/zuptsdk_metrics.h @@ -1,4 +1,4 @@ -/* zuptsdk observability — metrics & structured logging hooks +/* vuptsdk observability — metrics & structured logging hooks * SPDX-License-Identifier: AGPL-3.0-or-later */ #ifndef ZUPTSDK_METRICS_H