Skip to content

Commit 18c3649

Browse files
f de-DRY decrypt_in_place and remove optional tag param
and make it pub(super), see comment
1 parent aeaf125 commit 18c3649

File tree

1 file changed

+29
-32
lines changed

1 file changed

+29
-32
lines changed

lightning/src/util/chacha20poly1305rfc.rs

+29-32
Original file line numberDiff line numberDiff line change
@@ -94,40 +94,42 @@ mod real_chachapoly {
9494
}
9595

9696
pub fn decrypt(&mut self, input: &[u8], output: &mut [u8], tag: &[u8]) -> bool {
97-
if self.decrypt_inner(input, Some(output), Some(tag)) {
98-
self.cipher.process(input, output);
99-
return true
100-
}
101-
false
102-
}
103-
104-
// Decrypt in place, and check the tag if it's provided. If the tag is not provided, then
105-
// `finish_and_check_tag` may be called to check it later.
106-
pub fn decrypt_in_place(&mut self, input: &mut [u8], tag: Option<&[u8]>) -> bool {
107-
if self.decrypt_inner(input, None, tag) {
108-
self.cipher.process_in_place(input);
109-
return true
110-
}
111-
false
112-
}
113-
114-
fn decrypt_inner(&mut self, input: &[u8], output: Option<&mut [u8]>, tag: Option<&[u8]>) -> bool {
115-
if let Some(output) = output {
116-
assert!(input.len() == output.len());
117-
}
97+
assert!(input.len() == output.len());
11898
assert!(self.finished == false);
11999

100+
self.finished = true;
101+
120102
self.mac.input(input);
121103

122104
self.data_len += input.len();
105+
ChaCha20Poly1305RFC::pad_mac_16(&mut self.mac, self.data_len);
106+
self.mac.input(&self.aad_len.to_le_bytes());
107+
self.mac.input(&(self.data_len as u64).to_le_bytes());
123108

124-
if let Some(tag) = tag {
125-
return self.finish_and_check_tag(tag)
109+
let mut calc_tag = [0u8; 16];
110+
self.mac.raw_result(&mut calc_tag);
111+
if fixed_time_eq(&calc_tag, tag) {
112+
self.cipher.process(input, output);
113+
true
114+
} else {
115+
false
126116
}
127-
true
128117
}
129118

130-
pub fn finish_and_check_tag(&mut self, tag: &[u8]) -> bool {
119+
// Decrypt in place, without checking the tag. Use `finish_and_check_tag` to check it
120+
// later when decryption finishes.
121+
//
122+
// pub(super) because the public API should always enforce tag checking.
123+
pub(super) fn decrypt_in_place(&mut self, input_output: &mut [u8]) {
124+
assert!(self.finished == false);
125+
self.mac.input(input_output);
126+
self.data_len += input_output.len();
127+
self.cipher.process_in_place(input_output);
128+
}
129+
130+
// If we were previously decrypting with `decrypt_in_place`, this method must be used to finish
131+
// decrypting and check the tag. Returns whether or not the tag is valid.
132+
pub(super) fn finish_and_check_tag(&mut self, tag: &[u8]) -> bool {
131133
self.finished = true;
132134
ChaCha20Poly1305RFC::pad_mac_16(&mut self.mac, self.data_len);
133135
self.mac.input(&self.aad_len.to_le_bytes());
@@ -159,7 +161,7 @@ impl<'a, R: Read> Read for ChaChaPolyReader<'a, R> {
159161
fn read(&mut self, dest: &mut [u8]) -> Result<usize, io::Error> {
160162
let res = self.read.read(dest)?;
161163
if res > 0 {
162-
self.chacha.decrypt_in_place(&mut dest[0..res], None);
164+
self.chacha.decrypt_in_place(&mut dest[0..res]);
163165
}
164166
Ok(res)
165167
}
@@ -305,13 +307,8 @@ mod fuzzy_chachapoly {
305307
true
306308
}
307309

308-
pub fn decrypt_in_place(&mut self, _input: &mut [u8], tag: Option<&[u8]>) -> bool {
310+
pub fn decrypt_in_place(&mut self, _input: &mut [u8]) {
309311
assert!(self.finished == false);
310-
if let Some(tag) = tag {
311-
if tag[..] != self.tag[..] { return false; }
312-
}
313-
self.finished = true;
314-
true
315312
}
316313

317314
pub fn finish_and_check_tag(&mut self, tag: &[u8]) -> bool {

0 commit comments

Comments
 (0)