1use crate::{
4 constants::{CIPHERKEYLEN, MAXBLOCKLEN, MAXHASHLEN, TAGLEN},
5 Error,
6};
7use rand_core::{CryptoRng, RngCore};
8
9pub trait Random: CryptoRng + RngCore + Send + Sync {}
11
12pub trait Dh: Send + Sync {
14 fn name(&self) -> &'static str;
16
17 fn pub_len(&self) -> usize;
19
20 fn priv_len(&self) -> usize;
22
23 fn set(&mut self, privkey: &[u8]);
25
26 fn generate(&mut self, rng: &mut dyn Random);
28
29 fn pubkey(&self) -> &[u8];
31
32 fn privkey(&self) -> &[u8];
34
35 fn dh(&self, pubkey: &[u8], out: &mut [u8]) -> Result<(), Error>;
37}
38
39pub trait Cipher: Send + Sync {
41 fn name(&self) -> &'static str;
43
44 fn set(&mut self, key: &[u8]);
46
47 fn encrypt(&self, nonce: u64, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) -> usize;
49
50 fn decrypt(
52 &self,
53 nonce: u64,
54 authtext: &[u8],
55 ciphertext: &[u8],
56 out: &mut [u8],
57 ) -> Result<usize, Error>;
58
59 fn rekey(&mut self) {
62 let mut ciphertext = [0; CIPHERKEYLEN + TAGLEN];
63 let ciphertext_len = self.encrypt(u64::MAX, &[], &[0; CIPHERKEYLEN], &mut ciphertext);
64 assert_eq!(ciphertext_len, ciphertext.len());
65 self.set(&ciphertext[..CIPHERKEYLEN]);
66 }
67}
68
69pub trait Hash: Send + Sync {
71 fn name(&self) -> &'static str;
73
74 fn block_len(&self) -> usize;
76
77 fn hash_len(&self) -> usize;
79
80 fn reset(&mut self);
82
83 fn input(&mut self, data: &[u8]);
85
86 fn result(&mut self, out: &mut [u8]);
88
89 fn hmac(&mut self, key: &[u8], data: &[u8], out: &mut [u8]) {
93 assert!(key.len() <= self.block_len());
94 let block_len = self.block_len();
95 let hash_len = self.hash_len();
96 let mut ipad = [0x36u8; MAXBLOCKLEN];
97 let mut opad = [0x5cu8; MAXBLOCKLEN];
98 for count in 0..key.len() {
99 ipad[count] ^= key[count];
100 opad[count] ^= key[count];
101 }
102 self.reset();
103 self.input(&ipad[..block_len]);
104 self.input(data);
105 let mut inner_output = [0u8; MAXHASHLEN];
106 self.result(&mut inner_output);
107 self.reset();
108 self.input(&opad[..block_len]);
109 self.input(&inner_output[..hash_len]);
110 self.result(out);
111 }
112
113 fn hkdf(
117 &mut self,
118 chaining_key: &[u8],
119 input_key_material: &[u8],
120 outputs: usize,
121 out1: &mut [u8],
122 out2: &mut [u8],
123 out3: &mut [u8],
124 ) {
125 let hash_len = self.hash_len();
126 let mut temp_key = [0u8; MAXHASHLEN];
127 self.hmac(chaining_key, input_key_material, &mut temp_key);
128 self.hmac(&temp_key, &[1u8], out1);
129 if outputs == 1 {
130 return;
131 }
132
133 let mut in2 = [0u8; MAXHASHLEN + 1];
134 copy_slices!(out1[0..hash_len], &mut in2);
135 in2[hash_len] = 2;
136 self.hmac(&temp_key, &in2[..=hash_len], out2);
137 if outputs == 2 {
138 return;
139 }
140
141 let mut in3 = [0u8; MAXHASHLEN + 1];
142 copy_slices!(out2[0..hash_len], &mut in3);
143 in3[hash_len] = 3;
144 self.hmac(&temp_key, &in3[..=hash_len], out3);
145 }
146}
147
148#[cfg(feature = "hfs")]
150pub trait Kem: Send + Sync {
151 fn name(&self) -> &'static str;
153
154 fn pub_len(&self) -> usize;
156
157 fn ciphertext_len(&self) -> usize;
159
160 fn shared_secret_len(&self) -> usize;
162
163 fn generate(&mut self, rng: &mut dyn Random);
165
166 fn pubkey(&self) -> &[u8];
168
169 #[must_use]
171 fn encapsulate(
172 &self,
173 pubkey: &[u8],
174 shared_secret_out: &mut [u8],
175 ciphertext_out: &mut [u8],
176 ) -> Result<(usize, usize), ()>;
177
178 #[must_use]
180 fn decapsulate(&self, ciphertext: &[u8], shared_secret_out: &mut [u8]) -> Result<usize, ()>;
181}