Files
quicproquo/docs/src/security/audit-scope.md
Christian Nennemann 266bcfed59 docs: add threat model, crypto boundaries, and audit scope documents
Security audit preparation:
- Threat model with STRIDE analysis and 5 threat actors
- Crypto boundaries documenting all 11 primitives and key lifecycle
- Audit scope document for external security firms
2026-03-21 19:14:07 +01:00

8.3 KiB

Security Audit Scope

Project Summary

quicprochat is a production-grade end-to-end encrypted group messenger implemented in Rust. It uses MLS (RFC 9420) for group key agreement with a hybrid post-quantum KEM (X25519 + ML-KEM-768), OPAQUE for password-authenticated key exchange, and QUIC + TLS 1.3 as the transport layer. The project comprises approximately 38,000 lines of Rust across 9 workspace crates, with 300+ tests passing.

Scope

Primary Scope (Critical)

These components handle all cryptographic operations and should receive the deepest scrutiny.

quicprochat-core -- All Cryptographic Primitives

File Lines Responsibility
src/hybrid_kem.rs ~630 Hybrid X25519 + ML-KEM-768 KEM: key generation, encrypt/decrypt, encapsulate/decapsulate, HKDF key derivation
src/hybrid_crypto.rs ~540 OpenMLS OpenMlsCrypto + OpenMlsProvider implementation with hybrid HPKE routing
src/identity.rs ~250 Ed25519 identity keypair: generation, signing, verification, zeroization
src/group.rs ~1080 MLS group state machine: create, join, add/remove members, send/receive, epoch management
src/keypackage.rs ~100 MLS KeyPackage generation with hybrid init keys
src/keystore.rs ~710 Disk-backed OpenMLS key store with file permission restrictions
src/sealed_sender.rs ~160 Sender identity + Ed25519 signature envelope inside MLS payload
src/pq_noise.rs ~690 Post-quantum Noise_XX handshake with ML-KEM-768 mixing
src/opaque_auth.rs ~20 OPAQUE cipher suite definition (Ristretto255, Triple-DH, Argon2id)
src/recovery.rs ~340 Recovery code generation, Argon2id key derivation, encrypted backup bundles
src/padding.rs ~270 Message padding to fixed buckets + uniform boundary padding
src/safety_numbers.rs ~80 Signal-style safety number computation
src/transcript.rs ~400 Encrypted hash-chained transcript archive

quicprochat-server/src/domain/auth.rs -- OPAQUE Server Logic

File Lines Responsibility
src/domain/auth.rs ~170 OPAQUE registration (start/finish), session token validation, expiry cleanup

Secondary Scope (Important)

These components handle transport security and trust anchors. They are lower risk than the primary scope but still security-relevant.

quicprochat-rpc -- RPC Transport Security

File Lines Responsibility
src/framing.rs ~200 Wire format encoding/decoding, payload size limits (4 MiB max)
src/auth_handshake.rs ~80 Session token exchange over QUIC bi-stream
src/server.rs ~300 QUIC server setup, TLS configuration, connection handling
src/middleware.rs ~200 Tower middleware: rate limiting, timeouts

quicprochat-kt -- Key Transparency

File Lines Responsibility
src/lib.rs ~65 Merkle log hash functions (leaf_hash, node_hash) with RFC 6962 domain separation
src/tree.rs ~150 Append-only Merkle tree (insert, root computation)
src/proof.rs ~100 Inclusion proof generation and verification
src/revocation.rs ~100 Key revocation log with reason codes

quicprochat-server -- Security-Relevant Server Components

File Lines Responsibility
src/domain/rate_limit.rs ~150 Per-client rate limiting
src/domain/traffic_resistance.rs ~100 Decoy traffic generation, timing jitter, payload padding
src/domain/moderation.rs ~100 Abuse prevention (report handling)
src/tls.rs ~100 TLS certificate loading and configuration

Out of Scope

