Skip to content

Zeroize output buffers at the start of all _out functions (part of #16)#17

Closed
Quant-TheodoreFelix wants to merge 1 commit into
bcgit:release/0.1.2alphafrom
Quant-TheodoreFelix:qtf/0.1.2alpha-zeroize-out-buffers
Closed

Zeroize output buffers at the start of all _out functions (part of #16)#17
Quant-TheodoreFelix wants to merge 1 commit into
bcgit:release/0.1.2alphafrom
Quant-TheodoreFelix:qtf/0.1.2alpha-zeroize-out-buffers

Conversation

@Quant-TheodoreFelix

@Quant-TheodoreFelix Quant-TheodoreFelix commented Jun 9, 2026

Copy link
Copy Markdown

Summary

This zeroizes the caller-provided output buffer at the entry of every concrete function that writes into an output byte slice (the *_out family, the dispatch wrappers in the factory crate, and the constant-time copy helper in utils). Each such function now starts with out.fill(0) (or output.fill(0)) before it produces its result. 84 write sites in total.

Motivation (from the 0.1.2alpha TODO)

The TODO states: anywhere you have an _out(.. out: &mut [u8]), start by zeroizing it with .fill(0). Pre-zeroizing closes two leak paths:

  • An oversized output buffer keeps stale bytes past the digest/MAC length.
  • An early error return leaves partially written or stale data in the caller's buffer.

A representative change:

fn do_final_out(mut self, output: &mut [u8]) -> usize {
    output.fill(0);
    ...
}

Scope

sha2, sha3 (sha3 / shake / keccak), hmac, rng (hash_drbg), hex, base64, factory (hash / xof / mac / rng), utils/ct, and the PQ crates mlkem, mlkem_lowmemory, mldsa, mldsa_lowmemory (key-encode and sign paths).

Behavior change (please note)

Digest, MAC, XOF and RNG output functions now zero the tail of an oversized output buffer instead of leaving it untouched. One existing sha3 unit test (test_static_hash) asserted the old "does not touch the extra bytes" contract and was updated to assert the new zeroed-tail contract. The shared core-test-framework hash and mac tests already use zero-initialized buffers and expect zeroed tails, so they were unaffected.

Deliberately excluded

The row-wise partial writers in mlkem_lowmemory (pack_t_hat_row, pack_s_hat_row, compress_u_row) were NOT changed. They write a sub-slice of a shared buffer that already holds other rows, so a blanket fill(0) would erase previously written data and corrupt the output. Trait declarations (no body), unimplemented!() stubs, and KeyMaterialTrait-typed outputs (zeroized transitively through the byte-slice writers) were left as-is.

Merge conflict warning

This PR modifies crypto/rng/src/hash_drbg80090a.rs (generate_out, next_bytes_out, hash_df, hashgen). PR #16 also touches that file, so expect a conflict when folding this into the roundup branch.

Verification

cargo build            # clean across the workspace
cargo test --workspace # 326 passed, 0 failed

The test run includes the ML-KEM / ML-DSA wycheproof KATs, which exercise the modified key-encode and sign paths.

Relationship

Part of #16. Intended to be folded into the 0.1.2alpha TODO roundup.

- 출력 슬라이스를 받는 _out 계열 함수 진입부에서 out fill(0) 선-초기화
- 오버사이즈 버퍼 뒤쪽이나 조기 반환 시 남는 이전 데이터 노출 방지
- digest 출력 버퍼 뒤쪽까지 0이 되도록 sha3 테스트 1건 갱신
- 행 단위 부분 기록 함수는 다른 행을 지우므로 제외
@Quant-TheodoreFelix Quant-TheodoreFelix deleted the qtf/0.1.2alpha-zeroize-out-buffers branch June 9, 2026 05:52
@Quant-TheodoreFelix

Copy link
Copy Markdown
Author

Superseded by #18 (head branch renamed from qtf/0.1.2alpha-zeroize-out-buffers to qtfelix/0.1.2alpha-zeroize-out-buffers; the rename auto-closed this cross-fork PR). Same commit and contents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant