summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto/backend
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/crypto/backend')
-rw-r--r--openpgp/src/crypto/backend/cng/aead.rs23
-rw-r--r--openpgp/src/crypto/backend/nettle/aead.rs22
-rw-r--r--openpgp/src/crypto/backend/rust/aead.rs24
3 files changed, 61 insertions, 8 deletions
diff --git a/openpgp/src/crypto/backend/cng/aead.rs b/openpgp/src/crypto/backend/cng/aead.rs
index a7b87613..fb95b150 100644
--- a/openpgp/src/crypto/backend/cng/aead.rs
+++ b/openpgp/src/crypto/backend/cng/aead.rs
@@ -1,7 +1,9 @@
//! Implementation of AEAD using Windows CNG API.
+use std::cmp::Ordering;
use crate::{Error, Result};
use crate::crypto::aead::{Aead, CipherOp};
+use crate::crypto::mem::secure_cmp;
use crate::seal;
use crate::types::{AEADAlgorithm, SymmetricAlgorithm};
@@ -10,6 +12,12 @@ use win_crypto_ng::symmetric::{BlockCipherKey, Aes};
use win_crypto_ng::symmetric::block_cipher::generic_array::{GenericArray, ArrayLength};
use win_crypto_ng::symmetric::block_cipher::generic_array::typenum::{U128, U192, U256};
+/// Disables authentication checks.
+///
+/// This is DANGEROUS, and is only useful for debugging problems with
+/// malformed AEAD-encrypted messages.
+const DANGER_DISABLE_AUTHENTICATION: bool = false;
+
trait GenericArrayExt<T, N: ArrayLength<T>> {
const LEN: usize;
@@ -94,7 +102,7 @@ macro_rules! impl_aead {
dst[..len].copy_from_slice(&src[..len]);
EaxOnline::<$type, Encrypt>::encrypt(self, &mut dst[..len])
}
- fn decrypt(&mut self, _dst: &mut [u8], _src: &[u8]) {
+ fn decrypt_verify(&mut self, _dst: &mut [u8], _src: &[u8], _digest: &[u8]) -> Result<()> {
panic!("AEAD decryption called in the encryption context")
}
}
@@ -113,10 +121,19 @@ macro_rules! impl_aead {
fn encrypt(&mut self, _dst: &mut [u8], _src: &[u8]) {
panic!("AEAD encryption called in the decryption context")
}
- fn decrypt(&mut self, dst: &mut [u8], src: &[u8]) {
+ fn decrypt_verify(&mut self, dst: &mut [u8], src: &[u8], digest: &[u8]) -> Result<()> {
let len = core::cmp::min(dst.len(), src.len());
dst[..len].copy_from_slice(&src[..len]);
- self.decrypt_unauthenticated_hazmat(&mut dst[..len])
+ self.decrypt_unauthenticated_hazmat(&mut dst[..len]);
+ let mut chunk_digest = vec![0u8; self.digest_size()];
+
+ self.digest(&mut chunk_digest)?;
+ if secure_cmp(&chunk_digest[..], digest)
+ != Ordering::Equal && ! DANGER_DISABLE_AUTHENTICATION
+ {
+ return Err(Error::ManipulatedMessage.into());
+ }
+ Ok(())
}
}
impl seal::Sealed for EaxOnline<$type, Decrypt> {}
diff --git a/openpgp/src/crypto/backend/nettle/aead.rs b/openpgp/src/crypto/backend/nettle/aead.rs
index e7ae9d85..000d3156 100644
--- a/openpgp/src/crypto/backend/nettle/aead.rs
+++ b/openpgp/src/crypto/backend/nettle/aead.rs
@@ -1,12 +1,21 @@
//! Implementation of AEAD using Nettle cryptographic library.
+use std::cmp::Ordering;
+
use nettle::{aead, cipher};
use crate::{Error, Result};
use crate::crypto::aead::{Aead, CipherOp};
+use crate::crypto::mem::secure_cmp;
use crate::seal;
use crate::types::{AEADAlgorithm, SymmetricAlgorithm};
+/// Disables authentication checks.
+///
+/// This is DANGEROUS, and is only useful for debugging problems with
+/// malformed AEAD-encrypted messages.
+const DANGER_DISABLE_AUTHENTICATION: bool = false;
+
impl<T: nettle::aead::Aead> seal::Sealed for T {}
impl<T: nettle::aead::Aead> Aead for T {
fn update(&mut self, ad: &[u8]) {
@@ -15,8 +24,17 @@ impl<T: nettle::aead::Aead> Aead for T {
fn encrypt(&mut self, dst: &mut [u8], src: &[u8]) {
self.encrypt(dst, src)
}
- fn decrypt(&mut self, dst: &mut [u8], src: &[u8]) {
- self.decrypt(dst, src)
+ fn decrypt_verify(&mut self, dst: &mut [u8], src: &[u8], digest: &[u8]) -> Result<()> {
+ self.decrypt(dst, src);
+ let mut chunk_digest = vec![0u8; self.digest_size()];
+
+ self.digest(&mut chunk_digest);
+ if secure_cmp(&chunk_digest[..], digest)
+ != Ordering::Equal && ! DANGER_DISABLE_AUTHENTICATION
+ {
+ return Err(Error::ManipulatedMessage.into());
+ }
+ Ok(())
}
fn digest(&mut self, digest: &mut [u8]) {
self.digest(digest)
diff --git a/openpgp/src/crypto/backend/rust/aead.rs b/openpgp/src/crypto/backend/rust/aead.rs
index e5fcdb0b..f4dbc198 100644
--- a/openpgp/src/crypto/backend/rust/aead.rs
+++ b/openpgp/src/crypto/backend/rust/aead.rs
@@ -1,6 +1,7 @@
//! Implementation of AEAD using pure Rust cryptographic libraries.
use std::cmp;
+use std::cmp::Ordering;
use cipher::{BlockCipher, NewBlockCipher};
use cipher::block::Block;
@@ -10,9 +11,16 @@ use generic_array::{ArrayLength, GenericArray};
use crate::{Error, Result};
use crate::crypto::aead::{Aead, CipherOp};
+use crate::crypto::mem::secure_cmp;
use crate::seal;
use crate::types::{AEADAlgorithm, SymmetricAlgorithm};
+/// Disables authentication checks.
+///
+/// This is DANGEROUS, and is only useful for debugging problems with
+/// malformed AEAD-encrypted messages.
+const DANGER_DISABLE_AUTHENTICATION: bool = false;
+
trait GenericArrayExt<T, N: ArrayLength<T>> {
const LEN: usize;
@@ -56,7 +64,7 @@ where
Self::encrypt(self, &mut dst[..len])
}
- fn decrypt(&mut self, _dst: &mut [u8], _src: &[u8]) {
+ fn decrypt_verify(&mut self, _dst: &mut [u8], _src: &[u8], _digest: &[u8]) -> Result<()> {
panic!("AEAD decryption called in the encryption context")
}
}
@@ -83,10 +91,20 @@ where
panic!("AEAD encryption called in the decryption context")
}
- fn decrypt(&mut self, dst: &mut [u8], src: &[u8]) {
+ fn decrypt_verify(&mut self, dst: &mut [u8], src: &[u8], digest: &[u8]) -> Result<()> {
let len = core::cmp::min(dst.len(), src.len());
dst[..len].copy_from_slice(&src[..len]);
- self.decrypt_unauthenticated_hazmat(&mut dst[..len])
+ self.decrypt_unauthenticated_hazmat(&mut dst[..len]);
+
+ let mut chunk_digest = vec![0u8; self.digest_size()];
+
+ self.digest(&mut chunk_digest)?;
+ if secure_cmp(&chunk_digest[..], digest)
+ != Ordering::Equal && ! DANGER_DISABLE_AUTHENTICATION
+ {
+ return Err(Error::ManipulatedMessage.into());
+ }
+ Ok(())
}
}