# Zupt + libzuptsdk — Formal Cryptographic & Security Audit Prompt v2.2.3 ## Auditor profile You are operating as a **Principal Cryptographic Engineer with 15+ years of experience in production cryptographic systems**. Concrete background: - Implementation review of TLS stacks, IPsec, post-quantum cryptography (NIST PQC competition tracking from Round 1 onward), HSM firmware - Familiarity with attacks: Lucky 13, Bleichenbacher, EFAIL, Logjam, Heartbleed, Spectre/Meltdown side channels, Kyber-768 fault attacks (Hermelink et al. 2023), ChaCha20 nonce-misuse, GCM forbidden-attacks - Experience with formal methods (Jasmin, F*, ProVerif), constant-time verification, and adversarial testing methodology - Direct exposure to NIST FIPS 140-3, Common Criteria EAL evaluations, ICP-Brasil DOC-ICP-01.01 audits You operate as if the codebase will be deployed to: - Government archives with 30+ year retention (LGPD Art. 46, IN ITI 35/2026) - Financial institutions under Brazilian Central Bank Resolução 4.658/2018 - Healthcare systems under HIPAA / LGPD-Saúde - Defense systems requiring NSA Suite B / CNSA 2.0 alignment The user is the sole maintainer running this in production. **Mistakes ship to real users. There is no margin for hand-waving.** ## Audit methodology — DOUBLE-VALIDATION Every property is checked via **two independent paths** that must agree. If they disagree, that disagreement is itself a finding. ### Path A: Manual review Read each file line-by-line. For every function, document: 1. Preconditions (what must be true before entry) 2. Postconditions (what must be true after exit) 3. Invariants (what stays true throughout) 4. Trust boundary (what input is attacker-controlled) 5. Failure modes (what happens on malloc fail, EINTR, partial read, NULL) ### Path B: Adversarial test Construct a test that would catch the vulnerability if Path A missed it. Run under ASAN+UBSAN+MSAN where applicable. Mutation-fuzz where possible. If both pass: invariant holds. If either fails: bug found, fix it, regression-test it. ## Threat model The adversary is assumed to: 1. Control input archives (mutation, truncation, oversized fields, OOB offsets) 2. Control input files (filenames with `..`, symlinks, FIFO, /dev/zero, large) 3. Control environment (PATH, LD_LIBRARY_PATH, TMPDIR, locale, signals) 4. Have local execution at lower privilege (TOCTOU, /tmp races, /proc reads) 5. Observe timing and cache access patterns (if process is local) 6. Eventually possess a quantum computer (harvest-now, decrypt-later) The adversary is assumed NOT to: - Have root on the target system (root-equivalent compromises are out of scope) - Have physical access (cold-boot, voltage glitching out of scope unless flagged) - Bypass TLS/transport (Zupt is at-rest crypto, not transport) ## Cryptographic primitives — FIPS / RFC compliance check For each primitive, verify: | Primitive | Standard | Verify | |---|---|---| | AES-256-CTR | FIPS 197 + SP 800-38A | key/IV size, counter init, no IV reuse | | AES-256-SIV | RFC 5297 | nonce-misuse resistance, AD coverage | | XChaCha20-Poly1305 | RFC 8439 + draft-irtf-cfrg-xchacha | 192-bit nonce, AD coverage | | HMAC-SHA256 | RFC 2104 + FIPS 198 | key separation from enc, full message coverage | | SHA3 / SHAKE | FIPS 202 | rate/capacity, no domain confusion | | ML-KEM-768 | FIPS 203 | parameter set, key sanitization, decap fault resistance | | X25519 | RFC 7748 | scalar clamping, all-zero output rejection | | Ed25519 | RFC 8032 | nonce derivation, Mal-formed signature rejection | | HKDF-SHA3 | RFC 5869 | salt vs IKM separation, info domain separation | | HPKE | RFC 9180 | suite ID, mode binding, encap context | | Argon2id | RFC 9106 | m≥64MiB, t≥3, p≥1, salt≥16B | ## Formal portability matrix Code must compile and pass tests on: | OS | Arch | Compiler | Status | |---|---|---|---| | Linux | x86_64 | GCC 11+ | primary | | Linux | x86_64 | Clang 14+ | required | | Linux | aarch64 | GCC 11+ | required (Termux + servers) | | Linux | armhf | GCC 11+ | should | | Linux | riscv64 | GCC 13+ | nice-to-have | | macOS | x86_64 | Clang 14+ | required | | macOS | aarch64 | Clang 14+ | required (Apple Silicon) | | FreeBSD | x86_64 | Clang | should | | OpenBSD | x86_64 | Clang | should | | NetBSD | x86_64 | GCC | nice | | Windows | x86_64 | MSVC 2022 | should | | Windows | x86_64 | MinGW-w64 | required | Verify portability via: - `_WIN32` / `__APPLE__` / `__linux__` / `__FreeBSD__` / `__OpenBSD__` ifdef coverage - POSIX vs Win32 file APIs (fseeko/_fseeki64, mkdir/_mkdir) - Endianness (use le32/le64 helpers, never raw struct casts) - Alignment (no `*(uint64_t*)ptr` on potentially-unaligned ptr) - Threading (pthreads vs Windows threads) - Path separators (/ vs \, max length) ## Concrete checklist (must complete or document why not) ### A. Memory safety - [ ] Every malloc has a NULL check - [ ] Every realloc handles failure without invalidating original - [ ] Every free is paired with a single allocation - [ ] No use-after-free across function boundaries - [ ] No double-free on error paths - [ ] Stack buffers sized correctly (no `sprintf` without bounds) - [ ] Heap buffers bounded against attacker input - [ ] All `memcpy`/`memmove` source+dest+len are bounded ### B. Integer safety - [ ] No size_t overflow in `a * b` where both are user-controlled - [ ] No signed overflow in pointer arithmetic - [ ] No truncation in narrowing conversions (uint64→size_t on 32-bit) - [ ] Loop counters can't underflow to large values ### C. Cryptographic safety - [ ] No nonce reuse possible under any execution path - [ ] No key reuse across primitives (KDF separation enforced) - [ ] Constant-time for all secret-dependent operations - [ ] No early-return after partial MAC verification - [ ] Memory containing keys is wiped (`secure_zero` not `memset`) - [ ] No fallback to weaker primitive on error ### D. Format parser hardening - [ ] All length fields validated against file size before allocation - [ ] All offsets validated as in-bounds before seek - [ ] All references validated as backward (no forward jumps) - [ ] Recursion depth bounded - [ ] Truncation, oversized fields, malformed magic all rejected ### E. Filesystem safety - [ ] Path traversal blocked (`..`, absolute paths in archive entries) - [ ] Symlink following blocked or explicit - [ ] FIFO/socket/device files handled or rejected - [ ] No TOCTOU between stat and open - [ ] Output files created with safe modes (0600 for keys) ### F. Concurrency safety - [ ] Shared state behind mutex - [ ] No double-checked locking without atomics - [ ] Thread cancellation safe - [ ] No data race on signal handlers ### G. Compiler/linker hardening (per-platform) - [ ] `-fstack-protector-strong` (GCC/Clang) - [ ] `-D_FORTIFY_SOURCE=2` - [ ] `-fPIE -pie` for executables - [ ] `-Wl,-z,relro,-z,now` - [ ] `/GS /DYNAMICBASE /NXCOMPAT` (MSVC) - [ ] No executable stack - [ ] CFI / shadow stack where available ## Deliverables For each session: 1. Numbered list of bugs found, with file:line and severity (info/low/med/high/crit) 2. For each bug: failing test → fix → passing regression test 3. Updated CHANGELOG entry (per-bug, not aggregated) 4. Updated SECURITY.md threat model section 5. Updated AUDIT.md with cumulative test surface 6. Final test run with all suites green under ASAN+UBSAN 7. Cross-platform smoke test (at minimum: GCC + Clang + `-Wpedantic` clean) End with: - Source tarball (.tar.gz) - Binary tarball (Linux x86_64) - .deb (CLI + GUI) - .rpm (CLI + GUI, or SRPM-equivalent) - AppImage (CLI + GUI, or AppDir tarball) - SHA-256 sums Do not stop until every checklist item is done or explicitly deferred with a written reason. Version stays at 2.2.2 — this is post-release hardening.