The following components are explicitly excluded from the audit:

  • Client SDKs: quicprochat-sdk, Go/Python/TypeScript/WASM/FFI bindings (thin wrappers)
  • CLI/TUI client: quicprochat-client (user interface, no crypto logic)
  • Plugin API: quicprochat-plugin-api (#![no_std] C-ABI interface, no crypto)
  • P2P networking: quicprochat-p2p (iroh integration, feature-gated)
  • Proto definitions: quicprochat-proto (generated code, no security logic)
  • Documentation: mdBook sources, README, ROADMAP
  • CI/CD: GitHub Actions, Dockerfiles, justfile
  • Non-crypto server domain: user management, group metadata, blob storage, delivery routing

Specific Questions for Auditors

Hybrid KEM Construction

  1. Is the hybrid combiner HKDF-SHA256(salt, X25519_ss || ML-KEM_ss, info) a sound dual-PRF construction? Does it provide IND-CCA2 security assuming either component is secure?
  2. Is the nonce handling correct? The hybrid KEM uses random 12-byte nonces (not derived from HKDF). Is there a nonce collision risk at the expected message volume?
  3. Is the derive_from_ikm() construction (HKDF -> seeded StdRng -> key generation) suitable for deterministic key derivation in the MLS HPKE key schedule?

OpenMLS Integration

  1. Does the HybridCryptoProvider correctly satisfy the OpenMlsProvider trait contract? Are there edge cases where hybrid key detection by length could fail or be spoofed?
  2. Is the DiskKeyStore implementation (wrapping MemoryStorage with disk flush) safe for concurrent access? Could a crash between MemoryStorage update and disk flush cause key loss?
  3. Is the MLS group lifecycle (create, add_member with merge_pending_commit, join_group via StagedWelcome) correctly implemented? Are there state consistency issues after failed operations?

Timing Side-Channels

  1. Are there timing side-channels in the OPAQUE registration/login flow? The opaque-ke crate uses Ristretto255 (constant-time), but is the surrounding code (deserialization, error handling) timing-safe?
  2. Is constant_time_eq() in recovery.rs correctly implemented? The early return on length mismatch is intentional (lengths are not secret), but verify the XOR-accumulate loop.

Noise_XX + ML-KEM Layering

  1. Is the PQ Noise handshake (pq_noise.rs) sound? Specifically:
    • Is ML-KEM ciphertext placement in message 2 correct (after ee DH, before se DH)?
    • Is mix_key(mlkem_ss) the right integration point for the post-quantum shared secret?
    • Does ML-KEM implicit rejection (pseudorandom wrong shared secret) cause any subtle failures beyond AEAD decryption error?

Zeroization

  1. Is zeroization complete? Specifically:
    • x25519_dalek::StaticSecret does not publicly implement Zeroize. Is the HybridKeypair struct's x25519_sk field securely erased on drop?
    • Are there intermediate buffers or stack copies of secret material that escape Zeroizing wrappers?
    • Does the DiskKeyStore flush-on-write pattern leave secret material in OS page cache or filesystem buffers?

Key Transparency

  1. Is the Merkle log construction (RFC 6962-style domain separation with 0x00/0x01 prefixes) resistant to second-preimage attacks?
  2. Could an adversarial server forge inclusion proofs for non-existent entries?

Access

  • Repository: git clone https://github.com/quicprochat/quicprochat
  • Build: cargo build --workspace (Rust 1.75+, no system dependencies -- protobuf-src vendors protoc)
  • Test: cargo test --workspace (300+ tests, runs in ~60s)
  • Lint: cargo clippy --workspace -- -D warnings
  • Documentation: cd docs && mdbook build

Key Entry Points

  • Crypto primitives: crates/quicprochat-core/src/
  • Server auth: crates/quicprochat-server/src/domain/auth.rs
  • RPC framing: crates/quicprochat-rpc/src/framing.rs
  • Key transparency: crates/quicprochat-kt/src/

Timeline and Budget

Based on the scope (approximately 5,000 lines of security-critical Rust code in primary scope, plus ~1,000 lines in secondary scope), we recommend:

  • Duration: 4-6 weeks (2 auditors)
  • Budget range: $80,000 - $150,000
  • Firm type: Specialized cryptography audit firm (e.g., NCC Group Cryptography Services, Trail of Bits, Cure53, Quarkslab)

Suggested Audit Phases

  1. Week 1-2: Hybrid KEM construction review, HKDF key derivation, zeroization audit
  2. Week 2-3: OpenMLS integration, MLS group lifecycle, KeyPackage handling
  3. Week 3-4: OPAQUE integration, PQ Noise handshake, timing analysis
  4. Week 4-5: Key Transparency Merkle log, transport security (RPC framing)
  5. Week 5-6: Report writing, finding triage, remediation discussion