diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 6b38d43fd..8fbe28d4e 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -32,7 +32,7 @@ #![allow(clippy::upper_case_acronyms)] -use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, KeyInit, Result}; +use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, KeyInit, Result, Tag}; use core::ops::{AddAssign, Sub}; use generic_array::{ typenum::{Unsigned, U4, U5}, @@ -128,6 +128,25 @@ where buffer: &mut dyn Buffer, ) -> Result<()>; + /// Encrypt an AEAD message in-place at the given position in the STREAM. Return tag separately. + fn encrypt_in_place_detached( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result>; + + /// Decrypt an AEAD message in-place at the given position in the STREAM. Accept tag separately. + fn decrypt_in_place_detached( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + tag: &Tag, + ) -> Result<()>; + /// Encrypt the given plaintext payload, and return the resulting /// ciphertext as a vector of bytes. #[cfg(feature = "alloc")] @@ -346,6 +365,29 @@ impl_stream_object!( "ℰ STREAM encryptor" ); +impl Encryptor +where + A: AeadInPlace, + S: StreamPrimitive, + A::NonceSize: Sub<>::NonceOverhead>, + NonceSize: ArrayLength, +{ + #[doc = "Use the underlying AEAD to encrypt"] + #[doc = "the last AEAD message in this STREAM in-place,"] + #[doc = "consuming the "] + #[doc = "ℰ STREAM encryptor"] + #[doc = "object in order to prevent further use."] + #[doc = "Returns the tag separately."] + pub fn encrypt_last_in_place_detached( + self, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result> { + self.stream + .encrypt_in_place_detached(self.position, true, associated_data, buffer) + } +} + impl_stream_object!( Decryptor, decrypt_next, @@ -358,6 +400,30 @@ impl_stream_object!( "𝒟 STREAM decryptor" ); +impl Decryptor +where + A: AeadInPlace, + S: StreamPrimitive, + A::NonceSize: Sub<>::NonceOverhead>, + NonceSize: ArrayLength, +{ + #[doc = "Use the underlying AEAD to decrypt"] + #[doc = "the last AEAD message in this STREAM in-place,"] + #[doc = "consuming the "] + #[doc = "𝒟 STREAM decryptor"] + #[doc = "object in order to prevent further use."] + #[doc = "Accepts the tag separately."] + pub fn decrypt_last_in_place_detached( + self, + associated_data: &[u8], + buffer: &mut dyn Buffer, + tag: &Tag, + ) -> Result<()> { + self.stream + .decrypt_in_place_detached(self.position, true, associated_data, buffer, tag) + } +} + /// The original "Rogaway-flavored" STREAM as described in the paper /// [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]. /// @@ -424,6 +490,31 @@ where let nonce = self.aead_nonce(position, last_block); self.aead.decrypt_in_place(&nonce, associated_data, buffer) } + + fn encrypt_in_place_detached( + &self, + position: u32, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result> { + let nonce = self.aead_nonce(position, last_block); + self.aead + .encrypt_in_place_detached(&nonce, associated_data, buffer.as_mut()) + } + + fn decrypt_in_place_detached( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + tag: &Tag, + ) -> Result<()> { + let nonce = self.aead_nonce(position, last_block); + self.aead + .decrypt_in_place_detached(&nonce, associated_data, buffer.as_mut(), tag) + } } impl StreamBE32 @@ -503,6 +594,18 @@ where self.aead.encrypt_in_place(&nonce, associated_data, buffer) } + fn encrypt_in_place_detached( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result> { + let nonce = self.aead_nonce(position, last_block)?; + self.aead + .encrypt_in_place_detached(&nonce, associated_data, buffer.as_mut()) + } + fn decrypt_in_place( &self, position: Self::Counter, @@ -513,6 +616,19 @@ where let nonce = self.aead_nonce(position, last_block)?; self.aead.decrypt_in_place(&nonce, associated_data, buffer) } + + fn decrypt_in_place_detached( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + tag: &Tag, + ) -> Result<()> { + let nonce = self.aead_nonce(position, last_block)?; + self.aead + .decrypt_in_place_detached(&nonce, associated_data, buffer.as_mut(), tag) + } } impl StreamLE31