Skip to main content

spideroak_crypto/
zeroize.rs

1//! Securely zero memory.
2
3// The following code is taken from
4// https://github.com/RustCrypto/utils/tree/6ad2abf2b41feef6f8adf9fdaee5fb9c9b1e3849/zeroize
5// with the addition of `Borrow` and `BorrowMut`.
6//
7// TODO(eric): get rid of this? I don't think we need the Borrow
8// impls anymore.
9
10#![forbid(unsafe_code)]
11
12use core::{
13    borrow::{Borrow, BorrowMut},
14    ops::{Deref, DerefMut},
15};
16
17use generic_array::{ArrayLength, GenericArray};
18pub use zeroize::{zeroize_flat_type, Zeroize, ZeroizeOnDrop};
19
20pub(crate) const fn is_zeroize_on_drop<T>(_: &T)
21where
22    T: ZeroizeOnDrop,
23{
24}
25
26/// Zeroizing is a a wrapper for any `Z: Zeroize` type which
27/// implements a `Drop` handler which zeroizes dropped values.
28#[derive(Debug, Default, Eq, PartialEq)]
29pub struct Zeroizing<Z: Zeroize>(Z);
30
31impl<Z> Zeroizing<Z>
32where
33    Z: Zeroize,
34{
35    /// Move value inside a `Zeroizing` wrapper which ensures it
36    /// will be zeroized when it's dropped.
37    #[inline(always)]
38    pub fn new(value: Z) -> Self {
39        Self(value)
40    }
41}
42
43impl<Z> Borrow<[u8]> for Zeroizing<Z>
44where
45    Z: Borrow<[u8]> + Zeroize,
46{
47    #[inline(always)]
48    fn borrow(&self) -> &[u8] {
49        self.0.borrow()
50    }
51}
52
53impl<Z> BorrowMut<[u8]> for Zeroizing<Z>
54where
55    Z: BorrowMut<[u8]> + Zeroize,
56{
57    #[inline(always)]
58    fn borrow_mut(&mut self) -> &mut [u8] {
59        self.0.borrow_mut()
60    }
61}
62
63impl<const N: usize, Z> Borrow<[u8; N]> for Zeroizing<Z>
64where
65    Z: Borrow<[u8; N]> + Zeroize,
66{
67    #[inline(always)]
68    fn borrow(&self) -> &[u8; N] {
69        self.0.borrow()
70    }
71}
72
73impl<const N: usize, Z> BorrowMut<[u8; N]> for Zeroizing<Z>
74where
75    Z: BorrowMut<[u8; N]> + Zeroize,
76{
77    #[inline(always)]
78    fn borrow_mut(&mut self) -> &mut [u8; N] {
79        self.0.borrow_mut()
80    }
81}
82
83impl<N: ArrayLength> Borrow<GenericArray<u8, N>> for Zeroizing<GenericArray<u8, N>> {
84    #[inline]
85    fn borrow(&self) -> &GenericArray<u8, N> {
86        &self.0
87    }
88}
89
90impl<N: ArrayLength> BorrowMut<GenericArray<u8, N>> for Zeroizing<GenericArray<u8, N>> {
91    #[inline]
92    fn borrow_mut(&mut self) -> &mut GenericArray<u8, N> {
93        &mut self.0
94    }
95}
96
97impl<Z: Zeroize + Clone> Clone for Zeroizing<Z> {
98    #[inline(always)]
99    fn clone(&self) -> Self {
100        Self(self.0.clone())
101    }
102
103    #[inline(always)]
104    fn clone_from(&mut self, source: &Self) {
105        self.0.zeroize();
106        self.0.clone_from(&source.0);
107    }
108}
109
110impl<Z> From<Z> for Zeroizing<Z>
111where
112    Z: Zeroize,
113{
114    #[inline(always)]
115    fn from(value: Z) -> Zeroizing<Z> {
116        Zeroizing(value)
117    }
118}
119
120impl<Z> Deref for Zeroizing<Z>
121where
122    Z: Zeroize,
123{
124    type Target = Z;
125
126    #[inline(always)]
127    fn deref(&self) -> &Z {
128        &self.0
129    }
130}
131
132impl<Z> DerefMut for Zeroizing<Z>
133where
134    Z: Zeroize,
135{
136    #[inline(always)]
137    fn deref_mut(&mut self) -> &mut Z {
138        &mut self.0
139    }
140}
141
142impl<T, Z> AsRef<T> for Zeroizing<Z>
143where
144    T: ?Sized,
145    Z: AsRef<T> + Zeroize,
146{
147    #[inline(always)]
148    fn as_ref(&self) -> &T {
149        self.0.as_ref()
150    }
151}
152
153impl<T, Z> AsMut<T> for Zeroizing<Z>
154where
155    T: ?Sized,
156    Z: AsMut<T> + Zeroize,
157{
158    #[inline(always)]
159    fn as_mut(&mut self) -> &mut T {
160        self.0.as_mut()
161    }
162}
163
164impl<Z> Zeroize for Zeroizing<Z>
165where
166    Z: Zeroize,
167{
168    fn zeroize(&mut self) {
169        self.0.zeroize();
170    }
171}
172
173impl<Z> ZeroizeOnDrop for Zeroizing<Z> where Z: Zeroize {}
174
175impl<Z> Drop for Zeroizing<Z>
176where
177    Z: Zeroize,
178{
179    fn drop(&mut self) {
180        self.0.zeroize()
181    }
182}