SecretVec

Struct SecretVec 

Source
pub struct SecretVec<T>
where T: Bytes,
{ /* private fields */ }
Expand description

A type for protecting variable-length secrets allocated on the heap.

Heap-allocated secrets have distinct security needs from stack-allocated ones. They provide the following guarantees:

  • any attempt to access the memory without having been borrowed appropriately will result in immediate program termination; the memory is protected with mprotect(2) as follows:
  • the allocated region has guard pages preceding and following it—both set to PROT_NONE—ensuring that overflows and (large enough) underflows cause immediate program termination
  • a canary is placed just before the memory location (and after the guard page) in order to detect smaller underflows; if this memory has been written to (and the canary modified), the program will immediately abort when the SecretVec is dropped
  • mlock(2) is called on the underlying memory
  • munlock(2) is called on the underlying memory when no longer in use
  • the underlying memory is zeroed when no longer in use
  • they are best-effort compared in constant time
  • they are best-effort prevented from being printed by Debug.
  • they are best-effort protected from Cloneing the interior data

To fulfill these guarantees, SecretVec uses an API similar to (but not exactly like) that of RefCell. You must call borrow to (immutably) borrow the protected data inside and you must call borrow_mut to access it mutably. Unlike RefCell which hides interior mutability with immutable borrows, these two calls follow standard borrowing rules: borrow_mut takes a &mut self, so the borrow checker statically ensures the exclusivity of mutable borrows.

These borrow and borrow_mut calls return a wrapper around the interior that ensures the memory is re-mprotected when all active borrows leave scope. These wrappers Deref to the underlying value so you can to work with them as if they were the underlying type, with a few excepitons: they have specific implementations for Clone, Debug, PartialEq, and Eq that try to ensure that the underlying memory isn’t copied out of protected area, that the contents are never printed, and that two secrets are only ever compared in constant time.

Care must be taken not to over-aggressively dereference these wrappers, as once you’re working with the real underlying type, we can’t prevent direct calls to their implementations of these traits. Care must also be taken not to call any other methods on these types that introduce copying.

§Example: generate a cryptographically-random 128-bit SecretVec

Initialize a SecretVec with cryptographically random data:

let secret = SecretVec::<u8>::random(16);

assert_eq!(secret.size(), 16);

§Example: move mutable data into a SecretVec

Existing data can be moved into a SecretVec. When doing so, we make a best-effort attempt to zero out the data in the original location. Any prior copies will be unaffected, so please exercise as much caution as possible when handling data before it can be protected.

let mut value = [1u8, 2, 3, 4];

// the contents of `value` will be copied into the SecretVec before
// being zeroed out
let secret = SecretVec::from(&mut value[..]);

// the contents of `value` have been zeroed
assert_eq!(value, [0, 0, 0, 0]);

§Example: compilation failure from incompatible borrows

Unlike RefCell, which hides interior mutability behind immutable borrows, a SecretVec can’t have an outstanding borrow and borrow_mut at the same time.

let mut secret   = SecretVec::<u32>::zero(8);
let     secret_r = secret.borrow();

// error[E0502]: cannot borrow `secret` as mutable because it is
// also borrowed as immutable
secret.borrow_mut();

§Example: compilation failure from multiple mutable borrows

Unlike RefCell, which hides interior mutability behind immutable borrows, a SecretVec can’t have multiple outstanding borrow_muts at the same time.

let mut secret   = SecretVec::<u32>::zero(8);
let     secret_w = secret.borrow_mut();

// error[E0499]: cannot borrow `secret` as mutable more than once
// at a time
secret.borrow_mut();

Implementations§

Source§

impl<T> SecretVec<T>
where T: Bytes,

Source

pub fn new<F>(len: usize, f: F) -> SecretVec<T>
where F: FnOnce(&mut [T]),

Instantiates and returns a new SecretVec.

Accepts a callback function that is responsible for initializing its contents. The value yielded to the initialization callback will be filled with garbage bytes.

Example:

let secret = SecretVec::<u8>::new(2, |s| {
    s[0] = 0x10;
    s[1] = 0x20;
});

assert_eq!(*secret.borrow(), [0x10, 0x20]);
Source

pub fn try_new<U, E, F>(f: F) -> Result<SecretVec<T>, E>
where F: FnOnce(&mut [T]) -> Result<U, E>,

Instantiates and returns a new SecretVec. Has equivalent semantics to new, but allows the callback to return success or failure through a Result.

§Errors

Returns Err only if the user-provided callback does.

Source

pub fn len(&self) -> usize

Returns the number of elements in the SecretVec.

Source

pub fn is_empty(&self) -> bool

Returns true if length of the SecretVec is zero.

Source

pub fn size(&self) -> usize

Returns the size in bytes of the SecretVec.

Source

pub fn borrow(&self) -> Ref<'_, T>

Immutably borrows the contents of the SecretVec. Returns a wrapper that ensures the underlying memory is mprotect(2)ed once all borrows exit scope.

Example:

let secret    = SecretVec::<u8>::from(&mut [1, 2][..]);
let secret_r1 = secret.borrow();
let secret_r2 = secret.borrow();

assert_eq!(secret_r1[0], 1);
assert_eq!(secret_r2[1], 2);
assert_eq!(secret_r1, secret_r2);
Source

pub fn borrow_mut(&mut self) -> RefMut<'_, T>

Mutably borrows the contents of the SecretVec. Returns a wrapper that ensures the underlying memory is mprotect(2)ed once this borrow exits scope.

Example:

let mut secret   = SecretVec::<u8>::zero(2);
let mut secret_w = secret.borrow_mut();

secret_w[0] = 0xaa;

assert_eq!(*secret_w, [0xaa, 0x00]);
Source§

impl<T> SecretVec<T>
where T: Bytes + Randomizable,

Source

pub fn random(len: usize) -> SecretVec<T>

Creates a new SecretVec with len elements, filled with cryptographically-random bytes.

Source§

impl<T> SecretVec<T>
where T: Bytes + Zeroable,

Source

pub fn zero(len: usize) -> SecretVec<T>

Creates a new SecretVec with len elements, filled with zeroes.

Trait Implementations§

Source§

impl<T> Clone for SecretVec<T>
where T: Clone + Bytes,

Source§

fn clone(&self) -> SecretVec<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl<T> Debug for SecretVec<T>
where T: Bytes,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<T> From<&mut [T]> for SecretVec<T>
where T: Bytes + Zeroable,

Source§

fn from(data: &mut [T]) -> SecretVec<T>

Creates a new SecretVec from existing, unprotected data, and immediately zeroes out the memory of the data being moved in.

Source§

impl<T> PartialEq for SecretVec<T>
where T: Bytes + ConstantEq,

Source§

fn eq(&self, rhs: &SecretVec<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T> Eq for SecretVec<T>
where T: Eq + Bytes,

Auto Trait Implementations§

§

impl<T> !Freeze for SecretVec<T>

§

impl<T> !RefUnwindSafe for SecretVec<T>

§

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

§

impl<T> !Sync for SecretVec<T>

§

impl<T> Unpin for SecretVec<T>

§

impl<T> UnwindSafe for SecretVec<T>
where T: RefUnwindSafe,

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<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,