pub struct ZeroizingFlat<T> { /* private fields */ }Expand description
Zeroize a flat type/struct on drop.
For external types not implementing Zeroize, this can be used to still
clear its memory after it has been dropped.
Only the flat memory backing T itself is getting cleared, but not any
heap allocations the value itself possibly owns, like e.g. some managed
through Vecs, Boxes or alike.
Works reliably only once Boxed and only for the memory owned by the Box,
no guarantees are being made for temporary copies emitted by the compiler
during construction or unpeeling through take_with(),
take_boxed_with() or
into_inner() – it all depends on compiler
optimizations then
If the zeroize Cargo feature is off, ZeroizingFlat becomes a trivial
wrapper.
Implementations§
Source§impl<T> ZeroizingFlat<T>
impl<T> ZeroizingFlat<T>
Sourcepub fn new(value: T) -> Self
pub fn new(value: T) -> Self
Wrap a value for zeroization at drop.
Even when constructed from rvalues, it all depends on compiler optimizations whether or not the value will effectively get constructed in place or non-zeroized intermediate copies will be made on the stack.
§Arguments:
value- The value to wrap.
Sourcepub fn take_with<R, F: FnOnce(T) -> R>(self, f: F) -> R
pub fn take_with<R, F: FnOnce(T) -> R>(self, f: F) -> R
Take the wrapped value and invoke a callback on it.
Functionally equivalent to
f(self.into_inner())Compared to the code above, take_with() fosters certain compiler
optimizations for copy elisions because it makes it possible to
invoke f() directly on the original memory backing the wrapped value
instead of on a temporary stack copy thereof.
There are no guarantees regarding whether such an optimization will actually be made by the compiler. In particular, the compiler might create non-zeroized temporary copies of the wrapped data on the stack.
§Arguments:
f- The callback to invoke on the unwrapped value. The return value gets propagated back.
Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Take the wrapped value.
Once unwrapped, no zeroization guarantees will apply to the unwrapped value anymore, even in the following example:
let secret: ZeroizingFlat<T>;
let secret = ZeroizingFlat::new(secret.into_inner());Sourcepub fn take_boxed_with<R, F: FnOnce(T) -> R>(self: Box<Self>, f: F) -> R
pub fn take_boxed_with<R, F: FnOnce(T) -> R>(self: Box<Self>, f: F) -> R
Take the wrapped value from a Box<Self> and invoke a callback on it.
Functionally equivalent to
Box::into_inner(self).take_with(f)with Box::into_inner() being unstable at the time of writing.
Note that in the code snippet above, the Box::into_inner() to be more
specific, would almost certainly move Self into a temporary
location on the stack, and that stack copy would then eventually get
zeroized, not the memory previously owned by the Box.
take_boxed_with() on the other hand guarantees that the memory owned
by the Box will get zeroized.
Furthermore, take_boxed_with() fosters certain compiler
optimizations for copy elisions because it makes it possible to
invoke f() directly on the original memory managed by the Box
instead of on a temporary stack copy thereof.
There are no guarantees regarding whether such an optimization will actually be made by the compiler. In particular, the compiler might create non-zeroized temporary copies of the wrapped data on the stack.
§Arguments:
f- The callback to invoke on the unwrapped value. The return value gets propagated back.
Sourcepub fn replace(&mut self, value: T)
pub fn replace(&mut self, value: T)
Replace the wrapped value with a new one.
Compared to mere reassignment of Self, this avoids a redundant zeroization pass between dropping the old and assigning the new value.
The compiler might emit temporary copies of value on the stack not
covered by any zeroization.
§Arguments:
value- The new value to wrap.
Sourcepub fn replace_boxed_with<F: FnOnce() -> T>(self: Box<Self>, f: F) -> Box<Self>
pub fn replace_boxed_with<F: FnOnce() -> T>(self: Box<Self>, f: F) -> Box<Self>
Replace the value wrapped in a Boxed Self.
Compared to replace, replace_boxed_with() fosters
certain compiler optimizations for copy elisions because it makes it
possible to place the new value directly into the memory backing the
originally wrapped value instead of into an intermediate stack
copy first.
There are no guarantees regarding whether such an optimization will actually be made by the compiler. In particular, the compiler might create non-zeroized temporary copies of the wrapped data on the stack.
replace_boxed_with() takes a Box<Self> and a callback for obtaining
the new replacement for the wrapped value, invokes f() to obtain
the replacement, wraps it in self and returns the Box<Self>
back. No memory reallocation will be made in the course.
§Arguments:
f- The callback to obtain the replacement for the wrapped value from.