cl_noise_protocol/
cipherstate.rs1use crate::traits::{Cipher, Unspecified};
2
3#[cfg(feature = "alloc")]
4use alloc::vec::Vec;
5
6pub struct CipherState<C: Cipher> {
14 key: C::Key,
15 n: u64,
16}
17
18impl<C> Clone for CipherState<C>
19where
20 C: Cipher,
21 <C as Cipher>::Key: Clone,
22{
23 fn clone(&self) -> Self {
24 Self {
25 key: self.key.clone(),
26 n: self.n,
27 }
28 }
29}
30
31impl<C> CipherState<C>
32where
33 C: Cipher,
34{
35 pub fn name() -> &'static str {
37 C::name()
38 }
39
40 pub fn new(key: &[u8], n: u64) -> Self {
42 CipherState {
43 key: C::key_from_slice(key),
44 n,
45 }
46 }
47
48 pub fn rekey(&mut self) {
50 self.key = C::rekey(&self.key);
51 }
52
53 pub fn encrypt_ad(&mut self, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) {
55 C::encrypt(&self.key, self.n, authtext, plaintext, out);
56 #[cfg(feature = "alloc")]
57 if option_env!("NOISE_RUST_TEST_IN_PLACE").is_some() {
58 let mut inout = plaintext.to_vec();
59 inout.extend_from_slice(&[0; 16]);
60 let l = C::encrypt_in_place(&self.key, self.n, authtext, &mut inout, plaintext.len());
61 assert_eq!(inout, out);
62 assert_eq!(l, out.len());
63 }
64 self.n = self.n.checked_add(1).unwrap();
66 }
67
68 pub fn encrypt_ad_in_place(
70 &mut self,
71 authtext: &[u8],
72 in_out: &mut [u8],
73 plaintext_len: usize,
74 ) -> usize {
75 let size = C::encrypt_in_place(&self.key, self.n, authtext, in_out, plaintext_len);
76 self.n = self.n.checked_add(1).unwrap();
78 size
79 }
80
81 pub fn decrypt_ad(
83 &mut self,
84 authtext: &[u8],
85 ciphertext: &[u8],
86 out: &mut [u8],
87 ) -> Result<(), Unspecified> {
88 let r = C::decrypt(&self.key, self.n, authtext, ciphertext, out);
89 #[cfg(feature = "alloc")]
90 if option_env!("NOISE_RUST_TEST_IN_PLACE").is_some() {
91 let mut inout = ciphertext.to_vec();
92 let r2 = C::decrypt_in_place(&self.key, self.n, authtext, &mut inout, ciphertext.len());
93 assert_eq!(r.map(|_| out.len()), r2);
94 if r.is_ok() {
95 assert_eq!(&inout[..out.len()], out);
96 }
97 }
98 r?;
99 self.n = self.n.checked_add(1).unwrap();
100 Ok(())
101 }
102
103 pub fn decrypt_ad_in_place(
105 &mut self,
106 authtext: &[u8],
107 in_out: &mut [u8],
108 ciphertext_len: usize,
109 ) -> Result<usize, Unspecified> {
110 let size = C::decrypt_in_place(&self.key, self.n, authtext, in_out, ciphertext_len)?;
111 self.n = self.n.checked_add(1).unwrap();
112 Ok(size)
113 }
114
115 pub fn encrypt(&mut self, plaintext: &[u8], out: &mut [u8]) {
117 self.encrypt_ad(&[0u8; 0], plaintext, out)
118 }
119
120 pub fn encrypt_in_place(&mut self, in_out: &mut [u8], plaintext_len: usize) -> usize {
122 self.encrypt_ad_in_place(&[0u8; 0], in_out, plaintext_len)
123 }
124
125 #[cfg(feature = "alloc")]
127 pub fn encrypt_vec(&mut self, plaintext: &[u8]) -> Vec<u8> {
128 let mut out = vec![0u8; plaintext.len() + 16];
129 self.encrypt(plaintext, &mut out);
130 out
131 }
132
133 pub fn decrypt(&mut self, ciphertext: &[u8], out: &mut [u8]) -> Result<(), Unspecified> {
135 self.decrypt_ad(&[0u8; 0], ciphertext, out)
136 }
137
138 pub fn decrypt_in_place(
140 &mut self,
141 in_out: &mut [u8],
142 ciphertext_len: usize,
143 ) -> Result<usize, Unspecified> {
144 self.decrypt_ad_in_place(&[0u8; 0], in_out, ciphertext_len)
145 }
146
147 #[cfg(feature = "alloc")]
149 pub fn decrypt_vec(&mut self, ciphertext: &[u8]) -> Result<Vec<u8>, Unspecified> {
150 if ciphertext.len() < 16 {
151 return Err(Unspecified);
152 }
153 let mut out = vec![0u8; ciphertext.len() - 16];
154 self.decrypt(ciphertext, &mut out)?;
155 Ok(out)
156 }
157
158 pub fn get_next_n(&self) -> u64 {
160 self.n
161 }
162
163 pub fn extract(self) -> (C::Key, u64) {
168 (self.key, self.n)
169 }
170}