tc_zeroize/traits.rs
1//! Contracts for explicit erasure and opt-in erasure on drop.
2
3/// Explicitly erases a value's contents in its current storage.
4///
5/// Implementations must use volatile writes followed by a compiler fence, or
6/// delegate to implementations that do. Composite types should clear every
7/// secret-bearing field. This does not impose a drop policy or erase copies,
8/// inaccessible old allocations, or padding bytes.
9///
10/// ```
11/// use tc_zeroize::Zeroize;
12///
13/// struct Scratch([u32; 2]);
14/// impl Zeroize for Scratch {
15/// fn zeroize(&mut self) {
16/// self.0.zeroize();
17/// }
18/// }
19/// let mut scratch = Scratch([5, 9]);
20/// scratch.zeroize();
21/// assert_eq!(scratch.0, [0; 2]);
22/// ```
23pub trait Zeroize {
24 /// Overwrites the contents using volatile writes and a compiler fence to
25 /// prevent removal of the wipe.
26 fn zeroize(&mut self);
27}
28
29/// Marks a type that erases its contents when dropped.
30///
31/// Implementors must provide their own `Drop` implementation that calls
32/// [`Zeroize::zeroize`]. This marker generates no behavior and does not enforce
33/// that requirement. It expresses a policy for types that know they hold
34/// secrets, rather than for general-purpose storage types.
35///
36/// ```
37/// use tc_zeroize::{Zeroize, ZeroizeOnDrop};
38///
39/// struct Secret([u8; 32]);
40/// impl Zeroize for Secret {
41/// fn zeroize(&mut self) {
42/// self.0.zeroize();
43/// }
44/// }
45/// impl Drop for Secret {
46/// fn drop(&mut self) {
47/// self.zeroize();
48/// }
49/// }
50/// impl ZeroizeOnDrop for Secret {}
51/// let _secret = Secret([7; 32]);
52/// ```
53pub trait ZeroizeOnDrop {}