pub struct Prekey { /* private fields */ }sealed only.Expand description
The 16 KiB of random bytes that every sealing key is derived from, locked in RAM where the operating system allows it.
Each SealedFixed and SealedDynamic
keeps an Arc to the Prekey it was sealed under and derives its key afresh on every
access as SHA-256(salt ‖ pre-key). The key itself is never stored, and the stack the
cipher used is overwritten after each access, since the cipher leaves a copy there. A
lossy readout of memory (Spectre-class side channels, Rowhammer, cold boot) that gets any
one of the pre-key’s 131,072 bits wrong yields a useless key, with nothing to say which
bit was wrong. See the sealed module for the whole threat model.
§Lifetime
The pre-key is not a static. It lives as long as the last sealed object, or the last
other Arc, that refers to it. When that one drops, the pre-key is wiped while its pages
are still locked, then unlocked, then freed. An application typically holds one Prekey
for a session and drops it, along with everything sealed under it, at lock or logout.
§Locking
new asks the operating system to keep the pre-key’s pages out of swap
(VirtualLock on Windows, mlock on Unix) and never fails because it could not:
lock_status reports the outcome so the caller can decide. Locking
covers swap only. Hibernation, crash and core dumps, and a clean read of the process’s
memory (a debugger, /proc/<pid>/mem) all still see the pre-key.
§Fork
A child created by fork() shares the parent’s pre-key bytes (copy-on-write) but not
its page locks. A child that should not hold the parent’s sealing material creates its
own Prekey and re-seals what it keeps.
Implementations§
Source§impl Prekey
impl Prekey
Sourcepub fn new() -> Arc<Self> ⓘ
pub fn new() -> Arc<Self> ⓘ
Generates a pre-key from the system RNG and tries to lock its pages in RAM.
Returns an Arc, because every sealed object keeps one.
§Panics
Panics if the system RNG fails, as Fixed::from_random does. A failure to lock
is not a panic; see lock_status.
§Stack use
An unoptimized build constructs the block on the stack before boxing it, so this
call needs a few times the block’s size in free stack: about 192 KiB where the block
is 64 KiB (aarch64 other than Apple, and unlisted targets), less on x86. An optimized
build writes it to the heap directly. Avoiding the stack copy in every profile would
take unsafe (Box::new_zeroed), which this crate forbids.
Sourcepub fn lock_status(&self) -> Result<(), LockError>
pub fn lock_status(&self) -> Result<(), LockError>
Ok(()) if the pre-key’s pages are locked in RAM; otherwise why they are not.