diff --git a/aes-gcm/src/lib.rs b/aes-gcm/src/lib.rs index c6a67e5e..4006c368 100644 --- a/aes-gcm/src/lib.rs +++ b/aes-gcm/src/lib.rs @@ -300,10 +300,10 @@ where // TODO(tarcieri): interleave encryption with GHASH // See: let expected_tag = self.compute_tag(mask, associated_data, buffer); - ctr.apply_keystream_partial(buffer.into()); use subtle::ConstantTimeEq; if expected_tag[..TagSize::to_usize()].ct_eq(tag).into() { + ctr.apply_keystream_partial(buffer.into()); Ok(()) } else { Err(Error) diff --git a/aes-gcm/tests/aes128gcm.rs b/aes-gcm/tests/aes128gcm.rs index 7d4e5db0..8834636f 100644 --- a/aes-gcm/tests/aes128gcm.rs +++ b/aes-gcm/tests/aes128gcm.rs @@ -4,7 +4,7 @@ mod common; use self::common::TestVector; -use aes_gcm::aead::{generic_array::GenericArray, Aead, KeyInit, Payload}; +use aes_gcm::aead::{generic_array::GenericArray, Aead, AeadInPlace, KeyInit, Payload}; use aes_gcm::Aes128Gcm; use hex_literal::hex; diff --git a/aes-gcm/tests/aes256gcm.rs b/aes-gcm/tests/aes256gcm.rs index 82c9f1f6..dd701d5f 100644 --- a/aes-gcm/tests/aes256gcm.rs +++ b/aes-gcm/tests/aes256gcm.rs @@ -4,7 +4,7 @@ mod common; use self::common::TestVector; -use aes_gcm::aead::{generic_array::GenericArray, Aead, KeyInit, Payload}; +use aes_gcm::aead::{generic_array::GenericArray, Aead, AeadInPlace, KeyInit, Payload}; use aes_gcm::Aes256Gcm; use hex_literal::hex; diff --git a/aes-gcm/tests/common/mod.rs b/aes-gcm/tests/common/mod.rs index d8f2eb51..6255bb3a 100644 --- a/aes-gcm/tests/common/mod.rs +++ b/aes-gcm/tests/common/mod.rs @@ -71,8 +71,27 @@ macro_rules! tests { let cipher = <$aead>::new(key); assert!(cipher.decrypt(nonce, payload).is_err()); + } + + #[test] + fn decrypt_in_place_detached_modified() { + let vector = &$vectors.iter().last().unwrap(); + let key = GenericArray::from_slice(vector.key); + let nonce = GenericArray::from_slice(vector.nonce); + + let mut buffer = Vec::from(vector.ciphertext); + assert!(!buffer.is_empty()); + + // Tweak the first byte + let mut tag = GenericArray::clone_from_slice(vector.tag); + tag[0] ^= 0xaa; + + let cipher = <$aead>::new(key); + assert!(cipher + .decrypt_in_place_detached(nonce, &[], &mut buffer, &tag) + .is_err()); - // TODO(tarcieri): test ciphertext is unmodified in in-place API + assert_eq!(vector.ciphertext, buffer); } }; }