Summary
When using aes-gcm in security-sensitive applications (e.g. JWE secret delivery), callers often protect raw CEKs with zeroize::Zeroizing. However, Aes256Gcm / AesGcm do not implement Zeroize or ZeroizeOnDrop, and enabling the crate's zeroize feature does not fully clear sensitive material held inside cipher state at drop time without extra downstream dependencies.
Background
In confidential-containers/trustee (KBS JWE path) PR, we encrypt secrets with patterns like:
let cek = Zeroizing::new(Aes256Gcm::generate_key(&mut OsRng));
let mut cek_cipher = Aes256Gcm::new(&*cek);
cek_cipher.encrypt_in_place_detached(nonce, aad, &mut payload)?;
The raw CEK is zeroized on drop via Zeroizing, but Aes256Gcm::new() expands the key into internal Aes256 round keys plus a GHash subkey. That expanded state is a separate copy of key material in memory.
Current behavior
AesGcm does not implement Zeroize / ZeroizeOnDrop.
- With
features = ["zeroize"], only temporary ghash_key is zeroized during construction.
aes-gcm's zeroize does not propagate to optional deps (aes, ghash/polyval).
- Consumers currently need direct dependencies as workaround:
aes-gcm = { version = "0.10", features = ["zeroize"] }
aes = { version = "0.8", features = ["zeroize"] }
polyval = { version = "0.6", features = ["zeroize"] }
Expected behavior
zeroize feature should propagate to optional deps (e.g. aes?/zeroize, ghash?/zeroize).
AesGcm<...> should provide explicit ZeroizeOnDrop behavior when zeroize is enabled.
Thanks to @Cropi 's work
Summary
When using
aes-gcmin security-sensitive applications (e.g. JWE secret delivery), callers often protect raw CEKs withzeroize::Zeroizing. However,Aes256Gcm/AesGcmdo not implementZeroizeorZeroizeOnDrop, and enabling the crate'szeroizefeature does not fully clear sensitive material held inside cipher state at drop time without extra downstream dependencies.Background
In
confidential-containers/trustee(KBS JWE path) PR, we encrypt secrets with patterns like:The raw CEK is zeroized on drop via
Zeroizing, butAes256Gcm::new()expands the key into internalAes256round keys plus aGHashsubkey. That expanded state is a separate copy of key material in memory.Current behavior
AesGcmdoes not implementZeroize/ZeroizeOnDrop.features = ["zeroize"], only temporaryghash_keyis zeroized during construction.aes-gcm'szeroizedoes not propagate to optional deps (aes,ghash/polyval).Expected behavior
zeroizefeature should propagate to optional deps (e.g.aes?/zeroize,ghash?/zeroize).AesGcm<...>should provide explicitZeroizeOnDropbehavior whenzeroizeis enabled.Thanks to @Cropi 's work