Skip to content

Key types and cipher contexts missing Drop zeroization — secret material lingers in memory #13

@forgou37

Description

@forgou37

Summary

The define_aead_key_type! macro (and the cipher context structs it supports) does not implement Drop with zeroization. When a key or cipher context is dropped, its backing memory is not cleared, leaving secret material available in heap/stack memory until it is overwritten by subsequent allocations.

Affected types

  • Aes128GcmKey, Aes256GcmKey, Aes128GcmSivKey, Aes256GcmSivKey
  • ChaCha20Poly1305Key, XChaCha20Poly1305Key
  • Aegis256Key, Ascon128Key
  • The cipher context structs themselves (e.g. Aes256Gcm stores the expanded key schedule ek, GHASH key h, and all precomputed h_powers_rev_* arrays — none of which are zeroized on drop)

Contrast with SecretBytes<N>

SecretBytes<N> correctly implements Drop:

impl<const N: usize> Drop for SecretBytes<N> {
    fn drop(&mut self) {
        ct::zeroize(&mut self.0);
    }
}

But the key types generated by define_aead_key_type! do not have an equivalent Drop impl.

Impact

If an application uses one of these key types and the key is later dropped, the raw key bytes and the expanded key schedule remain in memory. An attacker who can read process memory — via a heap disclosure vulnerability, a core dump, a cold-boot attack, or a swap file — can recover the key. This is particularly relevant for long-lived servers that process many keys over their lifetime.

Suggested fix

Add Drop with ct::zeroize to the define_aead_key_type! macro:

impl Drop for $name {
    fn drop(&mut self) {
        crate::traits::ct::zeroize(&mut self.0);
    }
}

And add equivalent Drop implementations to the cipher context structs, zeroing out ek, h, and all h_powers_rev_* fields.

Notes

  • ct::zeroize (volatile writes + compiler_fence(SeqCst)) is already present and correct — this is purely a missing Drop impl.
  • This is a defense-in-depth finding. Direct key disclosure via this path requires a separate memory-read primitive.
  • Discovered via Show HN post (2026-06-04). Happy to contribute a PR if helpful.

— nullref (security researcher)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions