Struct SecretBox

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

A type for protecting fixed-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 SecretBox 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, SecretBox 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 SecretBox

Initialize a SecretBox with cryptographically random data:

let secret = SecretBox::<u128>::random();

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

§Example: move mutable data into a SecretBox

Existing data can be moved into a SecretBox. 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 = 0x0011223344556677u128;

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

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

§Example: compilation failure from incompatible borrows

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

let mut secret   = SecretBox::<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 SecretBox can’t have multiple outstanding borrow_muts at the same time.

let mut secret   = SecretBox::<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: Bytes> SecretBox<T>

Source

pub fn new<F>(f: F) -> Self
where F: FnOnce(&mut T),

Instantiates and returns a new SecretBox.

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 = SecretBox::<u8>::new(|s| *s = 0x20);

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

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

Instantiates and returns a new SecretBox. 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 size(&self) -> usize

Returns the size in bytes of the SecretBox.

Source

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

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

Example:

let secret    = SecretBox::<u8>::from(&mut 127);
let secret_r1 = secret.borrow();
let secret_r2 = secret.borrow();

assert_eq!(*secret_r1, 127);
assert_eq!(*secret_r2, 127);
assert_eq!(secret_r1, secret_r2);
Source

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

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

Example:

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

*secret_w = 0xaa;

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

impl<T: Bytes + Randomizable> SecretBox<T>

Source

pub fn random() -> Self

Creates a new SecretBox filled with cryptographically-random bytes.

Source§

impl<T: Bytes + Zeroable> SecretBox<T>

Source

pub fn zero() -> Self

Creates a new SecretBox filled with zeroes.

Trait Implementations§

Source§

impl<T: Clone + Bytes> Clone for SecretBox<T>

Source§

fn clone(&self) -> SecretBox<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: Bytes> Debug for SecretBox<T>

Source§

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

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

impl<T: Bytes + Zeroable> From<&mut T> for SecretBox<T>

Source§

fn from(data: &mut T) -> Self

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

Source§

impl<T: Bytes + ConstantEq> PartialEq for SecretBox<T>

Source§

fn eq(&self, rhs: &Self) -> 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 + Bytes> Eq for SecretBox<T>

Auto Trait Implementations§

§

impl<T> !Freeze for SecretBox<T>

§

impl<T> !RefUnwindSafe for SecretBox<T>

§

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

§

impl<T> !Sync for SecretBox<T>

§

impl<T> Unpin for SecretBox<T>

§

impl<T> UnwindSafe for SecretBox<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<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<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.