noise_protocol/
cipherstate.rs1use crate::traits::{Cipher, U8Array};
2
3#[cfg(feature = "use_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{
22 fn clone(&self) -> Self {
23 Self {
24 key: self.key.clone(),
25 n: self.n,
26 }
27 }
28}
29
30impl<C> CipherState<C>
31where
32 C: Cipher,
33{
34 pub fn name() -> &'static str {
36 C::name()
37 }
38
39 pub fn new(key: &[u8], n: u64) -> Self {
41 CipherState {
42 key: C::Key::from_slice(key),
43 n,
44 }
45 }
46
47 pub fn rekey(&mut self) {
49 self.key = C::rekey(&self.key);
50 }
51
52 pub fn encrypt_ad(&mut self, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) {
54 C::encrypt(&self.key, self.n, authtext, plaintext, out);
55 #[cfg(feature = "use_std")]
56 if option_env!("NOISE_RUST_TEST_IN_PLACE").is_some() {
57 let mut inout = plaintext.to_vec();
58 inout.extend_from_slice(&[0; 16]);
59 let l = C::encrypt_in_place(&self.key, self.n, authtext, &mut inout, plaintext.len());
60 assert_eq!(inout, out);
61 assert_eq!(l, out.len());
62 }
63 self.n = self.n.checked_add(1).unwrap();
65 }
66
67 pub fn encrypt_ad_in_place(
69 &mut self,
70 authtext: &[u8],
71 in_out: &mut [u8],
72 plaintext_len: usize,
73 ) -> usize {
74 let size = C::encrypt_in_place(&self.key, self.n, authtext, in_out, plaintext_len);
75 self.n = self.n.checked_add(1).unwrap();
77 size
78 }
79
80 pub fn decrypt_ad(
82 &mut self,
83 authtext: &[u8],
84 ciphertext: &[u8],
85 out: &mut [u8],
86 ) -> Result<(), ()> {
87 let r = C::decrypt(&self.key, self.n, authtext, ciphertext, out);
88 #[cfg(feature = "use_std")]
89 if option_env!("NOISE_RUST_TEST_IN_PLACE").is_some() {
90 let mut inout = ciphertext.to_vec();
91 let r2 = C::decrypt_in_place(&self.key, self.n, authtext, &mut inout, ciphertext.len());
92 assert_eq!(r.map(|_| out.len()), r2);
93 if r.is_ok() {
94 assert_eq!(&inout[..out.len()], out);
95 }
96 }
97 r?;
98 self.n = self.n.checked_add(1).unwrap();
99 Ok(())
100 }
101
102 pub fn decrypt_ad_in_place(
104 &mut self,
105 authtext: &[u8],
106 in_out: &mut [u8],
107 ciphertext_len: usize,
108 ) -> Result<usize, ()> {
109 let size = C::decrypt_in_place(&self.key, self.n, authtext, in_out, ciphertext_len)?;
110 self.n = self.n.checked_add(1).unwrap();
111 Ok(size)
112 }
113
114 pub fn encrypt(&mut self, plaintext: &[u8], out: &mut [u8]) {
116 self.encrypt_ad(&[0u8; 0], plaintext, out)
117 }
118
119 pub fn encrypt_in_place(&mut self, in_out: &mut [u8], plaintext_len: usize) -> usize {
121 self.encrypt_ad_in_place(&[0u8; 0], in_out, plaintext_len)
122 }
123
124 #[cfg(any(feature = "use_std", feature = "use_alloc"))]
126 pub fn encrypt_vec(&mut self, plaintext: &[u8]) -> Vec<u8> {
127 let mut out = vec![0u8; plaintext.len() + 16];
128 self.encrypt(plaintext, &mut out);
129 out
130 }
131
132 pub fn decrypt(&mut self, ciphertext: &[u8], out: &mut [u8]) -> Result<(), ()> {
134 self.decrypt_ad(&[0u8; 0], ciphertext, out)
135 }
136
137 pub fn decrypt_in_place(
139 &mut self,
140 in_out: &mut [u8],
141 ciphertext_len: usize,
142 ) -> Result<usize, ()> {
143 self.decrypt_ad_in_place(&[0u8; 0], in_out, ciphertext_len)
144 }
145
146 #[cfg(any(feature = "use_std", feature = "use_alloc"))]
148 pub fn decrypt_vec(&mut self, ciphertext: &[u8]) -> Result<Vec<u8>, ()> {
149 if ciphertext.len() < 16 {
150 return Err(());
151 }
152 let mut out = vec![0u8; ciphertext.len() - 16];
153 self.decrypt(ciphertext, &mut out)?;
154 Ok(out)
155 }
156
157 pub fn get_next_n(&self) -> u64 {
159 self.n
160 }
161
162 pub fn extract(self) -> (C::Key, u64) {
167 (self.key, self.n)
168 }
169}