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

A type for protecting secrets allocated on the stack.

Stack-allocated secrets have distinct security needs from heap-allocated secrets, and should be preferred when possible. They provide the following guarantees:

  • 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 out when no longer in use
  • they are borrowed for their entire lifespan, so cannot be moved
  • they are best-effort compared in constant time
  • they are best-effort prevented from being printed by Debug
  • they are best-effort prevented from being Cloned

To fulfill these guarantees, Secrets are constructed in an atypical pattern. Rather than having new return a newly-created instance, new accepts a callback argument that is provided with a mutably borrowed wrapper around the data in question. This wrapper Derefs into the desired type, with replacement implementations of Debug, PartialEq, and Eq to prevent accidental misuse.

Users must take care when dereferencing secrets as this will provide direct access to the underlying type. If the bare type implements traits like Clone, Debug, and PartialEq, those methods can be called directly and will not benefit from the protections provided by this wrapper.

Users must also take care to avoid unintentionally invoking Copy on the underlying data, as doing so will result in secret data being copied out of the Secret, thus losing the protections provided by this library. Be careful not to invoke methods that take ownership of self or functions that move parameters with secret data, since doing so will implicitly create copies.

Example: generate a cryptographically-random 128-bit Secret

Initialize a Secret with cryptographically random data:

Secret::<[u8; 16]>::random(|s| {
    // use `s` as if it were a `&mut [u8; 16]`
});

Example: move mutable data into a Secret

Existing data can be moved into a Secret. 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 Secret before
// being zeroed out
Secret::from(&mut value, |s| {
    assert_eq!(*s, [1, 2, 3, 4]);
});

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

Implementations

Creates a new Secret and invokes the provided callback with a wrapper to the protected memory. This memory will be filled with a well-defined, arbitrary byte pattern, and should be initialized to something meaningful before actual use.

Panics

This function will panic if the underlying call to mlock(2) (VirtualLock on windows) fails.

use std::fs::File;
use std::io::prelude::*;

Secret::<[u8; 32]>::new(|mut s| {
    File::open("/dev/urandom")?.read_exact(&mut s[..])
});

Creates a new Secret filled with zeroed bytes and invokes the callback with a wrapper to the protected memory.

Secret::<u8>::zero(|s| {
    assert_eq!(*s, 0);
});

Creates a new Secret from existing, unprotected data, and immediately zeroes out the memory of the data being moved in. Invokes the callback with a wrapper to the protected memory.

let mut bytes : [u32; 4] = [1, 2, 3, 4];

Secret::from(&mut bytes, |s| {
    assert_eq!(*s, [1, 2, 3, 4]);
});

assert_eq!(bytes, [0, 0, 0, 0]);

Creates a new Secret filled with random bytes and invokes the callback with a wrapper to the protected memory.

Secret::<u128>::random(|s| {
    // s is filled with random bytes
})

Trait Implementations

Ensures that the Secret’s underlying memory is munlocked and zeroed when it leaves scope.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.