veridian_kernel/crypto/
cipher_suite.rs1#![allow(dead_code)]
8
9use alloc::vec::Vec;
10
11use super::CryptoResult;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub(crate) enum CipherSuite {
23 ChaCha20Poly1305,
25 Aes256Gcm,
27}
28
29impl CipherSuite {
30 pub(crate) fn encrypt_aead(
32 &self,
33 key: &[u8],
34 nonce: &[u8],
35 _aad: &[u8],
36 plaintext: &[u8],
37 ) -> CryptoResult<Vec<u8>> {
38 use super::symmetric::SymmetricCipher;
39 match self {
40 Self::ChaCha20Poly1305 => {
41 let cipher = super::symmetric::ChaCha20Poly1305::new(key)?;
42 cipher.encrypt(plaintext, nonce)
43 }
44 Self::Aes256Gcm => {
45 let cipher = super::symmetric::Aes256Gcm::new(key)?;
46 cipher.encrypt(plaintext, nonce)
47 }
48 }
49 }
50
51 pub(crate) fn decrypt_aead(
53 &self,
54 key: &[u8],
55 nonce: &[u8],
56 _aad: &[u8],
57 ciphertext_and_tag: &[u8],
58 ) -> CryptoResult<Vec<u8>> {
59 use super::symmetric::SymmetricCipher;
60 match self {
61 Self::ChaCha20Poly1305 => {
62 let cipher = super::symmetric::ChaCha20Poly1305::new(key)?;
63 cipher.decrypt(ciphertext_and_tag, nonce)
64 }
65 Self::Aes256Gcm => {
66 let cipher = super::symmetric::Aes256Gcm::new(key)?;
67 cipher.decrypt(ciphertext_and_tag, nonce)
68 }
69 }
70 }
71
72 pub(crate) fn key_size(&self) -> usize {
74 match self {
75 Self::ChaCha20Poly1305 => 32,
76 Self::Aes256Gcm => 32,
77 }
78 }
79
80 pub(crate) fn nonce_size(&self) -> usize {
82 match self {
83 Self::ChaCha20Poly1305 => 12,
84 Self::Aes256Gcm => 12,
85 }
86 }
87
88 pub(crate) fn tag_size(&self) -> usize {
90 match self {
91 Self::ChaCha20Poly1305 => 16,
92 Self::Aes256Gcm => 16,
93 }
94 }
95
96 pub(crate) fn algorithm_name(&self) -> &'static str {
98 match self {
99 Self::ChaCha20Poly1305 => "ChaCha20-Poly1305",
100 Self::Aes256Gcm => "AES-256-GCM",
101 }
102 }
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq)]
111pub(crate) enum HmacAlgorithm {
112 HmacSha256,
114 HmacBlake2s,
116}
117
118impl HmacAlgorithm {
119 pub(crate) fn compute(&self, key: &[u8], data: &[u8]) -> [u8; 32] {
121 match self {
122 Self::HmacSha256 => hmac_sha256(key, data),
123 Self::HmacBlake2s => hmac_blake2s(key, data),
124 }
125 }
126
127 pub(crate) fn output_size(&self) -> usize {
129 match self {
130 Self::HmacSha256 => 32,
131 Self::HmacBlake2s => 32,
132 }
133 }
134}
135
136fn hmac_sha256(key: &[u8], data: &[u8]) -> [u8; 32] {
138 let block_size = 64;
139 let mut padded_key = [0u8; 64];
140
141 if key.len() > block_size {
142 let hash = super::hash::sha256(key);
143 padded_key[..32].copy_from_slice(hash.as_bytes());
144 } else {
145 padded_key[..key.len()].copy_from_slice(key);
146 }
147
148 let mut ipad = [0x36u8; 64];
150 for i in 0..64 {
151 ipad[i] ^= padded_key[i];
152 }
153 let mut inner_data = Vec::with_capacity(64 + data.len());
154 inner_data.extend_from_slice(&ipad);
155 inner_data.extend_from_slice(data);
156 let inner_hash = super::hash::sha256(&inner_data);
157
158 let mut opad = [0x5cu8; 64];
160 for i in 0..64 {
161 opad[i] ^= padded_key[i];
162 }
163 let mut outer_data = Vec::with_capacity(64 + 32);
164 outer_data.extend_from_slice(&opad);
165 outer_data.extend_from_slice(inner_hash.as_bytes());
166 let outer_hash = super::hash::sha256(&outer_data);
167
168 *outer_hash.as_bytes()
169}
170
171fn hmac_blake2s(key: &[u8], data: &[u8]) -> [u8; 32] {
173 use super::hash::Blake2s;
174
175 let block_size = 64;
176 let mut padded_key = [0u8; 64];
177
178 if key.len() > block_size {
179 let hash = super::hash::blake2s_hash(key, 32);
180 padded_key[..32].copy_from_slice(&hash);
181 } else {
182 padded_key[..key.len()].copy_from_slice(key);
183 }
184
185 let mut ipad = [0x36u8; 64];
187 for i in 0..64 {
188 ipad[i] ^= padded_key[i];
189 }
190 let mut inner = Blake2s::new(32);
191 inner.update(&ipad);
192 inner.update(data);
193 let inner_hash = inner.finalize();
194
195 let mut opad = [0x5cu8; 64];
197 for i in 0..64 {
198 opad[i] ^= padded_key[i];
199 }
200 let mut outer = Blake2s::new(32);
201 outer.update(&opad);
202 outer.update(&inner_hash);
203 outer.finalize()
204}
205
206#[derive(Debug, Clone, Copy, PartialEq, Eq)]
212pub(crate) enum KdfAlgorithm {
213 HkdfBlake2s,
215}
216
217impl KdfAlgorithm {
218 pub(crate) fn extract(&self, salt: &[u8], ikm: &[u8]) -> [u8; 32] {
220 match self {
221 Self::HkdfBlake2s => HmacAlgorithm::HmacBlake2s.compute(salt, ikm),
222 }
223 }
224
225 pub(crate) fn expand(&self, prk: &[u8], info: &[u8]) -> [u8; 32] {
229 match self {
230 Self::HkdfBlake2s => HmacAlgorithm::HmacBlake2s.compute(prk, info),
231 }
232 }
233
234 pub(crate) fn extract_expand2(
240 &self,
241 chaining_key: &[u8; 32],
242 input: &[u8],
243 ) -> ([u8; 32], [u8; 32]) {
244 match self {
245 Self::HkdfBlake2s => {
246 let prk = HmacAlgorithm::HmacBlake2s.compute(chaining_key, input);
247 let t1 = HmacAlgorithm::HmacBlake2s.compute(&prk, &[0x01]);
248 let mut t1_input = [0u8; 33];
249 t1_input[..32].copy_from_slice(&t1);
250 t1_input[32] = 0x02;
251 let t2 = HmacAlgorithm::HmacBlake2s.compute(&prk, &t1_input);
252 (t1, t2)
253 }
254 }
255 }
256
257 pub(crate) fn extract_expand3(
263 &self,
264 chaining_key: &[u8; 32],
265 input: &[u8],
266 ) -> ([u8; 32], [u8; 32], [u8; 32]) {
267 match self {
268 Self::HkdfBlake2s => {
269 let prk = HmacAlgorithm::HmacBlake2s.compute(chaining_key, input);
270 let t1 = HmacAlgorithm::HmacBlake2s.compute(&prk, &[0x01]);
271 let mut t1_input = [0u8; 33];
272 t1_input[..32].copy_from_slice(&t1);
273 t1_input[32] = 0x02;
274 let t2 = HmacAlgorithm::HmacBlake2s.compute(&prk, &t1_input);
275 let mut t2_input = [0u8; 33];
276 t2_input[..32].copy_from_slice(&t2);
277 t2_input[32] = 0x03;
278 let t3 = HmacAlgorithm::HmacBlake2s.compute(&prk, &t2_input);
279 (t1, t2, t3)
280 }
281 }
282 }
283}