From d39ad3012ea1c68f6e515b5aef1ee16adae77a48 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 28 Feb 2025 11:13:36 +0000 Subject: [PATCH] aead: factor apart `AeadInPlace`/`*Detached` (#1714) Factors apart the detached methods of `AeadInPlace` into a separate `AeadInPlaceDetached` trait, which itself can now more easily be further refactored (by adding e.g. `inout` support). Also adds a `PostfixTagged` trait which is used to gate the blanket impls. --- aead/src/lib.rs | 71 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 0294b6f4..edc0760a 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -206,7 +206,7 @@ pub trait Aead: AeadCore { ) -> Result>; } -/// In-place stateless AEAD trait. +/// In-place AEAD trait. /// /// This trait is both object safe and has no dependencies on `alloc` or `std`. pub trait AeadInPlace: AeadCore { @@ -224,13 +224,24 @@ pub trait AeadInPlace: AeadCore { nonce: &Nonce, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<()> { - let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; - buffer.extend_from_slice(tag.as_slice())?; - Ok(()) - } + ) -> 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( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()>; +} - /// Encrypt the data in-place, returning the authentication tag +/// In-place AEAD trait which handles the authentication tag as a return value/separate parameter. +pub trait AeadInPlaceDetached: AeadCore { + /// Encrypt the data in-place, returning the authentication tag. fn encrypt_in_place_detached( &self, nonce: &Nonce, @@ -238,11 +249,36 @@ pub trait AeadInPlace: AeadCore { 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. + /// 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<()>; +} + +/// Marker trait for AEAD algorithms which append the authentication tag to the end of the +/// ciphertext message. +/// +/// This is the common convention for AEAD algorithms. +pub trait PostfixTagged {} + +impl AeadInPlace for T { + fn encrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()> { + let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; + buffer.extend_from_slice(tag.as_slice())?; + Ok(()) + } + fn decrypt_in_place( &self, nonce: &Nonce, @@ -261,17 +297,6 @@ pub trait AeadInPlace: AeadCore { buffer.truncate(tag_pos); Ok(()) } - - /// 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<()>; } #[cfg(feature = "alloc")]