Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/algorithms/chacha20poly1305/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ libcrux-secrets.workspace = true
[dev-dependencies]
rand_core = { version = "0.10" }
rand = { version = "0.10", features = ["sys_rng"] }
zeroize = { version = "1.8", default-features = false }
libcrux-kats = { workspace = true, features = ["chacha20poly1305"] }
hex = "0.4.3"

[features]
check-secret-independence = ["libcrux-secrets/check-secret-independence"]
# Implement zeroize::Zeroize for the Key type
zeroize = ["libcrux-traits/zeroize", "libcrux-secrets/zeroize"]
15 changes: 15 additions & 0 deletions crates/algorithms/chacha20poly1305/tests/zeroize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![cfg(feature = "zeroize")]

use libcrux_chacha20poly1305::{Key, KEY_LEN};
use libcrux_secrets::{Classify, DeclassifyRef};
use zeroize::Zeroize;

#[test]
fn key_zeroize_clears_bytes() {
let mut key = Key::from([0xAAu8; KEY_LEN].classify());
assert_eq!(key.as_ref().declassify_ref(), &[0xAAu8; KEY_LEN]);

key.zeroize();

assert_eq!(key.as_ref().declassify_ref(), &[0u8; KEY_LEN]);
}
3 changes: 3 additions & 0 deletions crates/utils/secrets/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ exclude = ["/proofs"]

[dependencies]
hax-lib.workspace = true
zeroize = { version = "1.8", default-features = false, optional = true }

[target.'cfg(valgrind_ct_test)'.dependencies]
crabgrind.workspace = true

[features]
check-secret-independence = []
# Implement zeroize::Zeroize for Secret<T>
zeroize = ["dep:zeroize"]

[dev-dependencies]
criterion = "0.8.0"
Expand Down
7 changes: 7 additions & 0 deletions crates/utils/secrets/src/int/classify_secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ impl<T: Clone> Clone for Secret<T> {
}
}

#[cfg(feature = "zeroize")]
impl<T: zeroize::Zeroize> zeroize::Zeroize for Secret<T> {
fn zeroize(&mut self) {
self.0.zeroize();
}
}

// Any scalar type can be classified
impl<T: Scalar> From<T> for Secret<T> {
fn from(x: T) -> Secret<T> {
Expand Down
4 changes: 4 additions & 0 deletions libcrux-ml-dsa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ libcrux-macros.workspace = true
libcrux-secrets.workspace = true
hax-lib.workspace = true
tls_codec = { workspace = true, optional = true }
zeroize = { version = "1.8", default-features = false, optional = true }

[dev-dependencies]
rand = { version = "0.10" }
Expand Down Expand Up @@ -68,6 +69,9 @@ std = ["tls_codec?/std"]
# Serialization & Deserialization using tls_codec
codec = ["dep:tls_codec"]

# Zeroize secret key material on drop
zeroize = ["dep:zeroize"]

[[bench]]
name = "manual44"
harness = false
Expand Down
33 changes: 33 additions & 0 deletions libcrux-ml-dsa/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,36 @@ mod codec {
impl_tls_codec_for_generic_struct!(MLDSAVerificationKey);
impl_tls_codec_for_generic_struct!(MLDSASignature);
}

#[cfg(all(feature = "zeroize", not(hax)))]
mod zeroize_impls {
use super::*;
use zeroize::{Zeroize, ZeroizeOnDrop};

impl<const SIZE: usize> Zeroize for MLDSASigningKey<SIZE> {
fn zeroize(&mut self) {
self.value.zeroize();
}
}

impl<const SIZE: usize> Drop for MLDSASigningKey<SIZE> {
fn drop(&mut self) {
self.zeroize();
}
}

impl<const SIZE: usize> ZeroizeOnDrop for MLDSASigningKey<SIZE> {}

impl<const VERIFICATION_KEY_SIZE: usize, const SIGNING_KEY_SIZE: usize> Zeroize
for MLDSAKeyPair<VERIFICATION_KEY_SIZE, SIGNING_KEY_SIZE>
{
fn zeroize(&mut self) {
self.signing_key.zeroize();
}
}

impl<const VERIFICATION_KEY_SIZE: usize, const SIGNING_KEY_SIZE: usize> ZeroizeOnDrop
for MLDSAKeyPair<VERIFICATION_KEY_SIZE, SIGNING_KEY_SIZE>
{
}
}
32 changes: 32 additions & 0 deletions libcrux-ml-dsa/tests/zeroize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#![cfg(feature = "zeroize")]

use libcrux_ml_dsa::{MLDSAKeyPair, MLDSASigningKey, MLDSAVerificationKey};
use zeroize::Zeroize;

const SK_SIZE: usize = 64;
const VK_SIZE: usize = 32;

#[test]
fn signing_key_zeroize_clears_value() {
let mut key = MLDSASigningKey::<SK_SIZE>::new([0xAA; SK_SIZE]);
assert_eq!(key.as_slice(), &[0xAA; SK_SIZE]);

key.zeroize();

assert_eq!(key.as_slice(), &[0u8; SK_SIZE]);
}

#[test]
fn keypair_zeroize_clears_signing_key_only() {
let mut keypair = MLDSAKeyPair::<VK_SIZE, SK_SIZE> {
signing_key: MLDSASigningKey::<SK_SIZE>::new([0xAA; SK_SIZE]),
verification_key: MLDSAVerificationKey::<VK_SIZE>::new([0xBB; VK_SIZE]),
};
assert_eq!(keypair.signing_key.as_slice(), &[0xAA; SK_SIZE]);
assert_eq!(keypair.verification_key.as_slice(), &[0xBB; VK_SIZE]);

keypair.zeroize();

assert_eq!(keypair.signing_key.as_slice(), &[0u8; SK_SIZE]);
assert_eq!(keypair.verification_key.as_slice(), &[0xBB; VK_SIZE]);
}
3 changes: 3 additions & 0 deletions traits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ check-secret-independence = ["libcrux-secrets/check-secret-independence"]
generic-tests = []
# whether or not the alloc crate is used
alloc = []
# Implement zeroize::Zeroize for typed key wrappers
zeroize = ["dep:zeroize", "libcrux-secrets/zeroize"]

[dependencies]
rand = { version = "0.10", default-features = false }
libcrux-secrets.workspace = true
zeroize = { version = "1.8", default-features = false, optional = true }
10 changes: 10 additions & 0 deletions traits/src/aead/typed_owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,13 @@ impl<Algo: Aead> AsMut<Algo::Nonce> for Nonce<Algo> {
&mut self.0
}
}

#[cfg(feature = "zeroize")]
impl<Algo: Aead> zeroize::Zeroize for Key<Algo>
where
Algo::Key: zeroize::Zeroize,
{
fn zeroize(&mut self) {
self.0.zeroize();
}
}