diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2021-11-03 11:02:44 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2021-11-03 11:08:13 +0100 |
commit | b78690261254350fc1a4e3475a913c5c998a3248 (patch) | |
tree | 919dd9389b003e2ab589e019b5ec23b7dee1d7da | |
parent | c9626a20eb28428d291ae8b078830bf71633c12c (diff) |
openpgp: Reuse crypto::symmetric::Decryptor's ciphertext buffer.
-rw-r--r-- | openpgp/src/crypto/symmetric.rs | 30 | ||||
-rw-r--r-- | openpgp/src/lib.rs | 9 |
2 files changed, 24 insertions, 15 deletions
diff --git a/openpgp/src/crypto/symmetric.rs b/openpgp/src/crypto/symmetric.rs index 64fe368c..9d165814 100644 --- a/openpgp/src/crypto/symmetric.rs +++ b/openpgp/src/crypto/symmetric.rs @@ -6,7 +6,7 @@ use std::fmt; use crate::Result; use crate::SymmetricAlgorithm; -use crate::vec_truncate; +use crate::{vec_resize, vec_truncate}; use buffered_reader::BufferedReader; @@ -45,6 +45,8 @@ pub struct Decryptor<R: io::Read> { block_size: usize, // Up to a block of unread data. buffer: Vec<u8>, + // Ciphertext buffer. + ciphertext: Vec<u8>, } assert_send_and_sync!(Decryptor<R> where R: io::Read); @@ -61,6 +63,7 @@ impl<R: io::Read> Decryptor<R> { dec, block_size, buffer: Vec::with_capacity(block_size), + ciphertext: Vec::with_capacity(8 * 1024), }) } } @@ -121,14 +124,14 @@ impl<R: io::Read> io::Read for Decryptor<R> { // 2. Decrypt as many whole blocks as `plaintext` can hold. let mut to_copy = ((plaintext.len() - pos) / self.block_size) * self.block_size; - let mut ciphertext = vec![0u8; to_copy]; - let result = read_exact(&mut self.source, &mut ciphertext[..]); + vec_resize(&mut self.ciphertext, to_copy); + let result = read_exact(&mut self.source, &mut self.ciphertext[..]); let short_read; match result { Ok(amount) => { short_read = amount < to_copy; to_copy = amount; - vec_truncate(&mut ciphertext, to_copy); + vec_truncate(&mut self.ciphertext, to_copy); }, // We encountered an error, but we did read some. Err(_) if pos > 0 => return Ok(pos), @@ -136,7 +139,7 @@ impl<R: io::Read> io::Read for Decryptor<R> { } self.dec.decrypt(&mut plaintext[pos..pos + to_copy], - &ciphertext[..]) + &self.ciphertext[..]) .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, format!("{}", e)))?; @@ -151,29 +154,26 @@ impl<R: io::Read> io::Read for Decryptor<R> { assert!(0 < to_copy); assert!(to_copy < self.block_size); - let mut ciphertext = vec![0u8; self.block_size]; - let result = read_exact(&mut self.source, &mut ciphertext[..]); + vec_resize(&mut self.ciphertext, self.block_size); + let result = read_exact(&mut self.source, &mut self.ciphertext[..]); match result { Ok(amount) => { // Make sure `ciphertext` is not larger than the // amount of data that was actually read. - vec_truncate(&mut ciphertext, amount); + vec_truncate(&mut self.ciphertext, amount); // Make sure we don't read more than is available. - to_copy = cmp::min(to_copy, ciphertext.len()); + to_copy = cmp::min(to_copy, self.ciphertext.len()); }, // We encountered an error, but we did read some. Err(_) if pos > 0 => return Ok(pos), Err(e) => return Err(e), } - assert!(ciphertext.len() <= self.block_size); + assert!(self.ciphertext.len() <= self.block_size); - while self.buffer.len() < ciphertext.len() { - self.buffer.push(0u8); - } - vec_truncate(&mut self.buffer, ciphertext.len()); + vec_resize(&mut self.buffer, self.ciphertext.len()); - self.dec.decrypt(&mut self.buffer, &ciphertext[..]) + self.dec.decrypt(&mut self.buffer, &self.ciphertext[..]) .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, format!("{}", e)))?; diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index 5f303583..f7af0123 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -76,6 +76,15 @@ fn vec_truncate(v: &mut Vec<u8>, len: usize) { } } +/// Like `Vec<u8>::resize`, but fast in debug builds. +fn vec_resize(v: &mut Vec<u8>, new_size: usize) { + if v.len() < new_size { + v.resize(new_size, 0); + } else { + vec_truncate(v, new_size); + } +} + /// Like `drop(Vec<u8>::drain(..prefix_len))`, but fast in debug /// builds. fn vec_drain_prefix(v: &mut Vec<u8>, prefix_len: usize) { |