pub struct SecureVec<T>where
T: Zeroize,{ /* private fields */ }
Expand description
A securely allocated, growable vector, just like std::vec::Vec
.
§Security Model
When compiled with the std
feature (the default), it provides several layers of protection:
- Zeroization on Drop: The memory is zeroized when the vector is dropped.
- Memory Locking: The underlying memory pages are locked using
mlock
&madvise
for (Unix) orVirtualLock
&VirtualProtect
for (Windows) to prevent the OS from memory-dump/swap to disk or other processes accessing the memory. - Memory Encryption: On Windows, the memory is also encrypted using
CryptProtectMemory
.
In a no_std
environment, it falls back to providing only the zeroization-on-drop guarantee.
§Program Termination
Direct indexing (e.g., vec[0]
) on a locked vector will cause the operating system
to terminate the process with an access violation error.
Always use the provided scope methods (unlock_slice
, unlock_slice_mut
) for safe access.
§Notes
If you return a new allocated Vec
from one of the unlock methods you are responsible for zeroizing the memory.
§Example
Using SecureBytes
(a type alias for SecureVec<u8>
) to handle a secret key.
use secure_types::{SecureBytes, Zeroize};
// Create a new, empty secure vector.
let mut secret_key = SecureBytes::new().unwrap();
// Push some sensitive data into it.
secret_key.push(0xAB);
secret_key.push(0xCD);
secret_key.push(0xEF);
// The memory is locked here.
// Use a scope to safely access the contents as a slice.
secret_key.unlock_slice(|unlocked_slice| {
assert_eq!(unlocked_slice, &[0xAB, 0xCD, 0xEF]);
});
// Not recommended but if you allocate a new Vec make sure to zeroize it
let mut exposed = secret_key.unlock_slice(|unlocked_slice| {
Vec::from(unlocked_slice)
});
// Do what you need to to do with the new vector
// When you are done with it, zeroize it
exposed.zeroize();
// The memory is automatically locked again when the scope ends.
// When `secret_key` is dropped, its memory is securely zeroized.
Implementations§
Source§impl<T: Zeroize> SecureVec<T>
impl<T: Zeroize> SecureVec<T>
Sourcepub fn new_with_capacity(capacity: usize) -> Result<Self, Error>
pub fn new_with_capacity(capacity: usize) -> Result<Self, Error>
Create a new SecureVec
with the given capacity
Sourcepub fn from_vec(vec: Vec<T>) -> Result<Self, Error>
pub fn from_vec(vec: Vec<T>) -> Result<Self, Error>
Create a new SecureVec
from a Vec
The Vec
is zeroized afterwards
Sourcepub fn from_slice_mut(slice: &mut [T]) -> Result<Self, Error>where
T: Clone + DefaultIsZeroes,
pub fn from_slice_mut(slice: &mut [T]) -> Result<Self, Error>where
T: Clone + DefaultIsZeroes,
Create a new SecureVec
from a mutable slice.
The slice is zeroized afterwards
Sourcepub fn from_slice(slice: &[T]) -> Result<Self, Error>where
T: Clone,
pub fn from_slice(slice: &[T]) -> Result<Self, Error>where
T: Clone,
Create a new SecureVec
from a slice.
The slice is not zeroized, you are responsible for zeroizing it
pub fn len(&self) -> usize
pub fn is_empty(&self) -> bool
pub fn as_ptr(&self) -> *const T
pub fn as_mut_ptr(&mut self) -> *mut u8
Sourcepub fn unlock_slice<F, R>(&self, f: F) -> R
pub fn unlock_slice<F, R>(&self, f: F) -> R
Immutable access to the SecureVec
as &[T]
Sourcepub fn unlock_slice_mut<F, R>(&mut self, f: F) -> R
pub fn unlock_slice_mut<F, R>(&mut self, f: F) -> R
Mutable access to the SecureVec
as &mut [T]
Sourcepub fn unlock_iter<F, R>(&self, f: F) -> R
pub fn unlock_iter<F, R>(&self, f: F) -> R
Immutable access to the SecureVec
as Iter<T>
Sourcepub fn unlock_iter_mut<F, R>(&mut self, f: F) -> R
pub fn unlock_iter_mut<F, R>(&mut self, f: F) -> R
Mutable access to the SecureVec
as IterMut<T>
Sourcepub fn erase(&mut self)
pub fn erase(&mut self)
Erase the underlying data and clears the vector
The memory is locked again and the capacity is preserved for reuse
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clear the vector
This just sets the vector’s len to zero it does not erase the underlying data
pub fn push(&mut self, value: T)
Sourcepub fn reserve(&mut self, additional: usize)
pub fn reserve(&mut self, additional: usize)
Ensures that the vector has enough capacity for at least additional
more elements.
If more capacity is needed, it will reallocate. This may cause the buffer location to change.
§Panics
Panics if the new capacity overflows usize
or if the allocation fails.
Sourcepub fn drain<R>(&mut self, range: R) -> Drain<'_, T> ⓘwhere
R: RangeBounds<usize>,
pub fn drain<R>(&mut self, range: R) -> Drain<'_, T> ⓘwhere
R: RangeBounds<usize>,
Creates a draining iterator that removes the specified range from the vector and yields the removed items.
Note: The vector is unlocked during the lifetime of the Drain
iterator.
The memory is relocked when the Drain
iterator is dropped.
§Panics
Panics if the starting point is greater than the end point or if the end point is greater than the length of the vector.