Skip to content

sha-crypt: add zeroize feature - #955

Closed
nicopauss wants to merge 1 commit into
RustCrypto:masterfrom
nicopauss:sha-crypt-zeroize
Closed

nicopauss wants to merge 1 commit into
RustCrypto:masterfrom
nicopauss:sha-crypt-zeroize

Conversation

@nicopauss

Copy link
Copy Markdown

sha256_crypt() and sha512_crypt() leave intermediate digests derived from the password on the stack: the digests A, B, DP and DS, and the hash of each round before it is copied out. Some certifications, such as Common Criteria FDP_RIP.2 (residual information protection), require that a password hasher clears such data. We want to replace our C SHA-crypt with this crate, and this is the only blocker.

This PR adds an optional zeroize feature:

  • It clears the intermediate digests before the functions return.
  • It enables sha2/zeroize, so the hasher states clear themselves on drop. argon2 does the same for blake2 (argon2: pass zeroize along to blake2 #932).
  • The rounds now finalize in place with finalize_into(), so no temporary copy of a digest is left behind.

Without the feature, the output is unchanged and nothing is cleared. The extra calls compile to nothing.

Checked with cargo test, cargo clippy --all-targets and cargo fmt --check on sha-crypt, with the default features, --all-features and --no-default-features.

I did not touch CHANGELOG.md, because its entries reference PR numbers and appear to be written at release time. I can add an entry if you prefer.

`sha256_crypt()` and `sha512_crypt()` left intermediate digests derived
from the password on the stack: the digests A, B, DP and DS, and the
hash of each round before it was copied out. Some certifications, such
as Common Criteria FDP_RIP.2, require that a password hasher clears
such data.

The new `zeroize` feature clears these digests before return, and
enables `sha2/zeroize`, which clears the hasher states on drop, like
`argon2` does for `blake2`. The rounds now finalize in place with
`finalize_into()`, which leaves no temporary copy of the digest.
Without the feature, the output is the same and nothing is cleared.
@tarcieri

tarcieri commented Nov 9, 2026

Copy link
Copy Markdown
Member

We don't clear the stack by policy: RustCrypto/meta#38

See also: https://internals.rust-lang.org/t/pre-pre-rfc-zeroize-on-return-for-function-boundary-zeroization/24796/5

I guess we need to make an AGENTS.md that describes this

@newpavlov newpavlov closed this Nov 9, 2026
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.

3 participants