summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto/aead.rs
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2019-10-23 14:23:28 +0200
committerNeal H. Walfield <neal@pep.foundation>2019-10-23 14:23:28 +0200
commite6e2658e8159449b0a6752d83db6f490942b8bf8 (patch)
tree4a4e083d5dc59129f961a4808babeb217cfb5fc5 /openpgp/src/crypto/aead.rs
parenta3c4f05848d0d9d46a7b9cdc9b227ed27189e231 (diff)
openpgp: Make Decryptor::reader_helper only do a short read on EOF
- `Decryptor::reader_helper` is used to implement `BufferedReader::data`, which has the requirement that short reads only occur on EOF. - Adjust Decryptor::reader_helper to implement these semantics.
Diffstat (limited to 'openpgp/src/crypto/aead.rs')
-rw-r--r--openpgp/src/crypto/aead.rs31
1 files changed, 8 insertions, 23 deletions
diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs
index f5b8424e..0a34cbae 100644
--- a/openpgp/src/crypto/aead.rs
+++ b/openpgp/src/crypto/aead.rs
@@ -193,6 +193,10 @@ impl<'a> Decryptor<'a> {
}
}
+ // Note: this implementation tries *very* hard to make sure we don't
+ // gratuitiously do a short read. Specifically, if the return value
+ // is less than `plaintext.len()`, then it is either because we
+ // reached the end of the input or an error occured.
fn read_helper(&mut self, plaintext: &mut [u8]) -> Result<usize> {
use std::cmp::Ordering;
@@ -273,11 +277,7 @@ impl<'a> Decryptor<'a> {
}
if chunk.len() < final_digest_size {
- if pos > 0 {
- return Ok(pos);
- } else {
- return Err(Error::ManipulatedMessage.into());
- }
+ return Err(Error::ManipulatedMessage.into());
}
check_final_tag = chunk.len() < to_read;
@@ -285,9 +285,6 @@ impl<'a> Decryptor<'a> {
// Return the chunk.
&chunk[..cmp::min(chunk.len(), to_read) - final_digest_size]
},
- // We encountered an error, but we've already read
- // something, so return that.
- Err(_) if pos > 0 => return Ok(pos),
Err(e) => return Err(e.into()),
};
@@ -298,11 +295,7 @@ impl<'a> Decryptor<'a> {
// the final tag.
} else if chunk.len() <= self.digest_size {
// A chunk has to include at least one byte and a tag.
- if pos > 0 {
- return Ok(pos);
- } else {
- return Err(Error::ManipulatedMessage.into());
- }
+ return Err(Error::ManipulatedMessage.into());
} else {
// Decrypt the chunk and check the tag.
let to_decrypt = chunk.len() - self.digest_size;
@@ -326,11 +319,7 @@ impl<'a> Decryptor<'a> {
if secure_cmp(&digest[..], &chunk[to_decrypt..])
!= Ordering::Equal
{
- if pos > 0 {
- return Ok(pos);
- } else {
- return Err(Error::ManipulatedMessage.into());
- }
+ return Err(Error::ManipulatedMessage.into());
}
if double_buffer {
@@ -368,11 +357,7 @@ impl<'a> Decryptor<'a> {
if final_digest.len() != final_digest_size
|| secure_cmp(&digest[..], final_digest) != Ordering::Equal
{
- if pos > 0 {
- return Ok(pos);
- } else {
- return Err(Error::ManipulatedMessage.into());
- }
+ return Err(Error::ManipulatedMessage.into());
}
// Consume the data only on success so that we keep