1pub trait U8Array: Sized {
8 fn new() -> Self;
10 fn new_with(_: u8) -> Self;
12 fn from_slice(_: &[u8]) -> Self;
18 fn len() -> usize;
20 fn as_slice(&self) -> &[u8];
22 fn as_mut(&mut self) -> &mut [u8];
24 fn clone(&self) -> Self {
27 Self::from_slice(self.as_slice())
28 }
29}
30
31macro_rules! impl_array {
32 ($len:expr) => {
33 impl U8Array for [u8; $len] {
34 fn new() -> Self {
35 [0u8; $len]
36 }
37 fn new_with(x: u8) -> Self {
38 [x; $len]
39 }
40 fn from_slice(data: &[u8]) -> Self {
41 let mut a = [0u8; $len];
42 a.copy_from_slice(data);
43 a
44 }
45 fn len() -> usize {
46 $len
47 }
48 fn as_slice(&self) -> &[u8] {
49 self
50 }
51 fn as_mut(&mut self) -> &mut [u8] {
52 self
53 }
54 }
55 };
56}
57
58impl_array!(32);
59impl_array!(64);
60impl_array!(128);
61
62pub trait DH {
64 type Key: U8Array;
66 type Pubkey: U8Array;
68 type Output: U8Array;
70
71 fn name() -> &'static str;
73
74 fn genkey() -> Self::Key;
76
77 fn pubkey(_: &Self::Key) -> Self::Pubkey;
79
80 fn dh(_: &Self::Key, _: &Self::Pubkey) -> Result<Self::Output, ()>;
82}
83
84pub trait Cipher {
86 fn name() -> &'static str;
88 type Key: U8Array;
90
91 fn key_len() -> usize {
93 Self::Key::len()
94 }
95
96 fn tag_len() -> usize {
100 16
101 }
102
103 fn encrypt(k: &Self::Key, nonce: u64, ad: &[u8], plaintext: &[u8], out: &mut [u8]);
109
110 fn encrypt_in_place(
117 k: &Self::Key,
118 nonce: u64,
119 ad: &[u8],
120 in_out: &mut [u8],
121 plaintext_len: usize,
122 ) -> usize;
123
124 fn decrypt(
130 k: &Self::Key,
131 nonce: u64,
132 ad: &[u8],
133 ciphertext: &[u8],
134 out: &mut [u8],
135 ) -> Result<(), ()>;
136
137 fn decrypt_in_place(
144 k: &Self::Key,
145 nonce: u64,
146 ad: &[u8],
147 in_out: &mut [u8],
148 ciphertext_len: usize,
149 ) -> Result<usize, ()>;
150
151 fn rekey(k: &Self::Key) -> Self::Key {
153 let mut k1 = [0u8; 48];
155 Self::encrypt(k, 0u64.wrapping_sub(1), &[], &[0; 32], &mut k1);
156 Self::Key::from_slice(&k1[..32])
157 }
158}
159
160pub trait Hash: Default {
162 fn name() -> &'static str;
164
165 type Block: U8Array;
167 type Output: U8Array;
169
170 fn block_len() -> usize {
172 Self::Block::len()
173 }
174
175 fn hash_len() -> usize {
177 Self::Output::len()
178 }
179
180 fn reset(&mut self) {
182 *self = Default::default();
183 }
184
185 fn input(&mut self, data: &[u8]);
187
188 fn result(&mut self) -> Self::Output;
190
191 fn hash(data: &[u8]) -> Self::Output {
193 let mut h: Self = Default::default();
194 h.input(data);
195 h.result()
196 }
197
198 fn hmac_many(key: &[u8], data: &[&[u8]]) -> Self::Output {
200 assert!(key.len() <= Self::block_len());
201
202 let mut ipad = Self::Block::new_with(0x36u8);
203 let mut opad = Self::Block::new_with(0x5cu8);
204
205 let ipad = ipad.as_mut();
206 let opad = opad.as_mut();
207
208 for (i, b) in key.iter().enumerate() {
209 ipad[i] ^= b;
210 opad[i] ^= b;
211 }
212
213 let mut hasher: Self = Default::default();
214 hasher.input(ipad);
215 for d in data {
216 hasher.input(d);
217 }
218 let inner_output = hasher.result();
219
220 hasher.reset();
221 hasher.input(opad);
222 hasher.input(inner_output.as_slice());
223 hasher.result()
224 }
225
226 fn hmac(key: &[u8], data: &[u8]) -> Self::Output {
228 Self::hmac_many(key, &[data])
229 }
230
231 fn hkdf(chaining_key: &[u8], input_key_material: &[u8]) -> (Self::Output, Self::Output) {
233 let temp_key = Self::hmac(chaining_key, input_key_material);
234 let out1 = Self::hmac(temp_key.as_slice(), &[1u8]);
235 let out2 = Self::hmac_many(temp_key.as_slice(), &[out1.as_slice(), &[2u8]]);
236 (out1, out2)
237 }
238
239 fn hkdf3(
241 chaining_key: &[u8],
242 input_key_material: &[u8],
243 ) -> (Self::Output, Self::Output, Self::Output) {
244 let temp_key = Self::hmac(chaining_key, input_key_material);
245 let out1 = Self::hmac(temp_key.as_slice(), &[1u8]);
246 let out2 = Self::hmac_many(temp_key.as_slice(), &[out1.as_slice(), &[2u8]]);
247 let out3 = Self::hmac_many(temp_key.as_slice(), &[out2.as_slice(), &[3u8]]);
248 (out1, out2, out3)
249 }
250}