aranya_crypto_core/
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, ZeroizeOnDrop};
19
20/// Zeroizing is a a wrapper for any `Z: Zeroize` type which
21/// implements a `Drop` handler which zeroizes dropped values.
22#[derive(Debug, Default, Eq, PartialEq)]
23pub struct Zeroizing<Z: Zeroize>(Z);
24
25impl<Z> Zeroizing<Z>
26where
27    Z: Zeroize,
28{
29    /// Move value inside a `Zeroizing` wrapper which ensures it
30    /// will be zeroized when it's dropped.
31    #[inline(always)]
32    pub fn new(value: Z) -> Self {
33        Self(value)
34    }
35}
36
37impl<Z> Borrow<[u8]> for Zeroizing<Z>
38where
39    Z: Borrow<[u8]> + Zeroize,
40{
41    #[inline(always)]
42    fn borrow(&self) -> &[u8] {
43        self.0.borrow()
44    }
45}
46
47impl<Z> BorrowMut<[u8]> for Zeroizing<Z>
48where
49    Z: BorrowMut<[u8]> + Zeroize,
50{
51    #[inline(always)]
52    fn borrow_mut(&mut self) -> &mut [u8] {
53        self.0.borrow_mut()
54    }
55}
56
57impl<const N: usize, Z> Borrow<[u8; N]> for Zeroizing<Z>
58where
59    Z: Borrow<[u8; N]> + Zeroize,
60{
61    #[inline(always)]
62    fn borrow(&self) -> &[u8; N] {
63        self.0.borrow()
64    }
65}
66
67impl<const N: usize, Z> BorrowMut<[u8; N]> for Zeroizing<Z>
68where
69    Z: BorrowMut<[u8; N]> + Zeroize,
70{
71    #[inline(always)]
72    fn borrow_mut(&mut self) -> &mut [u8; N] {
73        self.0.borrow_mut()
74    }
75}
76
77impl<N: ArrayLength> Borrow<GenericArray<u8, N>> for Zeroizing<GenericArray<u8, N>> {
78    #[inline]
79    fn borrow(&self) -> &GenericArray<u8, N> {
80        &self.0
81    }
82}
83
84impl<N: ArrayLength> BorrowMut<GenericArray<u8, N>> for Zeroizing<GenericArray<u8, N>> {
85    #[inline]
86    fn borrow_mut(&mut self) -> &mut GenericArray<u8, N> {
87        &mut self.0
88    }
89}
90
91impl<Z: Zeroize + Clone> Clone for Zeroizing<Z> {
92    #[inline(always)]
93    fn clone(&self) -> Self {
94        Self(self.0.clone())
95    }
96
97    #[inline(always)]
98    fn clone_from(&mut self, source: &Self) {
99        self.0.zeroize();
100        self.0.clone_from(&source.0);
101    }
102}
103
104impl<Z> From<Z> for Zeroizing<Z>
105where
106    Z: Zeroize,
107{
108    #[inline(always)]
109    fn from(value: Z) -> Zeroizing<Z> {
110        Zeroizing(value)
111    }
112}
113
114impl<Z> Deref for Zeroizing<Z>
115where
116    Z: Zeroize,
117{
118    type Target = Z;
119
120    #[inline(always)]
121    fn deref(&self) -> &Z {
122        &self.0
123    }
124}
125
126impl<Z> DerefMut for Zeroizing<Z>
127where
128    Z: Zeroize,
129{
130    #[inline(always)]
131    fn deref_mut(&mut self) -> &mut Z {
132        &mut self.0
133    }
134}
135
136impl<T, Z> AsRef<T> for Zeroizing<Z>
137where
138    T: ?Sized,
139    Z: AsRef<T> + Zeroize,
140{
141    #[inline(always)]
142    fn as_ref(&self) -> &T {
143        self.0.as_ref()
144    }
145}
146
147impl<T, Z> AsMut<T> for Zeroizing<Z>
148where
149    T: ?Sized,
150    Z: AsMut<T> + Zeroize,
151{
152    #[inline(always)]
153    fn as_mut(&mut self) -> &mut T {
154        self.0.as_mut()
155    }
156}
157
158impl<Z> Zeroize for Zeroizing<Z>
159where
160    Z: Zeroize,
161{
162    fn zeroize(&mut self) {
163        self.0.zeroize();
164    }
165}
166
167impl<Z> ZeroizeOnDrop for Zeroizing<Z> where Z: Zeroize {}
168
169impl<Z> Drop for Zeroizing<Z>
170where
171    Z: Zeroize,
172{
173    fn drop(&mut self) {
174        self.0.zeroize()
175    }
176}