7.6 KiB
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:
- Preconditions (what must be true before entry)
- Postconditions (what must be true after exit)
- Invariants (what stays true throughout)
- Trust boundary (what input is attacker-controlled)
- 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:
- Control input archives (mutation, truncation, oversized fields, OOB offsets)
- Control input files (filenames with
.., symlinks, FIFO, /dev/zero, large) - Control environment (PATH, LD_LIBRARY_PATH, TMPDIR, locale, signals)
- Have local execution at lower privilege (TOCTOU, /tmp races, /proc reads)
- Observe timing and cache access patterns (if process is local)
- 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*)ptron 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
sprintfwithout bounds) - Heap buffers bounded against attacker input
- All
memcpy/memmovesource+dest+len are bounded
B. Integer safety
- No size_t overflow in
a * bwhere 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_zeronotmemset) - 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 -piefor executables-Wl,-z,relro,-z,now/GS /DYNAMICBASE /NXCOMPAT(MSVC)- No executable stack
- CFI / shadow stack where available
Deliverables
For each session:
- Numbered list of bugs found, with file:line and severity (info/low/med/high/crit)
- For each bug: failing test → fix → passing regression test
- Updated CHANGELOG entry (per-bug, not aggregated)
- Updated SECURITY.md threat model section
- Updated AUDIT.md with cumulative test surface
- Final test run with all suites green under ASAN+UBSAN
- Cross-platform smoke test (at minimum: GCC + Clang +
-Wpedanticclean)
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.