Skip to content

Commit ed88d8a

Browse files
committed
Additional zeroization/defense-in-depth + CI fixes
1 parent ef729e1 commit ed88d8a

5 files changed

Lines changed: 41 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,4 @@ jobs:
118118
with:
119119
tool: cargo-fuzz
120120
- name: cargo fuzz run ${{ matrix.target }}
121-
run: cargo fuzz run ${{ matrix.target }} -- -max_total_time=60 -rss_limit_mb=4096
121+
run: cargo fuzz run --target "$(rustc -vV | sed -n 's/^host: //p')" ${{ matrix.target }} -- -max_total_time=60 -rss_limit_mb=4096

Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ shake = { version = "0.1", default-features = false, optional = true
2121
aead = { version = "0.5", default-features = false, features = ["alloc"] }
2222
aes-gcm = { version = "0.10", default-features = false, features = ["aes", "alloc", "zeroize"] }
2323
chacha20poly1305 = { version = "0.10", default-features = false, features = ["alloc"] }
24+
aes = { version = "0.8", default-features = false, features = ["zeroize"] }
25+
ghash = { version = "0.5", default-features = false, features = ["zeroize"] }
26+
polyval = { version = "0.6", default-features = false, features = ["zeroize"] }
2427
x25519-dalek = { version = "3", default-features = false, features = ["zeroize", "static_secrets"] }
2528
ed448-goldilocks = { version = "0.14.0-pre.12", default-features = false }
2629
p256 = { version = "0.14", default-features = false, features = ["arithmetic", "ecdh"] }

src/aead.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,15 @@ mod tests {
288288
assert_eq!(r.err(), Some(HpkeError::AeadInitError));
289289
}
290290

291+
/// Guards the `aes/zeroize` entry in `Cargo.toml`: `aes_gcm::AesGcm` has no
292+
/// `Drop`, so without it the cached round keys survive in freed memory.
293+
#[test]
294+
fn aes_round_keys_are_scrubbed_on_drop() {
295+
fn assert_zeroize_on_drop<T: zeroize::ZeroizeOnDrop>() {}
296+
assert_zeroize_on_drop::<aes::Aes128>();
297+
assert_zeroize_on_drop::<aes::Aes256>();
298+
}
299+
291300
#[test]
292301
fn export_only_implements_aead_only() {
293302
fn assert_aead<A: Aead>() {}

src/psk.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
33
use core::fmt;
44

5+
use subtle::ConstantTimeEq;
6+
57
use crate::HpkeError;
68

79
/// Minimum accepted PSK length in bytes.
@@ -32,12 +34,21 @@ pub const MIN_PSK_LEN: usize = 32;
3234
/// assert_eq!(Psk::new(b"hunter2", b"my-psk-id"), Err(HpkeError::InsecurePsk));
3335
/// # Ok::<_, HpkeError>(())
3436
/// ```
35-
#[derive(Clone, Copy, PartialEq, Eq)]
37+
#[derive(Clone, Copy)]
3638
pub struct Psk<'a> {
3739
secret: &'a [u8],
3840
id: &'a [u8],
3941
}
4042

43+
/// Constant-time in the secret; the identifier is public and compared normally.
44+
impl PartialEq for Psk<'_> {
45+
fn eq(&self, other: &Self) -> bool {
46+
self.id == other.id && bool::from(self.secret.ct_eq(other.secret))
47+
}
48+
}
49+
50+
impl Eq for Psk<'_> {}
51+
4152
impl<'a> Psk<'a> {
4253
/// Bundle a PSK with its identifier.
4354
///
@@ -121,6 +132,16 @@ mod tests {
121132
assert_eq!(psk.id(), b"the-id");
122133
}
123134

135+
#[test]
136+
fn equality_compares_both_fields() {
137+
let a = [0x11u8; MIN_PSK_LEN];
138+
let mut b = a;
139+
b[MIN_PSK_LEN - 1] ^= 1;
140+
assert_eq!(Psk::new(&a, b"id").unwrap(), Psk::new(&a, b"id").unwrap());
141+
assert_ne!(Psk::new(&a, b"id").unwrap(), Psk::new(&b, b"id").unwrap());
142+
assert_ne!(Psk::new(&a, b"id").unwrap(), Psk::new(&a, b"id-x").unwrap());
143+
}
144+
124145
#[test]
125146
fn debug_redacts_the_secret() {
126147
let psk = Psk::new(&[0xAAu8; MIN_PSK_LEN], b"the-id").unwrap();

0 commit comments

Comments
 (0)