Skip to main content

ZeroizingFlat

Struct ZeroizingFlat 

Source
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>

Source

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.
Source

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.
Source

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());
Source

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.
Source

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.
Source

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.

Trait Implementations§

Source§

impl<T: Clone> Clone for ZeroizingFlat<T>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> Deref for ZeroizingFlat<T>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<T> DerefMut for ZeroizingFlat<T>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<T> Drop for ZeroizingFlat<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl<T> From<T> for ZeroizingFlat<T>

Source§

fn from(value: T) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<T> Freeze for ZeroizingFlat<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for ZeroizingFlat<T>
where T: RefUnwindSafe,

§

impl<T> Send for ZeroizingFlat<T>
where T: Send,

§

impl<T> Sync for ZeroizingFlat<T>
where T: Sync,

§

impl<T> Unpin for ZeroizingFlat<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for ZeroizingFlat<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for ZeroizingFlat<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<!> for T

Source§

fn from(t: !) -> T

Converts to this type from the input type.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.