diff --git a/aes-gcm-siv/Cargo.toml b/aes-gcm-siv/Cargo.toml index 33c20ad4..73c48188 100644 --- a/aes-gcm-siv/Cargo.toml +++ b/aes-gcm-siv/Cargo.toml @@ -17,7 +17,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.85" [dependencies] -aead = { version = "0.6.0-rc.0", default-features = false } +aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] } aes = { version = "=0.9.0-pre.3", optional = true } cipher = "=0.5.0-pre.8" ctr = "0.10.0-pre.2" diff --git a/aes-gcm-siv/src/lib.rs b/aes-gcm-siv/src/lib.rs index 37700513..d618e655 100644 --- a/aes-gcm-siv/src/lib.rs +++ b/aes-gcm-siv/src/lib.rs @@ -83,13 +83,13 @@ pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; #[cfg(feature = "aes")] pub use aes; -use aead::{inout::InOutBuf, PostfixTagged}; +use aead::{PostfixTagged, inout::InOutBuf}; use cipher::{ + BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore, array::Array, consts::{U12, U16}, - BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore, }; -use polyval::{universal_hash::UniversalHash, Polyval}; +use polyval::{Polyval, universal_hash::UniversalHash}; /// AES is optional to allow swapping in hardware-specific backends. #[cfg(feature = "aes")] @@ -278,10 +278,10 @@ where } self.polyval.update_padded(associated_data); - self.polyval.update_padded(buffer); + self.polyval.update_padded(buffer.get_in()); let tag = self.finish_tag(associated_data.len(), buffer.len()); - init_ctr(&self.enc_cipher, &tag).apply_keystream_partial(buffer.into()); + init_ctr(&self.enc_cipher, &tag).apply_keystream_partial(buffer); Ok(tag) } @@ -291,7 +291,7 @@ where pub(crate) fn decrypt_inout_detached( mut self, associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX { @@ -301,8 +301,8 @@ where self.polyval.update_padded(associated_data); // TODO(tarcieri): interleave decryption and authentication - init_ctr(&self.enc_cipher, tag).apply_keystream_partial(buffer.into()); - self.polyval.update_padded(buffer); + init_ctr(&self.enc_cipher, tag).apply_keystream_partial(buffer.reborrow()); + self.polyval.update_padded(buffer.get_in()); let expected_tag = self.finish_tag(associated_data.len(), buffer.len()); @@ -312,7 +312,7 @@ where } else { // On MAC verify failure, re-encrypt the plaintext buffer to // prevent accidental exposure. - init_ctr(&self.enc_cipher, tag).apply_keystream_partial(buffer.into()); + init_ctr(&self.enc_cipher, tag).apply_keystream_partial(buffer); Err(Error) } } diff --git a/aes-gcm/Cargo.toml b/aes-gcm/Cargo.toml index 0adb5f53..89f42b70 100644 --- a/aes-gcm/Cargo.toml +++ b/aes-gcm/Cargo.toml @@ -17,7 +17,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.85" [dependencies] -aead = { version = "0.6.0-rc.0", default-features = false } +aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] } aes = { version = "=0.9.0-pre.3", optional = true } cipher = "=0.5.0-pre.8" ctr = "0.10.0-pre.2" diff --git a/aes-gcm/src/lib.rs b/aes-gcm/src/lib.rs index 9b5e3d4e..45d42ebc 100644 --- a/aes-gcm/src/lib.rs +++ b/aes-gcm/src/lib.rs @@ -103,21 +103,21 @@ pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; #[cfg(feature = "aes")] pub use aes; -use aead::{inout::InOutBuf, PostfixTagged}; +use aead::{PostfixTagged, inout::InOutBuf}; use cipher::{ + BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore, array::{Array, ArraySize}, consts::U16, - BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore, }; use core::marker::PhantomData; -use ghash::{universal_hash::UniversalHash, GHash}; +use ghash::{GHash, universal_hash::UniversalHash}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; #[cfg(feature = "aes")] -use aes::{cipher::consts::U12, Aes128, Aes256}; +use aes::{Aes128, Aes256, cipher::consts::U12}; /// Maximum length of associated data. pub const A_MAX: u64 = 1 << 36; @@ -270,7 +270,7 @@ where &self, nonce: &Nonce, associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, ) -> Result, Error> { if buffer.len() as u64 > P_MAX || associated_data.len() as u64 > A_MAX { return Err(Error); @@ -280,9 +280,9 @@ where // TODO(tarcieri): interleave encryption with GHASH // See: - ctr.apply_keystream_partial(buffer.into()); + ctr.apply_keystream_partial(buffer.reborrow()); - let full_tag = self.compute_tag(mask, associated_data, buffer); + let full_tag = self.compute_tag(mask, associated_data, buffer.get_in()); Ok(Tag::try_from(&full_tag[..TagSize::to_usize()]).expect("tag size mismatch")) } @@ -301,11 +301,11 @@ where // TODO(tarcieri): interleave encryption with GHASH // See: - let expected_tag = self.compute_tag(mask, associated_data, buffer); + let expected_tag = self.compute_tag(mask, associated_data, buffer.get_in()); use subtle::ConstantTimeEq; if expected_tag[..TagSize::to_usize()].ct_eq(tag).into() { - ctr.apply_keystream_partial(buffer.into()); + ctr.apply_keystream_partial(buffer); Ok(()) } else { Err(Error) diff --git a/aes-gcm/tests/common/mod.rs b/aes-gcm/tests/common/mod.rs index c7d217ae..f8028d94 100644 --- a/aes-gcm/tests/common/mod.rs +++ b/aes-gcm/tests/common/mod.rs @@ -92,7 +92,7 @@ macro_rules! tests { let cipher = <$aead>::new(&key); assert!( cipher - .decrypt_inout_detached(&nonce, &[], &mut buffer, &tag) + .decrypt_inout_detached(&nonce, &[], (buffer.as_mut_slice()).into(), &tag) .is_err() ); diff --git a/aes-siv/src/siv.rs b/aes-siv/src/siv.rs index 8aec3289..693b9581 100644 --- a/aes-siv/src/siv.rs +++ b/aes-siv/src/siv.rs @@ -213,7 +213,7 @@ where // TODO(tarcieri): add offset param to `encrypt_inout_detached` buffer.as_mut().copy_within(..pt_len, IV_SIZE); - let tag = self.encrypt_inout_detached(headers, &mut buffer.as_mut()[IV_SIZE..])?; + let tag = self.encrypt_inout_detached(headers, (&mut buffer.as_mut()[IV_SIZE..]).into())?; buffer.as_mut()[..IV_SIZE].copy_from_slice(tag.as_slice()); Ok(()) } @@ -227,15 +227,15 @@ where pub fn encrypt_inout_detached( &mut self, headers: I, - plaintext: InOutBuf<'_, '_, u8>, + mut plaintext: InOutBuf<'_, '_, u8>, ) -> Result where I: IntoIterator, T: AsRef<[u8]>, { // Compute the synthetic IV for this plaintext - let siv_tag = s2v(&mut self.mac, headers, plaintext)?; - self.xor_with_keystream(siv_tag, plaintext); + let siv_tag = s2v(&mut self.mac, headers, plaintext.get_in())?; + self.xor_with_keystream(siv_tag, plaintext.get_out()); Ok(siv_tag) } @@ -271,7 +271,7 @@ where } let siv_tag = Tag::try_from(&buffer.as_ref()[..IV_SIZE]).expect("tag size mismatch"); - self.decrypt_inout_detached(headers, &mut buffer.as_mut()[IV_SIZE..], &siv_tag)?; + self.decrypt_inout_detached(headers, (&mut buffer.as_mut()[IV_SIZE..]).into(), &siv_tag)?; let pt_len = buffer.len() - IV_SIZE; @@ -290,22 +290,22 @@ where pub fn decrypt_inout_detached( &mut self, headers: I, - ciphertext: InOutBuf<'_, '_, u8>, + mut ciphertext: InOutBuf<'_, '_, u8>, siv_tag: &Tag, ) -> Result<(), Error> where I: IntoIterator, T: AsRef<[u8]>, { - self.xor_with_keystream(*siv_tag, ciphertext); - let computed_siv_tag = s2v(&mut self.mac, headers, ciphertext)?; + self.xor_with_keystream(*siv_tag, ciphertext.get_out()); + let computed_siv_tag = s2v(&mut self.mac, headers, ciphertext.get_in())?; // Note: `CtOutput` provides constant-time equality if CtOutput::::new(computed_siv_tag) == CtOutput::new(*siv_tag) { Ok(()) } else { // Re-encrypt the decrypted plaintext to avoid revealing it - self.xor_with_keystream(*siv_tag, ciphertext); + self.xor_with_keystream(*siv_tag, ciphertext.get_out()); Err(Error) } } diff --git a/aes-siv/tests/aead.rs b/aes-siv/tests/aead.rs index d0d8ffd0..1034c9df 100644 --- a/aes-siv/tests/aead.rs +++ b/aes-siv/tests/aead.rs @@ -40,7 +40,7 @@ macro_rules! tests { let cipher = <$aead>::new(&key); let tag = cipher - .encrypt_inout_detached(&nonce, vector.aad, &mut buffer) + .encrypt_inout_detached(&nonce, vector.aad, buffer.as_mut_slice().into()) .unwrap(); let (expected_tag, expected_ciphertext) = vector.ciphertext.split_at(16); assert_eq!(expected_tag, &tag[..]); @@ -75,7 +75,7 @@ macro_rules! tests { let mut buffer = vector.ciphertext[16..].to_vec(); <$aead>::new(&key) - .decrypt_inout_detached(&nonce, vector.aad, &mut buffer, &tag) + .decrypt_inout_detached(&nonce, vector.aad, buffer.as_mut_slice().into(), &tag) .unwrap(); assert_eq!(vector.plaintext, buffer.as_slice()); diff --git a/ascon-aead/Cargo.toml b/ascon-aead/Cargo.toml index a20e14df..0e8cea59 100644 --- a/ascon-aead/Cargo.toml +++ b/ascon-aead/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.85" [dependencies] -aead = { version = "0.6.0-rc.0", default-features = false } +aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] } subtle = { version = "2", default-features = false } zeroize = { version = "1.6", optional = true, default-features = false, features = ["derive"] } ascon = "0.4" diff --git a/ascon-aead/src/asconcore.rs b/ascon-aead/src/asconcore.rs index aa70ae23..7db2a8bf 100644 --- a/ascon-aead/src/asconcore.rs +++ b/ascon-aead/src/asconcore.rs @@ -5,6 +5,7 @@ use aead::{ Error, array::{Array, ArraySize, typenum::Unsigned}, consts::{U16, U20}, + inout::InOutBuf, }; use ascon::{State, pad}; use subtle::ConstantTimeEq; @@ -337,30 +338,30 @@ impl<'a, P: Parameters> AsconCore<'a, P> { tag } - pub(crate) fn encrypt_inplace( + pub(crate) fn encrypt_inout( &mut self, - message: &mut [u8], + mut message: InOutBuf<'_, '_, u8>, associated_data: &[u8], ) -> Array { self.process_associated_data(associated_data); - self.process_encrypt_inplace(message); + self.process_encrypt_inplace(message.get_out()); Array::from(self.process_final()) } - pub(crate) fn decrypt_inplace( + pub(crate) fn decrypt_inout( &mut self, - ciphertext: &mut [u8], + mut ciphertext: InOutBuf<'_, '_, u8>, associated_data: &[u8], expected_tag: &Array, ) -> Result<(), Error> { self.process_associated_data(associated_data); - self.process_decrypt_inplace(ciphertext); + self.process_decrypt_inplace(ciphertext.get_out()); let tag = self.process_final(); if bool::from(tag.ct_eq(expected_tag)) { Ok(()) } else { - ciphertext.fill(0); + ciphertext.get_out().fill(0); Err(Error) } } diff --git a/ascon-aead/src/lib.rs b/ascon-aead/src/lib.rs index 52201699..8ed7b3f2 100644 --- a/ascon-aead/src/lib.rs +++ b/ascon-aead/src/lib.rs @@ -158,7 +158,7 @@ impl AeadInOut for Ascon

