1use crate::{
2 constants::TAGLEN,
3 error::{Error, InitStage, StateProblem},
4 types::Cipher,
5};
6
7pub(crate) struct CipherState {
8 cipher: Box<dyn Cipher>,
9 n: u64,
10 has_key: bool,
11}
12
13impl CipherState {
14 pub fn new(cipher: Box<dyn Cipher>) -> Self {
15 Self { cipher, n: 0, has_key: false }
16 }
17
18 pub fn name(&self) -> &'static str {
19 self.cipher.name()
20 }
21
22 pub fn set(&mut self, key: &[u8], n: u64) {
23 self.cipher.set(key);
24 self.n = n;
25 self.has_key = true;
26 }
27
28 pub fn encrypt_ad(
29 &mut self,
30 authtext: &[u8],
31 plaintext: &[u8],
32 out: &mut [u8],
33 ) -> Result<usize, Error> {
34 if !self.has_key {
35 return Err(StateProblem::MissingKeyMaterial.into());
36 }
37
38 validate_nonce(self.n)?;
39 let len = self.cipher.encrypt(self.n, authtext, plaintext, out);
40
41 self.n += 1;
43
44 Ok(len)
45 }
46
47 pub fn decrypt_ad(
48 &mut self,
49 authtext: &[u8],
50 ciphertext: &[u8],
51 out: &mut [u8],
52 ) -> Result<usize, Error> {
53 if (ciphertext.len() < TAGLEN) || out.len() < (ciphertext.len() - TAGLEN) {
54 return Err(Error::Decrypt);
55 }
56
57 if !self.has_key {
58 return Err(StateProblem::MissingKeyMaterial.into());
59 }
60
61 validate_nonce(self.n)?;
62 let len = self.cipher.decrypt(self.n, authtext, ciphertext, out)?;
63
64 self.n += 1;
66
67 Ok(len)
68 }
69
70 pub fn encrypt(&mut self, plaintext: &[u8], out: &mut [u8]) -> Result<usize, Error> {
71 self.encrypt_ad(&[0u8; 0], plaintext, out)
72 }
73
74 pub fn decrypt(&mut self, ciphertext: &[u8], out: &mut [u8]) -> Result<usize, Error> {
75 self.decrypt_ad(&[0u8; 0], ciphertext, out)
76 }
77
78 pub fn rekey(&mut self) {
79 self.cipher.rekey();
80 }
81
82 pub fn rekey_manually(&mut self, key: &[u8]) {
83 self.cipher.set(key);
84 }
85
86 pub fn nonce(&self) -> u64 {
87 self.n
88 }
89
90 pub fn set_nonce(&mut self, nonce: u64) {
91 self.n = nonce;
92 }
93}
94
95pub(crate) struct CipherStates(pub CipherState, pub CipherState);
96
97impl CipherStates {
98 pub fn new(initiator: CipherState, responder: CipherState) -> Result<Self, Error> {
99 if initiator.name() != responder.name() {
100 return Err(InitStage::ValidateCipherTypes.into());
101 }
102
103 Ok(CipherStates(initiator, responder))
104 }
105
106 pub fn rekey_initiator(&mut self) {
107 self.0.rekey()
108 }
109
110 pub fn rekey_initiator_manually(&mut self, key: &[u8]) {
111 self.0.rekey_manually(key)
112 }
113
114 pub fn rekey_responder(&mut self) {
115 self.1.rekey()
116 }
117
118 pub fn rekey_responder_manually(&mut self, key: &[u8]) {
119 self.1.rekey_manually(key)
120 }
121}
122
123pub(crate) struct StatelessCipherState {
124 cipher: Box<dyn Cipher>,
125 has_key: bool,
126}
127
128impl StatelessCipherState {
129 pub fn encrypt_ad(
130 &self,
131 nonce: u64,
132 authtext: &[u8],
133 plaintext: &[u8],
134 out: &mut [u8],
135 ) -> Result<usize, Error> {
136 if !self.has_key {
137 return Err(StateProblem::MissingKeyMaterial.into());
138 }
139
140 validate_nonce(nonce)?;
141
142 Ok(self.cipher.encrypt(nonce, authtext, plaintext, out))
143 }
144
145 pub fn decrypt_ad(
146 &self,
147 nonce: u64,
148 authtext: &[u8],
149 ciphertext: &[u8],
150 out: &mut [u8],
151 ) -> Result<usize, Error> {
152 if (ciphertext.len() < TAGLEN) || out.len() < (ciphertext.len() - TAGLEN) {
153 return Err(Error::Decrypt);
154 }
155
156 if !self.has_key {
157 return Err(StateProblem::MissingKeyMaterial.into());
158 }
159
160 validate_nonce(nonce)?;
161
162 self.cipher.decrypt(nonce, authtext, ciphertext, out)
163 }
164
165 pub fn encrypt(&self, nonce: u64, plaintext: &[u8], out: &mut [u8]) -> Result<usize, Error> {
166 self.encrypt_ad(nonce, &[], plaintext, out)
167 }
168
169 pub fn decrypt(&self, nonce: u64, ciphertext: &[u8], out: &mut [u8]) -> Result<usize, Error> {
170 self.decrypt_ad(nonce, &[], ciphertext, out)
171 }
172
173 pub fn rekey(&mut self) {
174 self.cipher.rekey()
175 }
176
177 pub fn rekey_manually(&mut self, key: &[u8]) {
178 self.cipher.set(key);
179 }
180}
181
182fn validate_nonce(current: u64) -> Result<(), Error> {
185 if current == u64::MAX {
189 Err(Error::State(StateProblem::Exhausted))
190 } else {
191 Ok(())
192 }
193}
194
195impl From<CipherState> for StatelessCipherState {
196 fn from(other: CipherState) -> Self {
197 Self { cipher: other.cipher, has_key: other.has_key }
198 }
199}
200
201pub(crate) struct StatelessCipherStates(pub StatelessCipherState, pub StatelessCipherState);
202
203impl From<CipherStates> for StatelessCipherStates {
204 fn from(other: CipherStates) -> Self {
205 StatelessCipherStates(other.0.into(), other.1.into())
206 }
207}
208
209impl StatelessCipherStates {
210 pub fn rekey_initiator(&mut self) {
211 self.0.rekey()
212 }
213
214 pub fn rekey_initiator_manually(&mut self, key: &[u8]) {
215 self.0.rekey_manually(key)
216 }
217
218 pub fn rekey_responder(&mut self) {
219 self.1.rekey()
220 }
221
222 pub fn rekey_responder_manually(&mut self, key: &[u8]) {
223 self.1.rekey_manually(key)
224 }
225}