Skip to content

Commit 7771673

Browse files
committed
Implement ZeroizeOnDrop for the output of buffer_ct_variable
This allows `blake2::Blake2b: ZeroizeOnDrop`.
1 parent 1c96506 commit 7771673

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

digest/src/buffer_macros/variable.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/// Creates a buffered wrapper around block-level "core" type which implements variable output size traits
22
/// with output size selected at compile time.
3+
#[doc(hidden)]
34
#[macro_export]
4-
macro_rules! buffer_ct_variable {
5+
macro_rules! buffer_ct_variable_internal {
56
(
67
$(#[$attr:meta])*
78
$vis:vis struct $name:ident<$out_size:ident>($core_ty:ty);
@@ -209,3 +210,64 @@ macro_rules! buffer_ct_variable {
209210
}
210211
};
211212
}
213+
214+
#[doc(hidden)]
215+
#[cfg(not(feature = "zeroize"))]
216+
#[macro_export]
217+
macro_rules! buffer_ct_variable_zeroize_on_drop {
218+
($name:ident, $out_size:ident, $max_size:ty) => {};
219+
}
220+
221+
#[doc(hidden)]
222+
#[cfg(feature = "zeroize")]
223+
#[macro_export]
224+
macro_rules! buffer_ct_variable_zeroize_on_drop {
225+
($name:ident, $out_size:ident, $max_size:ty) => {
226+
// While `$name` will not implement `Drop`, it is still `ZeroizeOnDrop` as all its fields
227+
// are `ZeroizeOnDrop`. The following ensures this.
228+
impl<$out_size> $name<$out_size>
229+
where
230+
$out_size: $crate::array::ArraySize
231+
+ $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>,
232+
{
233+
// This is `pub` to ensure it's actually compiled and not eliminated as dead code
234+
#[doc(hidden)]
235+
pub fn __ensure_all_fields_impl_zeroize_on_drop(&mut self) {
236+
let Self { core, buffer } = self;
237+
fn implements_zeroize_on_drop(_value: &mut impl $crate::zeroize::ZeroizeOnDrop) {}
238+
implements_zeroize_on_drop(core);
239+
implements_zeroize_on_drop(buffer);
240+
}
241+
}
242+
243+
impl<$out_size> $crate::zeroize::ZeroizeOnDrop for $name<$out_size> where
244+
$out_size: $crate::array::ArraySize
245+
+ $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>
246+
{
247+
}
248+
};
249+
}
250+
251+
/// Creates a buffered wrapper around block-level "core" type which implements variable output size traits
252+
/// with output size selected at compile time.
253+
#[macro_export]
254+
macro_rules! buffer_ct_variable {
255+
(
256+
$(#[$attr:meta])*
257+
$vis:vis struct $name:ident<$out_size:ident>($core_ty:ty);
258+
exclude: SerializableState;
259+
// Ideally, we would use `$core_ty::OutputSize`, but unfortunately the compiler
260+
// does not accept such code. The likely reason is this issue:
261+
// https://github.com/rust-lang/rust/issues/79629
262+
max_size: $max_size:ty;
263+
) => {
264+
$crate::buffer_ct_variable_internal!(
265+
$(#[$attr])*
266+
$vis struct $name<$out_size>($core_ty);
267+
exclude: SerializableState;
268+
max_size: $max_size;
269+
);
270+
271+
$crate::buffer_ct_variable_zeroize_on_drop!($name, $out_size, $max_size);
272+
}
273+
}

0 commit comments

Comments
 (0)