{ } let mut core = AsconCore::

::new(&self.key, nonce); - Ok(core.encrypt_inplace(buffer, associated_data)) + Ok(core.encrypt_inout(buffer, associated_data)) } fn decrypt_inout_detached( @@ -176,7 +176,7 @@ impl AeadInOut for Ascon

{ } let mut core = AsconCore::

::new(&self.key, nonce); - core.decrypt_inplace(buffer, associated_data, tag) + core.decrypt_inout(buffer, associated_data, tag) } } diff --git a/ascon-aead/tests/kats_test.rs b/ascon-aead/tests/kats_test.rs index 6fa63537..0915bae1 100644 --- a/ascon-aead/tests/kats_test.rs +++ b/ascon-aead/tests/kats_test.rs @@ -40,7 +40,8 @@ fn run_tv( let bad_tag = Tag::::default(); let mut buf = ciphertext[..ciphertext.len() - bad_tag.len()].to_vec(); - let res = core.decrypt_inout_detached(nonce, associated_data, &mut buf, &bad_tag); + let res = + core.decrypt_inout_detached(nonce, associated_data, buf.as_mut_slice().into(), &bad_tag); assert!(res.is_err()); assert!(buf.iter().all(|b| *b == 0)); } diff --git a/ccm/Cargo.toml b/ccm/Cargo.toml index cc43be2a..54324b8d 100644 --- a/ccm/Cargo.toml +++ b/ccm/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["encryption", "aead"] rust-version = "1.85" [dependencies] -aead = { version = "0.6.0-rc.0", default-features = false } +aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] } cipher = { version = "=0.5.0-pre.8", default-features = false } ctr = { version = "0.10.0-pre.2", default-features = false } subtle = { version = "2", default-features = false } diff --git a/ccm/src/lib.rs b/ccm/src/lib.rs index a9200aa6..9b6f0125 100644 --- a/ccm/src/lib.rs +++ b/ccm/src/lib.rs @@ -42,13 +42,13 @@ //! [aead]: https://docs.rs/aead //! [1]: https://en.wikipedia.org/wiki/Authenticated_encryption -pub use aead::{self, consts, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, consts}; use aead::{ - array::{typenum::Unsigned, Array, ArraySize}, + PostfixTagged, + array::{Array, ArraySize, typenum::Unsigned}, consts::U16, inout::InOutBuf, - PostfixTagged, }; use cipher::{ Block, BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipher, StreamCipherSeek, @@ -232,9 +232,9 @@ where &self, nonce: &Nonce, adata: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, ) -> Result, Error> { - let mut full_tag = self.calc_mac(nonce, adata, buffer)?; + let mut full_tag = self.calc_mac(nonce, adata, buffer.get_in())?; let ext_nonce = Self::extend_nonce(nonce); // number of bytes left for counter (max 8) @@ -243,11 +243,11 @@ where if cb > 4 { let mut ctr = Ctr64BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce)); ctr.apply_keystream(&mut full_tag); - ctr.apply_keystream(buffer); + ctr.apply_keystream(buffer.get_out()); } else { let mut ctr = Ctr32BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce)); ctr.apply_keystream(&mut full_tag); - ctr.apply_keystream(buffer); + ctr.apply_keystream(buffer.get_out()); } Ok(Tag::try_from(&full_tag[..M::to_usize()]).expect("tag size mismatch")) @@ -257,7 +257,7 @@ where &self, nonce: &Nonce, adata: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { let ext_nonce = Self::extend_nonce(nonce); @@ -267,14 +267,14 @@ where if cb > 4 { let mut ctr = Ctr64BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce)); ctr.seek(C::BlockSize::USIZE); - ctr.apply_keystream(buffer); + ctr.apply_keystream(buffer.get_out()); } else { let mut ctr = Ctr32BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce)); ctr.seek(C::BlockSize::USIZE); - ctr.apply_keystream(buffer); + ctr.apply_keystream(buffer.get_out()); } - let mut full_tag = self.calc_mac(nonce, adata, buffer)?; + let mut full_tag = self.calc_mac(nonce, adata, buffer.get_in())?; if cb > 4 { let mut ctr = Ctr64BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce)); @@ -287,7 +287,7 @@ where if full_tag[..tag.len()].ct_eq(tag).into() { Ok(()) } else { - buffer.iter_mut().for_each(|v| *v = 0); + buffer.get_out().fill(0); Err(Error) } } diff --git a/ccm/tests/mod.rs b/ccm/tests/mod.rs index aa393c7e..0befbf81 100644 --- a/ccm/tests/mod.rs +++ b/ccm/tests/mod.rs @@ -19,11 +19,11 @@ fn test_data_len_check() { let c = Cipher::new(&key); let mut buf1 = [1; u16::MAX as usize]; - let res = c.encrypt_inout_detached(&nonce, &[], &mut buf1); + let res = c.encrypt_inout_detached(&nonce, &[], (&mut buf1[..]).into()); assert!(res.is_ok()); let mut buf2 = [1; u16::MAX as usize + 1]; - let res = c.encrypt_inout_detached(&nonce, &[], &mut buf2); + let res = c.encrypt_inout_detached(&nonce, &[], (&mut buf2[..]).into()); assert!(res.is_err()); } diff --git a/chacha20poly1305/Cargo.toml b/chacha20poly1305/Cargo.toml index 6be0a7ca..51d184dc 100644 --- a/chacha20poly1305/Cargo.toml +++ b/chacha20poly1305/Cargo.toml @@ -20,7 +20,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.85" [dependencies] -aead = { version = "0.6.0-rc.0", default-features = false } +aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] } chacha20 = { version = "=0.10.0-pre.3", default-features = false, features = ["xchacha"] } cipher = "=0.5.0-pre.8" poly1305 = "0.9.0-rc.0" diff --git a/chacha20poly1305/src/lib.rs b/chacha20poly1305/src/lib.rs index a021df7f..41595752 100644 --- a/chacha20poly1305/src/lib.rs +++ b/chacha20poly1305/src/lib.rs @@ -264,19 +264,24 @@ where &self, nonce: &aead::Nonce, associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, ) -> Result { - Cipher::new(C::new(&self.key, nonce)).encrypt_inout_detached(associated_data, buffer) + Cipher::new(C::new(&self.key, nonce)) + .encrypt_inout_detached(associated_data, buffer.get_out()) } fn decrypt_inout_detached( &self, nonce: &aead::Nonce, associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { - Cipher::new(C::new(&self.key, nonce)).decrypt_inout_detached(associated_data, buffer, tag) + Cipher::new(C::new(&self.key, nonce)).decrypt_inout_detached( + associated_data, + buffer.get_out(), + tag, + ) } } diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index 7c360207..153dd71d 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -18,7 +18,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -aead = { version = "0.6.0-rc.0", default-features = false } +aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] } aes = { version = "=0.9.0-pre.3", features = ["hazmat"], default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1", optional = true, default-features = false } diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index fe68704a..7fce5d39 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -154,7 +154,7 @@ where fn encrypt_in_place( nonce: &Array, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, subkeys: &Array<[u8; 16], B::SubkeysSize>, ) -> [u8; 16]; @@ -163,7 +163,7 @@ where fn decrypt_in_place( nonce: &Array, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, subkeys: &Array<[u8; 16], B::SubkeysSize>, ) -> Result<(), aead::Error>; diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index 7453bea5..19090891 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -2,6 +2,7 @@ use super::{DeoxysBcType, DeoxysMode}; use aead::{ array::Array, consts::{U8, U15, U16}, + inout::InOutBuf, }; use core::marker::PhantomData; use subtle::ConstantTimeEq; @@ -83,7 +84,7 @@ where fn encrypt_in_place( nonce: &Array, associated_data: &[u8], - buffer: &mut [u8], + mut buffer: InOutBuf<'_, '_, u8>, subkeys: &Array<[u8; 16], B::SubkeysSize>, ) -> [u8; 16] { let mut tag = [0u8; 16]; @@ -110,7 +111,7 @@ where if !buffer.is_empty() { tweak[0] = (tweak[0] & 0xf) | TWEAK_M; - for (index, data) in buffer.chunks_mut(16).enumerate() { + for (index, data) in buffer.get_out().chunks_mut(16).enumerate() { // Copy block number let tmp = tweak[8] & 0xf0; tweak[8..].copy_from_slice(&(index as u64).to_be_bytes()); @@ -181,7 +182,7 @@ where fn decrypt_in_place( nonce: &Array, associated_data: &[u8], - buffer: &mut [u8], + mut buffer: InOutBuf<'_, '_, u8>, tag: &Array, subkeys: &Array<[u8; 16], B::SubkeysSize>, ) -> Result<(), aead::Error> { @@ -209,7 +210,7 @@ where if !buffer.is_empty() { tweak[0] = (tweak[0] & 0xf) | TWEAK_M; - for (index, data) in buffer.chunks_mut(16).enumerate() { + for (index, data) in buffer.get_out().chunks_mut(16).enumerate() { // Copy block number let tmp = tweak[8] & 0xf0; tweak[8..].copy_from_slice(&(index as u64).to_be_bytes()); @@ -372,7 +373,7 @@ where fn encrypt_in_place( nonce: &Array, associated_data: &[u8], - buffer: &mut [u8], + mut buffer: InOutBuf<'_, '_, u8>, subkeys: &Array<[u8; 16], B::SubkeysSize>, ) -> [u8; 16] { let mut tag = [0u8; 16]; @@ -387,14 +388,14 @@ where ); // Message authentication - Self::authenticate_message(buffer, &mut tweak, subkeys, &mut tag); + Self::authenticate_message(buffer.get_in(), &mut tweak, subkeys, &mut tag); tweak[0] = TWEAK_TAG; tweak[1..].copy_from_slice(nonce); B::encrypt_in_place(&mut tag, &tweak, subkeys); // Message encryption - Self::encrypt_decrypt_message(buffer, &mut tweak, subkeys, &tag.into(), nonce); + Self::encrypt_decrypt_message(buffer.get_out(), &mut tweak, subkeys, &tag.into(), nonce); tag } @@ -402,7 +403,7 @@ where fn decrypt_in_place( nonce: &Array, associated_data: &[u8], - buffer: &mut [u8], + mut buffer: InOutBuf<'_, '_, u8>, tag: &Array, subkeys: &Array<[u8; 16], B::SubkeysSize>, ) -> Result<(), aead::Error> { @@ -418,12 +419,12 @@ where ); // Message decryption - Self::encrypt_decrypt_message(buffer, &mut tweak, subkeys, tag, nonce); + Self::encrypt_decrypt_message(buffer.get_out(), &mut tweak, subkeys, tag, nonce); tweak.fill(0); // Message authentication - Self::authenticate_message(buffer, &mut tweak, subkeys, &mut computed_tag); + Self::authenticate_message(buffer.get_in(), &mut tweak, subkeys, &mut computed_tag); tweak[0] = TWEAK_TAG; tweak[1..].copy_from_slice(nonce); diff --git a/eax/Cargo.toml b/eax/Cargo.toml index 9152c064..0da78b09 100644 --- a/eax/Cargo.toml +++ b/eax/Cargo.toml @@ -20,7 +20,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.85" [dependencies] -aead = { version = "0.6.0-rc.0", default-features = false } +aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] } cipher = "=0.5.0-pre.8" cmac = "0.8.0-pre.2" ctr = "0.10.0-pre.2" diff --git a/eax/src/lib.rs b/eax/src/lib.rs index e619c305..92d7b757 100644 --- a/eax/src/lib.rs +++ b/eax/src/lib.rs @@ -110,7 +110,7 @@ //! buffer.extend_from_slice(b"plaintext message"); //! //! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! let tag = cipher.encrypt_inout_detached(nonce, b"", &mut buffer).expect("encryption failure!"); +//! let tag = cipher.encrypt_inout_detached(nonce, b"", buffer.as_mut_slice().into()).expect("encryption failure!"); //! //! // The tag has only 8 bytes, compared to the usual 16 bytes //! assert_eq!(tag.len(), 8); @@ -119,7 +119,7 @@ //! assert_ne!(&buffer, b"plaintext message"); //! //! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_inout_detached(nonce, b"", &mut buffer, &tag).expect("decryption failure!"); +//! cipher.decrypt_inout_detached(nonce, b"", buffer.as_mut_slice().into(), &tag).expect("decryption failure!"); //! assert_eq!(&buffer, b"plaintext message"); //! # } //! ``` @@ -228,7 +228,7 @@ where &self, nonce: &Nonce, associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, ) -> Result, Error> { if buffer.len() as u64 > P_MAX || associated_data.len() as u64 > A_MAX { return Err(Error); @@ -247,10 +247,10 @@ where // 3. enc ← CTR(M) using n as iv Ctr128BE::::inner_iv_init(Cipher::new(&self.key), &n) - .apply_keystream_partial(buffer.into()); + .apply_keystream_partial(buffer.reborrow()); // 4. c ← OMAC(2 || enc) - let c = Self::cmac_with_iv(&self.key, 2, buffer); + let c = Self::cmac_with_iv(&self.key, 2, buffer.get_in()); // 5. tag ← n ^ h ^ c // (^ means xor) @@ -285,7 +285,7 @@ where let h = Self::cmac_with_iv(&self.key, 1, associated_data); // 4. c ← OMAC(2 || enc) - let c = Self::cmac_with_iv(&self.key, 2, buffer); + let c = Self::cmac_with_iv(&self.key, 2, buffer.get_in()); // 5. tag ← n ^ h ^ c // (^ means xor) @@ -305,7 +305,7 @@ where if expected_tag.ct_eq(tag).into() { // Decrypt Ctr128BE::::inner_iv_init(Cipher::new(&self.key), &n) - .apply_keystream_partial(buffer.into()); + .apply_keystream_partial(buffer); Ok(()) } else { diff --git a/ocb3/Cargo.toml b/ocb3/Cargo.toml index 4e7fd1c2..9fe5b2e8 100644 --- a/ocb3/Cargo.toml +++ b/ocb3/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.85" [dependencies] -aead = { version = "0.6.0-rc.0", default-features = false } +aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] } cipher = "=0.5.0-pre.8" ctr = "0.10.0-pre.2" dbl = "0.4.0-rc.2" diff --git a/ocb3/src/lib.rs b/ocb3/src/lib.rs index 261a863e..4f05effd 100644 --- a/ocb3/src/lib.rs +++ b/ocb3/src/lib.rs @@ -208,19 +208,20 @@ where &self, nonce: &Nonce, associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, ) -> aead::Result> { if (buffer.len() > P_MAX) || (associated_data.len() > A_MAX) { unimplemented!() } // First, try to process many blocks at once. - let (processed_bytes, mut offset_i, mut checksum_i) = self.wide_encrypt(nonce, buffer); + let (processed_bytes, mut offset_i, mut checksum_i) = + self.wide_encrypt(nonce, buffer.get_out()); let mut i = (processed_bytes / 16) + 1; // Then, process the remaining blocks. - for p_i in Block::slice_as_chunks_mut(&mut buffer[processed_bytes..]).0 { + for p_i in Block::slice_as_chunks_mut(&mut buffer.get_out()[processed_bytes..]).0 { // offset_i = offset_{i-1} xor L_{ntz(i)} inplace_xor(&mut offset_i, &self.ll[ntz(i)]); // checksum_i = checksum_{i-1} xor p_i @@ -247,11 +248,11 @@ where self.cipher.encrypt_block(&mut pad); // checksum_* = checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) let checksum_rhs = &mut [0u8; 16]; - checksum_rhs[..remaining_bytes].copy_from_slice(&buffer[processed_bytes..]); + checksum_rhs[..remaining_bytes].copy_from_slice(&buffer.get_in()[processed_bytes..]); checksum_rhs[remaining_bytes] = 0b1000_0000; inplace_xor(&mut checksum_i, checksum_rhs.as_ref()); // C_* = P_* xor Pad[1..bitlen(P_*)] - let p_star = &mut buffer[processed_bytes..]; + let p_star = &mut buffer.get_out()[processed_bytes..]; let pad = &mut pad[..p_star.len()]; for (aa, bb) in p_star.iter_mut().zip(pad) { *aa ^= *bb; @@ -267,10 +268,11 @@ where &self, nonce: &Nonce, associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, + mut buffer: InOutBuf<'_, '_, u8>, tag: &aead::Tag, ) -> aead::Result<()> { - let expected_tag = self.decrypt_in_place_return_tag(nonce, associated_data, buffer); + let expected_tag = + self.decrypt_in_place_return_tag(nonce, associated_data, buffer.get_out()); if expected_tag.ct_eq(tag).into() { Ok(()) } else { diff --git a/ocb3/tests/kats.rs b/ocb3/tests/kats.rs index b58069d7..1b30c726 100644 --- a/ocb3/tests/kats.rs +++ b/ocb3/tests/kats.rs @@ -38,7 +38,11 @@ macro_rules! rfc7253_wider_variety { let N = num2str96(3 * i + 1); let mut buffer = S.clone(); let tag = ocb - .encrypt_inout_detached(N.as_slice().try_into().unwrap(), &S, &mut buffer) + .encrypt_inout_detached( + N.as_slice().try_into().unwrap(), + &S, + buffer.as_mut_slice().into(), + ) .unwrap(); ciphertext.append(&mut buffer); ciphertext.append(&mut tag.as_slice().to_vec()); @@ -48,7 +52,11 @@ macro_rules! rfc7253_wider_variety { let N = num2str96(3 * i + 2); let mut buffer = S.clone(); let tag = ocb - .encrypt_inout_detached(N.as_slice().try_into().unwrap(), &[], &mut buffer) + .encrypt_inout_detached( + N.as_slice().try_into().unwrap(), + &[], + buffer.as_mut_slice().into(), + ) .unwrap(); ciphertext.append(&mut buffer); ciphertext.append(&mut tag.as_slice().to_vec()); @@ -57,7 +65,7 @@ macro_rules! rfc7253_wider_variety { // C = C || OCB-ENCRYPT(K,N,S,) let N = num2str96(3 * i + 3); let tag = ocb - .encrypt_inout_detached(N.as_slice().try_into().unwrap(), &S, &mut []) + .encrypt_inout_detached(N.as_slice().try_into().unwrap(), &S, (&mut [][..]).into()) .unwrap(); ciphertext.append(&mut tag.as_slice().to_vec()); } @@ -75,7 +83,11 @@ macro_rules! rfc7253_wider_variety { // Output : OCB-ENCRYPT(K,N,C,) let N = num2str96(385); let tag = ocb - .encrypt_inout_detached(N.as_slice().try_into().unwrap(), &ciphertext, &mut []) + .encrypt_inout_detached( + N.as_slice().try_into().unwrap(), + &ciphertext, + (&mut [][..]).into(), + ) .unwrap(); assert_eq!(tag.as_slice(), hex!($expected))