melodies_core/
cipher_state.rs1use crate::crypto::{Cipher, CIPHER_KEY_LEN, TAG_SIZE};
2use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
3
4#[derive(Zeroize, ZeroizeOnDrop)]
5pub struct CipherState<Nonce = u64> {
6 key: [u8; CIPHER_KEY_LEN],
7 #[zeroize(skip)]
8 pub(crate) cipher: &'static dyn Cipher,
9 #[zeroize(skip)]
11 pub nonce: Nonce,
12}
13
14impl<T> CipherState<T> {
15 pub fn encrypt_with_nonce(&self, n: u64, ad: &[u8], buf: &mut [u8]) {
18 assert_ne!(n, u64::MAX);
19 let (buf, tag) = buf.split_at_mut(buf.len() - TAG_SIZE);
20 let tag = tag.try_into().unwrap();
21 self.cipher.encrypt(&self.key, n, ad, buf, tag);
22 }
23 pub fn decrypt_with_nonce<'a>(&self, n: u64, ad: &[u8], buf: &'a mut [u8]) -> Option<&'a [u8]> {
24 assert_ne!(n, u64::MAX);
25 self.cipher.decrypt(&self.key, n, ad, buf)
26 }
27 pub fn rekey(&mut self) {
28 let tmp = Zeroizing::new(self.key);
29 self.cipher.rekey(&tmp, &mut self.key);
30 }
31}
32
33
34impl CipherState<u64> {
35 #[inline(always)]
36 pub(crate) const fn new(cipher: &'static dyn Cipher) -> Self {
37 Self {
38 key: [0; CIPHER_KEY_LEN],
39 cipher,
40 nonce: u64::MAX,
41 }
42 }
43 pub(crate) fn initialize_key(&mut self, key: &[u8; CIPHER_KEY_LEN]) {
44 self.key = *key;
45 self.nonce = 0;
46 }
47 #[inline(always)]
48 pub fn into_stateless(self) -> CipherState<()> {
49 CipherState {
50 key: self.key,
51 cipher: self.cipher,
52 nonce: (),
53 }
54 }
55 pub fn encrypt(&mut self, ad: &[u8], buf: &mut [u8]) -> usize {
57 self.encrypt_with_nonce(self.nonce, ad, buf);
58 self.nonce += 1;
59 buf.len()
60 }
61 pub fn decrypt<'a>(&mut self, ad: &[u8], buf: &'a mut [u8]) -> Option<&'a [u8]> {
63 let res = self.decrypt_with_nonce(self.nonce, ad, buf);
64 if res.is_some() {
65 self.nonce += 1;
66 }
67 res
68 }
69}
70