Skip to main content

SealedFixed

Struct SealedFixed 

Source
pub struct SealedFixed<const N: usize> { /* private fields */ }
Available on crate feature sealed only.
Expand description

A fixed-size byte secret held encrypted in RAM while idle, opened for one closure call at a time. The sealed counterpart of Fixed<[u8; N]>. Requires the sealed feature.

The ciphertext, tag and salt sit inline and are not secret. Each access derives the sealing key from the Prekey, decrypts in place into a stack Fixed<[u8; N]>, hands the closure a reference, and lets that wrapper’s Drop wipe it. Nothing is allocated per access.

There is no expose_secret, and the type does not implement RevealSecret: a reference that outlives the call would need plaintext that outlives it too, which is what sealing exists to prevent. Generic code that only needs scoped access can take RevealScoped, which this type and every RevealSecret type implement.

use secure_gate::{Fixed, Prekey, SealedFixed};

let prekey = Prekey::new();
let key = SealedFixed::seal(Fixed::new([0xAB; 32]), &prekey);
key.with_secret(|bytes| assert_eq!(bytes[0], 0xAB));
assert_eq!(format!("{key:?}"), "[REDACTED]");

§Panics

Every access panics if the sealed bytes fail to authenticate: they were modified or corrupted in memory and cannot be recovered. The temporary is wiped and the stack below the call scrubbed before the panic continues.

Implementations§

Source§

impl<const N: usize> SealedFixed<N>

Source

pub fn seal(secret: Fixed<[u8; N]>, prekey: &Arc<Prekey>) -> Self

Seals secret under prekey. The plain wrapper is consumed and wiped on drop.

Source

pub fn from_random(prekey: &Arc<Prekey>) -> Self

Generates the secret from the system RNG and seals it.

§Panics

Panics if the system RNG fails, as Fixed::from_random does.

Source

pub fn with_secret<F, R>(&self, f: F) -> R
where F: FnOnce(&[u8; N]) -> R,

Decrypts into a temporary for the length of f, then wipes the temporary.

Source

pub fn with_secret_mut<F, R>(&mut self, f: F) -> R
where F: FnOnce(&mut [u8; N]) -> R,

Decrypts into a temporary, lets f change it, then seals the result under a fresh salt and wipes the temporary.

If f panics, the temporary is still wiped, the stack scrubbed, and the sealed value left as it was.

Source

pub fn unseal(self) -> Fixed<[u8; N]>

Opens the secret back into a plain Fixed. Protection from sealing ends here; the returned wrapper still wipes on drop, and is an ordinary Fixed from then on, moves included: returning it by value can leave a copy in the caller’s frame that nothing wipes (SECURITY.md §1; one was measured in a release build). To read the secret, prefer with_secret, which leaves nothing.

Source

pub const fn len(&self) -> usize

The secret’s length in bytes, N.

Source

pub const fn is_empty(&self) -> bool

N == 0. A zero-length Fixed does not compile, so this is false for every SealedFixed that can exist; it is here for symmetry with len.

Trait Implementations§

Source§

impl<const N: usize> ConstantTimeEq for SealedFixed<N>

Available on crate feature ct-eq only.

Constant-time equality: opens both sides and compares the plaintext with subtle. Comparing ciphertexts could not work, since every seal has its own salt.

Source§

fn ct_eq(&self, other: &Self) -> bool

Performs equality comparison in constant time. Read more
Source§

impl<const N: usize> Debug for SealedFixed<N>

Always prints [REDACTED]: no salt, no tag, no length.

Source§

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

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

impl<const N: usize> RevealScoped for SealedFixed<N>

Source§

type Inner = [u8; N]

The secret’s type as the closure sees it.
Source§

fn with_secret<F, R>(&self, f: F) -> R
where F: FnOnce(&[u8; N]) -> R,

Calls f with a reference to the secret that cannot outlive the call.

Auto Trait Implementations§

§

impl<const N: usize> Freeze for SealedFixed<N>
where [u8; N]: Freeze,

§

impl<const N: usize> RefUnwindSafe for SealedFixed<N>
where [u8; N]: RefUnwindSafe,

§

impl<const N: usize> Send for SealedFixed<N>
where [u8; N]: Send,

§

impl<const N: usize> Sync for SealedFixed<N>
where [u8; N]: Sync,

§

impl<const N: usize> Unpin for SealedFixed<N>
where [u8; N]: Unpin,

§

impl<const N: usize> UnsafeUnpin for SealedFixed<N>
where [u8; N]: UnsafeUnpin,

§

impl<const N: usize> UnwindSafe for SealedFixed<N>
where [u8; N]: 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> 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> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.