From 9a7e777d55c31a7d07d43297aa0e45525db9727e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jan 2025 17:33:24 -0700 Subject: [PATCH] aead: remove stateful AEAD traits (`AeadMut*`) We currently have no implementations which require these traits, or plans to implement any. If we do wind up needing these, they can be easily added back. --- aead/src/lib.rs | 187 +++--------------------------------------------- 1 file changed, 10 insertions(+), 177 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index dc7f6bce..7f35e457 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -149,9 +149,6 @@ pub trait AeadCore { } /// Authenticated Encryption with Associated Data (AEAD) algorithm. -/// -/// This trait is intended for use with stateless AEAD algorithms. The -/// [`AeadMut`] trait provides a stateful interface. #[cfg(feature = "alloc")] pub trait Aead: AeadCore { /// Encrypt the given plaintext payload, and return the resulting @@ -207,53 +204,6 @@ pub trait Aead: AeadCore { ) -> Result>; } -/// Stateful Authenticated Encryption with Associated Data algorithm. -#[cfg(feature = "alloc")] -pub trait AeadMut: AeadCore { - /// Encrypt the given plaintext slice, and return the resulting ciphertext - /// as a vector of bytes. - /// - /// See notes on [`Aead::encrypt()`] about allowable message payloads and - /// Associated Additional Data (AAD). - fn encrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - plaintext: impl Into>, - ) -> Result>; - - /// Decrypt the given ciphertext slice, and return the resulting plaintext - /// as a vector of bytes. - /// - /// See notes on [`Aead::encrypt()`] and [`Aead::decrypt()`] about allowable - /// message payloads and Associated Additional Data (AAD). - fn decrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result>; -} - -/// Implement the `decrypt_in_place` method on [`AeadInPlace`] and -/// [`AeadMutInPlace]`, using a macro to gloss over the `&self` vs `&mut self`. -/// -/// Assumes a postfix authentication tag. AEAD ciphers which do not use a -/// postfix authentication tag will need to define their own implementation. -macro_rules! impl_decrypt_in_place { - ($aead:expr, $nonce:expr, $aad:expr, $buffer:expr) => {{ - let tag_pos = $buffer - .len() - .checked_sub(Self::TagSize::to_usize()) - .ok_or(Error)?; - - let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); - let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); - - $aead.decrypt_in_place_detached($nonce, $aad, msg, &tag)?; - $buffer.truncate(tag_pos); - Ok(()) - }}; -} - /// In-place stateless AEAD trait. /// /// This trait is both object safe and has no dependencies on `alloc` or `std`. @@ -297,72 +247,24 @@ pub trait AeadInPlace: AeadCore { associated_data: &[u8], buffer: &mut dyn Buffer, ) -> Result<()> { - impl_decrypt_in_place!(self, nonce, associated_data, buffer) - } + let tag_pos = buffer + .len() + .checked_sub(Self::TagSize::to_usize()) + .ok_or(Error)?; - /// Decrypt the message in-place, returning an error in the event the provided - /// authentication tag does not match the given ciphertext (i.e. ciphertext - /// is modified/unauthentic) - fn decrypt_in_place_detached( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - tag: &Tag, - ) -> Result<()>; -} + let (msg, tag) = buffer.as_mut().split_at_mut(tag_pos); + let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); -/// In-place stateful AEAD trait. -/// -/// This trait is both object safe and has no dependencies on `alloc` or `std`. -pub trait AeadMutInPlace: AeadCore { - /// Encrypt the given buffer containing a plaintext message in-place. - /// - /// The buffer must have sufficient capacity to store the ciphertext - /// message, which will always be larger than the original plaintext. - /// The exact size needed is cipher-dependent, but generally includes - /// the size of an authentication tag. - /// - /// Returns an error if the buffer has insufficient capacity to store the - /// resulting ciphertext message. - fn encrypt_in_place( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut impl Buffer, - ) -> Result<()> { - let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; - buffer.extend_from_slice(tag.as_slice())?; + self.decrypt_in_place_detached(nonce, associated_data, msg, &tag)?; + buffer.truncate(tag_pos); Ok(()) } - /// Encrypt the data in-place, returning the authentication tag - fn encrypt_in_place_detached( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - ) -> Result>; - - /// Decrypt the message in-place, returning an error in the event the - /// provided authentication tag does not match the given ciphertext. - /// - /// The buffer will be truncated to the length of the original plaintext - /// message upon success. - fn decrypt_in_place( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut impl Buffer, - ) -> Result<()> { - impl_decrypt_in_place!(self, nonce, associated_data, buffer) - } - - /// Decrypt the data in-place, returning an error in the event the provided + /// Decrypt the message in-place, returning an error in the event the provided /// authentication tag does not match the given ciphertext (i.e. ciphertext /// is modified/unauthentic) fn decrypt_in_place_detached( - &mut self, + &self, nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], @@ -396,71 +298,6 @@ impl Aead for Alg { } } -#[cfg(feature = "alloc")] -impl AeadMut for Alg { - fn encrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - plaintext: impl Into>, - ) -> Result> { - let payload = plaintext.into(); - let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); - buffer.extend_from_slice(payload.msg); - self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } - - fn decrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result> { - let payload = ciphertext.into(); - let mut buffer = Vec::from(payload.msg); - self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } -} - -impl AeadMutInPlace for Alg { - fn encrypt_in_place( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut impl Buffer, - ) -> Result<()> { - ::encrypt_in_place(self, nonce, associated_data, buffer) - } - - fn encrypt_in_place_detached( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - ) -> Result> { - ::encrypt_in_place_detached(self, nonce, associated_data, buffer) - } - - fn decrypt_in_place( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut impl Buffer, - ) -> Result<()> { - ::decrypt_in_place(self, nonce, associated_data, buffer) - } - - fn decrypt_in_place_detached( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - tag: &Tag, - ) -> Result<()> { - ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) - } -} - /// AEAD payloads (message + AAD). /// /// Combination of a message (plaintext or ciphertext) and @@ -572,8 +409,4 @@ mod tests { /// Ensure that `AeadInPlace` is object-safe #[allow(dead_code)] type DynAeadInPlace = dyn AeadInPlace; - - /// Ensure that `AeadMutInPlace` is object-safe - #[allow(dead_code)] - type DynAeadMutInPlace = dyn AeadMutInPlace; }