mirror of
https://github.com/BLAKE3-team/BLAKE3
synced 2024-11-08 12:59:17 +01:00
Manually implement Zeroize
Removes dependence on proc-macros when enabling the zeroize feature.
This commit is contained in:
parent
39e962e2bd
commit
84a4ec319a
@ -103,7 +103,7 @@ digest = { version = "0.10.1", features = [ "mac" ], optional = true }
|
|||||||
memmap2 = { version = "0.9", optional = true }
|
memmap2 = { version = "0.9", optional = true }
|
||||||
rayon-core = { version = "1.12.1", optional = true }
|
rayon-core = { version = "1.12.1", optional = true }
|
||||||
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
|
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
|
||||||
zeroize = { version = "1", default-features = false, features = ["zeroize_derive"], optional = true }
|
zeroize = { version = "1", default-features = false, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hmac = "0.12.0"
|
hmac = "0.12.0"
|
||||||
|
92
src/lib.rs
92
src/lib.rs
@ -138,6 +138,8 @@ use arrayvec::{ArrayString, ArrayVec};
|
|||||||
use core::cmp;
|
use core::cmp;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use platform::{Platform, MAX_SIMD_DEGREE, MAX_SIMD_DEGREE_OR_2};
|
use platform::{Platform, MAX_SIMD_DEGREE, MAX_SIMD_DEGREE_OR_2};
|
||||||
|
#[cfg(feature = "zeroize")]
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
/// The number of bytes in a [`Hash`](struct.Hash.html), 32.
|
/// The number of bytes in a [`Hash`](struct.Hash.html), 32.
|
||||||
pub const OUT_LEN: usize = 32;
|
pub const OUT_LEN: usize = 32;
|
||||||
@ -216,7 +218,6 @@ fn counter_high(counter: u64) -> u32 {
|
|||||||
/// [`from_hex`]: #method.from_hex
|
/// [`from_hex`]: #method.from_hex
|
||||||
/// [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
|
/// [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
|
||||||
/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
|
/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
|
||||||
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize))]
|
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[derive(Clone, Copy, Hash)]
|
#[derive(Clone, Copy, Hash)]
|
||||||
pub struct Hash([u8; OUT_LEN]);
|
pub struct Hash([u8; OUT_LEN]);
|
||||||
@ -305,6 +306,15 @@ impl core::str::FromStr for Hash {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "zeroize")]
|
||||||
|
impl Zeroize for Hash {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
// Destructuring to trigger compile error as a reminder to update this impl.
|
||||||
|
let Self(bytes) = self;
|
||||||
|
bytes.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// A proper implementation of constant time equality is tricky, and we get it from the
|
// A proper implementation of constant time equality is tricky, and we get it from the
|
||||||
// constant_time_eq crate instead of rolling our own. However, that crate isn't compatible with
|
// constant_time_eq crate instead of rolling our own. However, that crate isn't compatible with
|
||||||
// Miri, so we roll our own just for that.
|
// Miri, so we roll our own just for that.
|
||||||
@ -416,7 +426,6 @@ impl std::error::Error for HexError {}
|
|||||||
// Each chunk or parent node can produce either a 32-byte chaining value or, by
|
// Each chunk or parent node can produce either a 32-byte chaining value or, by
|
||||||
// setting the ROOT flag, any number of final output bytes. The Output struct
|
// setting the ROOT flag, any number of final output bytes. The Output struct
|
||||||
// captures the state just prior to choosing between those two possibilities.
|
// captures the state just prior to choosing between those two possibilities.
|
||||||
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize))]
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Output {
|
struct Output {
|
||||||
input_chaining_value: CVWords,
|
input_chaining_value: CVWords,
|
||||||
@ -424,7 +433,6 @@ struct Output {
|
|||||||
block_len: u8,
|
block_len: u8,
|
||||||
counter: u64,
|
counter: u64,
|
||||||
flags: u8,
|
flags: u8,
|
||||||
#[cfg_attr(feature = "zeroize", zeroize(skip))]
|
|
||||||
platform: Platform,
|
platform: Platform,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,8 +468,28 @@ impl Output {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "zeroize")]
|
||||||
|
impl Zeroize for Output {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
// Destructuring to trigger compile error as a reminder to update this impl.
|
||||||
|
let Self {
|
||||||
|
input_chaining_value,
|
||||||
|
block,
|
||||||
|
block_len,
|
||||||
|
counter,
|
||||||
|
flags,
|
||||||
|
platform: _,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
input_chaining_value.zeroize();
|
||||||
|
block.zeroize();
|
||||||
|
block_len.zeroize();
|
||||||
|
counter.zeroize();
|
||||||
|
flags.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize))]
|
|
||||||
struct ChunkState {
|
struct ChunkState {
|
||||||
cv: CVWords,
|
cv: CVWords,
|
||||||
chunk_counter: u64,
|
chunk_counter: u64,
|
||||||
@ -469,7 +497,6 @@ struct ChunkState {
|
|||||||
buf_len: u8,
|
buf_len: u8,
|
||||||
blocks_compressed: u8,
|
blocks_compressed: u8,
|
||||||
flags: u8,
|
flags: u8,
|
||||||
#[cfg_attr(feature = "zeroize", zeroize(skip))]
|
|
||||||
platform: Platform,
|
platform: Platform,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,6 +599,29 @@ impl fmt::Debug for ChunkState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "zeroize")]
|
||||||
|
impl Zeroize for ChunkState {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
// Destructuring to trigger compile error as a reminder to update this impl.
|
||||||
|
let Self {
|
||||||
|
cv,
|
||||||
|
chunk_counter,
|
||||||
|
buf,
|
||||||
|
buf_len,
|
||||||
|
blocks_compressed,
|
||||||
|
flags,
|
||||||
|
platform: _,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
cv.zeroize();
|
||||||
|
chunk_counter.zeroize();
|
||||||
|
buf.zeroize();
|
||||||
|
buf_len.zeroize();
|
||||||
|
blocks_compressed.zeroize();
|
||||||
|
flags.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IMPLEMENTATION NOTE
|
// IMPLEMENTATION NOTE
|
||||||
// ===================
|
// ===================
|
||||||
// The recursive function compress_subtree_wide(), implemented below, is the
|
// The recursive function compress_subtree_wide(), implemented below, is the
|
||||||
@ -985,7 +1035,6 @@ fn parent_node_output(
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize))]
|
|
||||||
pub struct Hasher {
|
pub struct Hasher {
|
||||||
key: CVWords,
|
key: CVWords,
|
||||||
chunk_state: ChunkState,
|
chunk_state: ChunkState,
|
||||||
@ -1532,6 +1581,22 @@ impl std::io::Write for Hasher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "zeroize")]
|
||||||
|
impl Zeroize for Hasher {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
// Destructuring to trigger compile error as a reminder to update this impl.
|
||||||
|
let Self {
|
||||||
|
key,
|
||||||
|
chunk_state,
|
||||||
|
cv_stack,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
key.zeroize();
|
||||||
|
chunk_state.zeroize();
|
||||||
|
cv_stack.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An incremental reader for extended output, returned by
|
/// An incremental reader for extended output, returned by
|
||||||
/// [`Hasher::finalize_xof`](struct.Hasher.html#method.finalize_xof).
|
/// [`Hasher::finalize_xof`](struct.Hasher.html#method.finalize_xof).
|
||||||
///
|
///
|
||||||
@ -1555,7 +1620,6 @@ impl std::io::Write for Hasher {
|
|||||||
/// from an unknown position in the output stream to recover its block index. Callers with strong
|
/// from an unknown position in the output stream to recover its block index. Callers with strong
|
||||||
/// secret keys aren't affected in practice, but secret offsets are a [design
|
/// secret keys aren't affected in practice, but secret offsets are a [design
|
||||||
/// smell](https://en.wikipedia.org/wiki/Design_smell) in any case.
|
/// smell](https://en.wikipedia.org/wiki/Design_smell) in any case.
|
||||||
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize))]
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct OutputReader {
|
pub struct OutputReader {
|
||||||
inner: Output,
|
inner: Output,
|
||||||
@ -1667,3 +1731,17 @@ impl std::io::Seek for OutputReader {
|
|||||||
Ok(self.position())
|
Ok(self.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "zeroize")]
|
||||||
|
impl Zeroize for OutputReader {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
// Destructuring to trigger compile error as a reminder to update this impl.
|
||||||
|
let Self {
|
||||||
|
inner,
|
||||||
|
position_within_block,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
inner.zeroize();
|
||||||
|
position_within_block.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user