Skip to content

Commit

Permalink
Implement Zeroize for SHA 1..=3 and Blake2
Browse files Browse the repository at this point in the history
  • Loading branch information
kayabaNerve committed Nov 12, 2023
1 parent 70a2b62 commit 1d46e95
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 8 deletions.
52 changes: 52 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion blake2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@ categories = ["cryptography", "no-std"]

[dependencies]
digest = { version = "0.10.7", features = ["mac"] }
zeroize = { version = "1", features = ["derive"], optional = true }

[dev-dependencies]
digest = { version = "0.10.7", features = ["dev"] }
hex-literal = "0.2.2"

[features]
default = ["std"]
std = ["digest/std"]
std = ["digest/std", "zeroize?/std"]
reset = [] # Enable reset functionality
simd = []
simd_opt = ["simd"]
simd_asm = ["simd_opt"]
size_opt = [] # Optimize for code size. Removes some `inline(always)`
zeroize = ["dep:zeroize"] # Implement Zeroize for Digest implementors
18 changes: 16 additions & 2 deletions blake2/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ macro_rules! blake2_impl {
pub struct $name {
h: [$vec; 2],
t: u64,
#[cfg(feature = "reset")]
#[cfg(any(feature = "reset", feature = "zeroize"))]
h0: [$vec; 2],
}

Expand Down Expand Up @@ -86,7 +86,7 @@ macro_rules! blake2_impl {
Self::iv1() ^ $vec::new(p[4], p[5], p[6], p[7]),
];
$name {
#[cfg(feature = "reset")]
#[cfg(any(feature = "reset", feature = "zeroize"))]
h0: h.clone(),
h,
t: 0,
Expand Down Expand Up @@ -243,6 +243,20 @@ macro_rules! blake2_impl {
}
}

#[cfg(feature = "zeroize")]
impl zeroize::Zeroize for $name {
fn zeroize(&mut self) {
self.h.zeroize();
self.t.zeroize();

// Because the hasher is now in an invalid state, restore the starting state
// This makes Zeroize equivalent to reset *yet using a zero-write the compiler
// hopefully shouldn't be able to optimize out*
// The following lines may be optimized out if no further use occurs, which is fine
self.h = self.h0;
}
}

impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(concat!(stringify!($name), " { ... }"))
Expand Down
5 changes: 5 additions & 0 deletions blake2/src/simd/simdty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@

#![allow(dead_code, non_camel_case_types)]

#[cfg(feature = "zeroize")]
use zeroize::Zeroize;

use crate::as_bytes::Safe;

#[cfg(feature = "simd")]
macro_rules! decl_simd {
($($decl:item)*) => {
$(
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "zeroize", derive(Zeroize))]
#[repr(simd)]
$decl
)*
Expand All @@ -25,6 +29,7 @@ macro_rules! decl_simd {
($($decl:item)*) => {
$(
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "zeroize", derive(Zeroize))]
#[repr(C)]
$decl
)*
Expand Down
4 changes: 3 additions & 1 deletion sha1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ categories = ["cryptography", "no-std"]
[dependencies]
digest = "0.10.7"
cfg-if = "1.0"
zeroize = { version = "1", optional = true }

[target.'cfg(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64"))'.dependencies]
cpufeatures = "0.2"
Expand All @@ -25,14 +26,15 @@ hex-literal = "0.2.2"

[features]
default = ["std"]
std = ["digest/std"]
std = ["digest/std", "zeroize?/std"]
oid = ["digest/oid"] # Enable OID support. WARNING: Bumps MSRV to 1.57
asm = ["sha1-asm"] # WARNING: this feature SHOULD NOT be enabled by library crates
# Use assembly backend for LoongArch64 targets
# WARNING: Bumps MSRV to 1.72. This feature SHOULD NOT be enabled by library crates
loongarch64_asm = []
compress = [] # Expose compress function
force-soft = [] # Force software implementation
zeroize = ["dep:zeroize"] # Implement Zeroize for Digest implementors

[package.metadata.docs.rs]
all-features = true
Expand Down
14 changes: 14 additions & 0 deletions sha1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,20 @@ impl AlgorithmName for Sha1Core {
}
}

