Skip to content

hmac: impl ZeroizeOnDrop for HMAC cores and wrappers - #287

Open
czareko wants to merge 1 commit into
RustCrypto:masterfrom
aletheia-labs:hmac-zeroize-on-drop
Open

czareko wants to merge 1 commit into
RustCrypto:masterfrom
aletheia-labs:hmac-zeroize-on-drop

Conversation

@czareko

@czareko czareko commented Nov 12, 2026 •

Copy link
Copy Markdown

With the zeroize feature enabled, dropping Hmac<D> / HmacReset<D> already clears their state when the hash core does: the inner D::Core instances zeroize on drop (e.g. sha2 with its zeroize feature) and the BlockBuffer is zeroized via digest/zeroize. However, no HMAC type implements the ZeroizeOnDrop marker, so downstream code cannot assert this at compile time.

This adds ZeroizeOnDrop for HmacCore, HmacResetCore, Hmac and HmacReset behind the zeroize feature, bounded on D::Core: ZeroizeOnDrop, following the pattern used by the other crates in this repo. The ZeroizeOnDrop arm of buffer_fixed! is not used because it emits an unconditional impl, which would be incorrect for hash cores that do not zeroize.

As suggested by @tarcieri in #255. Stack temporaries remain out of scope.

Motivation

Without the marker, downstream code has two options, both visible in the wild:

  • Assert on the internals instead, e.g. <Sha512 as CoreProxy>::Core and Buffer<Core<Sha512>>, which silently stops covering Hmac if its layout changes.
  • Avoid hmac entirely for secret keys. krusty-kms reimplements HMAC on top of sha2 and requires D: ZeroizeOnDrop, so that dropping the zeroize feature fails the build.

It also makes a missing feature detectable. Some projects derive keys from seeds through Hmac<Sha512> (e.g. BIP-32 / SLIP-10) while zeroizing their own key types, but build hmac and sha2 without zeroize, leaving the HMAC state in memory. With this change, a single assert_zeroize_on_drop::<Hmac<Sha512>>() catches that at compile time.

@ErgonSurfer

Copy link
Copy Markdown

Thanks for making the hash-state guarantee checkable. Could the docs clarify which features clear the HMAC block buffer and the underlying hash state, for example with Hmac<Sha256> and sha2/zeroize?

A short note linking to the stack-zeroization discussion would also help readers understand the scope for the ipad/opad scratch block, the inner digest, and the long-key digest in 0.13.0. Compiler-generated copies and spills are outside scope.

This branch has not been deployed

No deployments
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.

2 participants