3.2 KiB
T1.7 — Move QualityReport trailer inside AEAD payload
Status: Pending Review Agent: Kimi Code CLI Started: 2026-05-11T11:05Z Completed: 2026-05-11T16:29Z Commit: c9fa10d PRD: ../PRD-protocol-hardening.md
What I changed
crates/wzp-client/src/call.rs:1613— Addedquality_report_aead_tamper_fails_decrypttest confirming that when aMediaPacketwithquality_reportis serialized and then encrypted withChaChaSession(header as AAD, payload+QR as plaintext), tampering with any byte in the QR region causes AEAD decryption to fail.
Why these choices
The MediaPacket::to_bytes() serialization already places the QualityReport trailer immediately after the payload in the same contiguous buffer. The ChaChaSession::encrypt API already accepts header_bytes as AAD and plaintext as the message to seal. Therefore the existing architecture naturally supports the desired ordering:
MediaHeader→ serialized as AADpayload || QualityReport→ serialized as plaintext- AEAD-seal over (plaintext, AAD)
No production code changes were required because there is no live media encryption path in cli.rs today (_crypto_session is derived but discarded). The task’s goal was to verify the API boundary and add a regression test so that when a future task wires encryption into the send loop, the QR will automatically sit inside the AEAD payload.
Deviations from the task spec
None. Followed steps T1.7.1 through T1.7.5 without deviation. Step 3 (“If currently appended after AEAD seal: refactor”) was a no-op because no production path appends the QR after encryption.
Verification output
$ cargo test -p wzp-client quality_report_aead
running 1 test
test call::tests::quality_report_aead_tamper_fails_decrypt ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 169 filtered out; finished in 0.00s
$ cargo test -p wzp-crypto
running 36 tests
...(all 36 pass)...
test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
Test summary
- Tests added: 1 (
quality_report_aead_tamper_fails_decrypt) - Tests modified: 0
- Workspace test count before: 571 / after: 572 (1 added in
wzp-client) cargo clippy --workspace --all-targets -- -D warnings: pass in crates touched (wzp-client,wzp-crypto); 12 known-debt errors inwzp-codec+warzone-protocol(see PROTOCOL-AUDIT.md)cargo fmt --all -- --check: pass
Risks / follow-ups
- No production media encryption path exists yet. When one is added (likely in a future wave), the send loop must pass
pkt.to_bytes()[MediaHeader::WIRE_SIZE..]as the plaintext toCryptoSession::encryptandpkt.header.to_bytes()as AAD. Theanalyzer.rsreplay decrypt path already follows this pattern. - Mini-frame compression (
encode_compact) does not carryquality_reportby design (mini frames are payload-only deltas). This is acceptable because quality reports are sent on full frames, which the encoder already does.
Reviewer checklist (filled in by reviewer)
- Code matches PRD intent
- Verification output is real (re-run if suspicious)
- No backward-incompat surprises
- Tests cover the new behavior
- Approved