1use runtime::{
5 locked_memory::LockedMemory,
6 memories::{buffer::Buffer, noncontiguous_memory::*},
7};
8use serde::{Deserialize, Serialize};
9use std::{
10 fmt::Debug,
11 hash::{Hash, Hasher},
12 marker::PhantomData,
13};
14use zeroize::{ZeroizeOnDrop, Zeroizing};
15
16pub trait BoxProvider: 'static + Sized + Ord + PartialOrd {
18 type Error: Debug;
19
20 fn box_key_len() -> usize;
22 fn box_overhead() -> usize;
24
25 fn box_seal(key: &Key<Self>, ad: &[u8], data: &[u8]) -> Result<Vec<u8>, Self::Error>;
27
28 fn box_open(key: &Key<Self>, ad: &[u8], data: &[u8]) -> Result<Vec<u8>, Self::Error>;
30
31 fn random_buf(buf: &mut [u8]) -> Result<(), Self::Error>;
33
34 fn random_vec(len: usize) -> Result<Zeroizing<Vec<u8>>, Self::Error> {
36 let mut buf = Zeroizing::new(vec![0; len]);
37 Self::random_buf(&mut buf)?;
38 Ok(buf)
39 }
40}
41
42#[derive(Serialize, Deserialize, ZeroizeOnDrop)]
45pub struct Key<T: BoxProvider> {
46 pub key: Buffer<u8>,
48
49 #[serde(skip_serializing, skip_deserializing)]
51 _box_provider: PhantomData<T>,
52}
53
54impl<T: BoxProvider> Key<T> {
55 pub fn random() -> Self {
57 Self {
58 key: {
59 Buffer::alloc(
60 T::random_vec(T::box_key_len())
61 .expect("failed to generate random key")
62 .as_slice(),
63 T::box_key_len(),
64 )
65 },
66 _box_provider: PhantomData,
67 }
68 }
69
70 pub fn load(key: Zeroizing<Vec<u8>>) -> Option<Self> {
74 if key.len() == T::box_key_len() {
75 Some(Self {
76 key: Buffer::alloc(key.as_slice(), T::box_key_len()),
77 _box_provider: PhantomData,
78 })
79 } else {
80 None
81 }
82 }
83}
84
85impl<T: BoxProvider> Clone for Key<T> {
86 fn clone(&self) -> Self {
87 Self {
88 key: self.key.clone(),
89 _box_provider: PhantomData,
90 }
91 }
92}
93
94impl<T: BoxProvider> Eq for Key<T> {}
95
96impl<T: BoxProvider> PartialEq for Key<T> {
97 fn eq(&self, other: &Self) -> bool {
98 self.key == other.key && self._box_provider == other._box_provider
99 }
100}
101
102impl<T: BoxProvider> PartialOrd for Key<T> {
103 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
104 Some(self.cmp(other))
105 }
106}
107
108impl<T: BoxProvider> Ord for Key<T> {
109 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
110 self.key.borrow().cmp(&*other.key.borrow())
111 }
112}
113
114impl<T: BoxProvider> Hash for Key<T> {
115 fn hash<H: Hasher>(&self, state: &mut H) {
116 self.key.borrow().hash(state);
117 self._box_provider.hash(state);
118 }
119}
120
121impl<T: BoxProvider> Debug for Key<T> {
122 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 write!(f, "KeyData")
124 }
125}
126
127pub trait Encrypt<T: From<Vec<u8>>>: AsRef<[u8]> {
129 fn encrypt<P: BoxProvider, AD: AsRef<[u8]>>(&self, key: &Key<P>, ad: AD) -> Result<T, P::Error> {
131 let sealed = P::box_seal(key, ad.as_ref(), self.as_ref())?;
132 Ok(T::from(sealed))
133 }
134}
135
136#[derive(Debug)]
137pub enum DecryptError<E: Debug> {
138 Invalid,
139 Provider(E),
140}
141
142pub trait Decrypt<T: TryFrom<Vec<u8>>>: AsRef<[u8]> {
144 fn decrypt<P: BoxProvider, AD: AsRef<[u8]>>(&self, key: &Key<P>, ad: AD) -> Result<T, DecryptError<P::Error>> {
146 let opened = P::box_open(key, ad.as_ref(), self.as_ref()).map_err(DecryptError::Provider)?;
147 T::try_from(opened).map_err(|_| DecryptError::Invalid)
148 }
149}
150
151#[derive(Serialize, Deserialize, ZeroizeOnDrop)]
156pub struct NCKey<T: BoxProvider> {
157 pub key: NonContiguousMemory,
159
160 #[serde(skip_serializing, skip_deserializing)]
162 _box_provider: PhantomData<T>,
163}
164
165impl<T: BoxProvider> NCKey<T> {
166 pub fn random() -> Self {
168 Self {
169 key: {
170 NonContiguousMemory::alloc(
171 T::random_vec(T::box_key_len())
172 .expect("failed to generate random key")
173 .as_slice(),
174 T::box_key_len(),
175 NC_CONFIGURATION,
176 )
177 .unwrap_or_else(|e| panic!("{}", e))
178 },
179 _box_provider: PhantomData,
180 }
181 }
182
183 pub fn load(key: Zeroizing<Vec<u8>>) -> Option<Self> {
187 if key.len() == T::box_key_len() {
188 Some(Self {
189 key: NonContiguousMemory::alloc(key.as_slice(), T::box_key_len(), NC_CONFIGURATION)
190 .unwrap_or_else(|e| panic!("{}", e)),
191 _box_provider: PhantomData,
192 })
193 } else {
194 None
195 }
196 }
197
198 pub fn encrypt_key<AD: AsRef<[u8]>>(&self, data: &Key<T>, ad: AD) -> Result<Vec<u8>, T::Error> {
199 let key = Key {
200 key: self.key.unlock().unwrap_or_else(|e| panic!("{}", e)),
201 _box_provider: PhantomData,
202 };
203 T::box_seal(&key, ad.as_ref(), &data.key.borrow())
204 }
205
206 pub fn decrypt_key<AD: AsRef<[u8]>>(&self, data: Vec<u8>, ad: AD) -> Result<Key<T>, DecryptError<T::Error>> {
207 let key = Key {
208 key: self.key.unlock().unwrap_or_else(|e| panic!("{}", e)),
209 _box_provider: PhantomData,
210 };
211 let opened = T::box_open(&key, ad.as_ref(), &data).map_err(DecryptError::Provider)?;
212 Key::load(opened.into()).ok_or(DecryptError::Invalid)
213 }
214
215 }
222
223impl<T: BoxProvider> Clone for NCKey<T> {
224 fn clone(&self) -> Self {
225 Self {
226 key: self.key.clone(),
227 _box_provider: PhantomData,
228 }
229 }
230}
231
232impl<T: BoxProvider> Eq for NCKey<T> {}
233
234impl<T: BoxProvider> PartialEq for NCKey<T> {
235 fn eq(&self, other: &Self) -> bool {
236 let buf1 = self.key.unlock().unwrap_or_else(|e| panic!("{}", e));
237 let buf2 = other.key.unlock().unwrap_or_else(|e| panic!("{}", e));
238 buf1 == buf2 && self._box_provider == other._box_provider
239 }
240}
241
242impl<T: BoxProvider> PartialOrd for NCKey<T> {
243 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
244 Some(self.cmp(other))
245 }
246}
247
248impl<T: BoxProvider> Ord for NCKey<T> {
249 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
250 let buf1 = self.key.unlock().unwrap_or_else(|e| panic!("{}", e));
251 let buf2 = other.key.unlock().unwrap_or_else(|e| panic!("{}", e));
252 let b = buf1.borrow().cmp(&*buf2.borrow());
253 b
254 }
255}
256
257impl<T: BoxProvider> Hash for NCKey<T> {
258 fn hash<H: Hasher>(&self, state: &mut H) {
259 let buf = self.key.unlock().unwrap_or_else(|e| panic!("{}", e));
260 buf.borrow().hash(state);
261 self._box_provider.hash(state);
262 }
263}
264
265impl<T: BoxProvider> Debug for NCKey<T> {
266 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
267 write!(f, "KeyData")
268 }
269}