#[cfg(feature = "zeroize")]
impl zeroize::Zeroize for Sha1Core {
fn zeroize(&mut self) {
self.h.zeroize();
self.block_len.zeroize();

// Because the hasher is now in an invalid state, restore the starting state
// This makes Zeroize equivalent to reset *yet using a zero-write the compiler hopefully
// shouldn't be able to optimize out*
// The following lines may be optimized out if no further use occurs, which is fine
self.h = Self::default().h;
}
}

impl fmt::Debug for Sha1Core {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Sha1Core { ... }")
Expand Down
4 changes: 3 additions & 1 deletion sha2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ categories = ["cryptography", "no-std"]
[dependencies]
digest = "0.10.7"
cfg-if = "1.0"
zeroize = { version = "1", optional = true }

[target.'cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "x86"))'.dependencies]
cpufeatures = "0.2"
Expand All @@ -28,7 +29,7 @@ hex-literal = "0.2.2"

[features]
default = ["std"]
std = ["digest/std"]
std = ["digest/std", "zeroize?/std"]
oid = ["digest/oid"] # Enable OID support. WARNING: Bumps MSRV to 1.57
asm = ["sha2-asm"] # WARNING: this feature SHOULD NOT be enabled by library crates
# Use assembly backend for LoongArch64 targets
Expand All @@ -37,6 +38,7 @@ loongarch64_asm = []
compress = [] # Expose compress functions
force-soft = [] # Force software implementation
asm-aarch64 = ["asm"] # DEPRECATED: use `asm` instead
zeroize = ["dep:zeroize"] # Implement Zeroize for Digest implementors

[package.metadata.docs.rs]
all-features = true
Expand Down
41 changes: 39 additions & 2 deletions sha2/src/core_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use digest::{
/// i.e. 224 and 256 bits respectively.
#[derive(Clone)]
pub struct Sha256VarCore {
#[cfg(feature = "zeroize")]
output_size: usize,
state: consts::State256,
block_len: u64,
}
Expand Down Expand Up @@ -53,7 +55,12 @@ impl VariableOutputCore for Sha256VarCore {
_ => return Err(InvalidOutputSize),
};
let block_len = 0;
Ok(Self { state, block_len })
Ok(Self {
#[cfg(feature = "zeroize")]
output_size,
state,
block_len,
})
}

#[inline]
Expand All @@ -75,6 +82,20 @@ impl AlgorithmName for Sha256VarCore {
}
}

#[cfg(feature = "zeroize")]
impl zeroize::Zeroize for Sha256VarCore {
fn zeroize(&mut self) {
self.state.zeroize();
self.block_len.zeroize();

// Because the hasher is now in an invalid state, restore the starting state
// This makes Zeroize equivalent to reset *yet using a zero-write the compiler hopefully
// shouldn't be able to optimize out*
// The following lines may be optimized out if no further use occurs, which is fine
self.state = Self::new(self.output_size).unwrap().state;
}
}

impl fmt::Debug for Sha256VarCore {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand All @@ -88,6 +109,8 @@ impl fmt::Debug for Sha256VarCore {
/// i.e. 224, 256, 384, and 512 bits respectively.
#[derive(Clone)]
pub struct Sha512VarCore {
#[cfg(feature = "zeroize")]
output_size: usize,
state: consts::State512,
block_len: u128,
}
Expand Down Expand Up @@ -127,7 +150,12 @@ impl VariableOutputCore for Sha512VarCore {
_ => return Err(InvalidOutputSize),
};
let block_len = 0;
Ok(Self { state, block_len })
Ok(Self {
#[cfg(feature = "zeroize")]
output_size,
state,
block_len,
})
}

#[inline]
Expand All @@ -149,6 +177,15 @@ impl AlgorithmName for Sha512VarCore {
}
}

#[cfg(feature = "zeroize")]
impl zeroize::Zeroize for Sha512VarCore {
fn zeroize(&mut self) {
self.state.zeroize();
self.block_len.zeroize();
self.state = Self::new(self.output_size).unwrap().state;
}
}

impl fmt::Debug for Sha512VarCore {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down
9 changes: 8 additions & 1 deletion sha3/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ impl Default for Sha3State {
}
}

#[cfg(feature = "zeroize")]
impl Zeroize for Sha3State {
fn zeroize(&mut self) {
self.state.zeroize();
}
}

#[cfg(feature = "zeroize")]
impl Drop for Sha3State {
fn drop(&mut self) {
self.state.zeroize();
self.zeroize();
}
}

Expand Down

0 comments on commit 1d46e95

Please sign in to comment.