diff --git a/Cargo.lock b/Cargo.lock index 1ba8327c..fdd07cc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,13 +6,14 @@ version = 4 [[package]] name = "aead" version = "0.6.0-rc.0" -source = "git+https://github.com/RustCrypto/traits.git#1548d2a7d7ce71a278a783d19d94b59b0103ab15" +source = "git+https://github.com/RustCrypto/traits.git#3620aba4f1e81e506b46a5f88c47f7ee3a7b87e0" dependencies = [ "arrayvec", "blobby 0.4.0-pre.0", "bytes", "crypto-common", "heapless", + "inout", ] [[package]] @@ -98,7 +99,6 @@ version = "0.1.0" dependencies = [ "aead", "ascon", - "inout", "subtle", "zeroize", ] @@ -248,7 +248,7 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.2.0-rc.2" -source = "git+https://github.com/RustCrypto/traits.git#1548d2a7d7ce71a278a783d19d94b59b0103ab15" +source = "git+https://github.com/RustCrypto/traits.git#3620aba4f1e81e506b46a5f88c47f7ee3a7b87e0" dependencies = [ "hybrid-array", "rand_core", @@ -278,7 +278,6 @@ dependencies = [ "aead", "aes", "hex-literal 0.4.1", - "inout", "subtle", "zeroize", ] @@ -393,7 +392,6 @@ dependencies = [ "ctr", "dbl", "hex-literal 0.4.1", - "inout", "subtle", "zeroize", ] @@ -450,18 +448,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -489,9 +487,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.99" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", diff --git a/aead-stream/src/lib.rs b/aead-stream/src/lib.rs index b3332681..4d095902 100644 --- a/aead-stream/src/lib.rs +++ b/aead-stream/src/lib.rs @@ -6,7 +6,7 @@ extern crate alloc; use aead::{ - AeadCore, AeadInPlace, Buffer, Error, Result, + AeadCore, AeadInOut, Buffer, Error, Result, array::{ Array, ArraySize, typenum::{U4, U5, Unsigned}, @@ -32,7 +32,7 @@ pub type NonceSize = /// Create a new STREAM from the provided AEAD. pub trait NewStream: StreamPrimitive where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, NonceSize: ArraySize, { @@ -57,7 +57,7 @@ where /// Deliberately immutable and stateless to permit parallel operation. pub trait StreamPrimitive where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, NonceSize: ArraySize, { @@ -165,7 +165,7 @@ macro_rules! impl_stream_object { #[derive(Debug)] pub struct $name where - A: AeadInPlace, + A: AeadInOut, S: StreamPrimitive, A::NonceSize: Sub<>::NonceOverhead>, NonceSize: ArraySize, @@ -179,7 +179,7 @@ macro_rules! impl_stream_object { impl $name where - A: AeadInPlace, + A: AeadInOut, S: StreamPrimitive, A::NonceSize: Sub<>::NonceOverhead>, NonceSize: ArraySize, @@ -344,7 +344,7 @@ pub type DecryptorLE31 = Decryptor>; #[derive(Debug)] pub struct StreamBE32 where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -357,7 +357,7 @@ where impl NewStream for StreamBE32 where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -371,7 +371,7 @@ where impl StreamPrimitive for StreamBE32 where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -405,7 +405,7 @@ where impl StreamBE32 where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -434,7 +434,7 @@ where #[derive(Debug)] pub struct StreamLE31 where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -447,7 +447,7 @@ where impl NewStream for StreamLE31 where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -461,7 +461,7 @@ where impl StreamPrimitive for StreamLE31 where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -495,7 +495,7 @@ where impl StreamLE31 where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { diff --git a/aes-gcm-siv/src/lib.rs b/aes-gcm-siv/src/lib.rs index 7f2ca194..070f8e5d 100644 --- a/aes-gcm-siv/src/lib.rs +++ b/aes-gcm-siv/src/lib.rs @@ -34,7 +34,7 @@ //! This crate has an optional `alloc` feature which can be disabled in e.g. //! microcontroller environments that don't have a heap. //! -//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! The [`AeadInOut::encrypt_in_place`] and [`AeadInOut::decrypt_in_place`] //! methods accept any type that impls the [`aead::Buffer`] trait which //! contains the plaintext for encryption or ciphertext for decryption. //! @@ -48,7 +48,7 @@ #![cfg_attr(not(all(feature = "os_rng", feature = "heapless")), doc = "```ignore")] //! # fn main() -> Result<(), Box> { //! use aes_gcm_siv::{ -//! aead::{AeadInPlace, KeyInit, rand_core::OsRng, heapless::Vec}, +//! aead::{AeadInOut, KeyInit, rand_core::OsRng, heapless::Vec}, //! Aes256GcmSiv, Nonce, // Or `Aes128GcmSiv` //! }; //! @@ -78,12 +78,12 @@ //! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the //! [`aead`] crate as [`aead::bytes::BytesMut`]). -pub use aead::{self, AeadCore, AeadInPlaceDetached, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; #[cfg(feature = "aes")] pub use aes; -use aead::PostfixTagged; +use aead::{TagPosition, inout::InOutBuf}; use cipher::{ BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore, array::Array, @@ -161,32 +161,31 @@ where { type NonceSize = U12; type TagSize = U16; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } -impl PostfixTagged for AesGcmSiv {} - -impl AeadInPlaceDetached for AesGcmSiv +impl AeadInOut for AesGcmSiv where Aes: BlockSizeUser + BlockCipherEncrypt + KeyInit, { - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result { Cipher::::new(&self.key_generating_key, nonce) - .encrypt_in_place_detached(associated_data, buffer) + .encrypt_inout_detached(associated_data, buffer) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { - Cipher::::new(&self.key_generating_key, nonce).decrypt_in_place_detached( + Cipher::::new(&self.key_generating_key, nonce).decrypt_inout_detached( associated_data, buffer, tag, @@ -268,30 +267,30 @@ where } /// Encrypt the given message in-place, returning the authentication tag. - pub(crate) fn encrypt_in_place_detached( + pub(crate) fn encrypt_inout_detached( mut self, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result { if buffer.len() as u64 > P_MAX || associated_data.len() as u64 > A_MAX { return Err(Error); } 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) } /// Decrypt the given message, first authenticating ciphertext integrity /// and returning an error if it's been tampered with. - pub(crate) fn decrypt_in_place_detached( + pub(crate) fn decrypt_inout_detached( mut self, associated_data: &[u8], - buffer: &mut [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 +300,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_out()); let expected_tag = self.finish_tag(associated_data.len(), buffer.len()); @@ -312,7 +311,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..774e9fd5 100644 --- a/aes-gcm/Cargo.toml +++ b/aes-gcm/Cargo.toml @@ -26,7 +26,7 @@ subtle = { version = "2", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] -aead = { version = "0.6.0-rc.0", features = ["dev"], default-features = false } +aead = { version = "0.6.0-rc.0", features = ["alloc", "dev"], default-features = false } hex-literal = "0.4" [features] diff --git a/aes-gcm/src/lib.rs b/aes-gcm/src/lib.rs index 6b307d68..90d41b64 100644 --- a/aes-gcm/src/lib.rs +++ b/aes-gcm/src/lib.rs @@ -54,7 +54,7 @@ //! This crate has an optional `alloc` feature which can be disabled in e.g. //! microcontroller environments that don't have a heap. //! -//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! The [`AeadInOut::encrypt_in_place`] and [`AeadInOut::decrypt_in_place`] //! methods accept any type that impls the [`aead::Buffer`] trait which //! contains the plaintext for encryption or ciphertext for decryption. //! @@ -68,7 +68,7 @@ #![cfg_attr(not(all(feature = "os_rng", feature = "heapless")), doc = "```ignore")] //! # fn main() -> Result<(), Box> { //! use aes_gcm::{ -//! aead::{AeadCore, AeadInPlace, KeyInit, rand_core::OsRng, heapless::Vec}, +//! aead::{AeadCore, AeadInOut, KeyInit, rand_core::OsRng, heapless::Vec}, //! Aes256Gcm, Nonce, // Or `Aes128Gcm` //! }; //! @@ -98,12 +98,12 @@ //! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the //! [`aead`] crate as [`aead::bytes::BytesMut`]). -pub use aead::{self, AeadCore, AeadInPlaceDetached, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; #[cfg(feature = "aes")] pub use aes; -use aead::PostfixTagged; +use aead::{TagPosition, inout::InOutBuf}; use cipher::{ BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore, @@ -253,24 +253,20 @@ where { type NonceSize = NonceSize; type TagSize = TagSize; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } -impl PostfixTagged for AesGcm where - TagSize: self::TagSize -{ -} - -impl AeadInPlaceDetached for AesGcm +impl AeadInOut for AesGcm where Aes: BlockSizeUser + BlockCipherEncrypt, NonceSize: ArraySize, TagSize: self::TagSize, { - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [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,17 +276,17 @@ 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_out()); Ok(Tag::try_from(&full_tag[..TagSize::to_usize()]).expect("tag size mismatch")) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX { @@ -301,11 +297,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/aes128gcm.rs b/aes-gcm/tests/aes128gcm.rs index 1e0f82e0..819a631b 100644 --- a/aes-gcm/tests/aes128gcm.rs +++ b/aes-gcm/tests/aes128gcm.rs @@ -7,7 +7,7 @@ mod common; use self::common::TestVector; use aes_gcm::Aes128Gcm; -use aes_gcm::aead::{Aead, AeadInPlaceDetached, KeyInit, Payload, array::Array}; +use aes_gcm::aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; use hex_literal::hex; /// NIST CAVS vectors diff --git a/aes-gcm/tests/aes256gcm.rs b/aes-gcm/tests/aes256gcm.rs index e56e5110..7f0ea0b5 100644 --- a/aes-gcm/tests/aes256gcm.rs +++ b/aes-gcm/tests/aes256gcm.rs @@ -7,7 +7,7 @@ mod common; use self::common::TestVector; use aes_gcm::Aes256Gcm; -use aes_gcm::aead::{Aead, AeadInPlaceDetached, KeyInit, Payload, array::Array}; +use aes_gcm::aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; use hex_literal::hex; /// NIST CAVS vectors diff --git a/aes-gcm/tests/common/mod.rs b/aes-gcm/tests/common/mod.rs index 5833b250..ef1dd674 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_in_place_detached(&nonce, &[], &mut buffer, &tag) + .decrypt_inout_detached(&nonce, &[], buffer.as_mut_slice().into(), &tag) .is_err() ); diff --git a/aes-siv/Cargo.toml b/aes-siv/Cargo.toml index 2f1faac7..d290c7a7 100644 --- a/aes-siv/Cargo.toml +++ b/aes-siv/Cargo.toml @@ -32,6 +32,7 @@ pmac = { version = "0.8.0-pre.2", optional = true } [dev-dependencies] blobby = "0.3" hex-literal = "0.4" +aead = { version = "0.6.0-rc.0", features = ["alloc", "dev"], default-features = false } [features] default = ["alloc", "os_rng"] diff --git a/aes-siv/src/lib.rs b/aes-siv/src/lib.rs index 9fd9e289..c0cad4cc 100644 --- a/aes-siv/src/lib.rs +++ b/aes-siv/src/lib.rs @@ -34,7 +34,7 @@ //! This crate has an optional `alloc` feature which can be disabled in e.g. //! microcontroller environments that don't have a heap. //! -//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! The [`AeadInOut::encrypt_in_place`] and [`AeadInOut::decrypt_in_place`] //! methods accept any type that impls the [`aead::Buffer`] trait which //! contains the plaintext for encryption or ciphertext for decryption. //! @@ -48,7 +48,7 @@ #![cfg_attr(not(all(feature = "os_rng", feature = "heapless")), doc = "```ignore")] //! # fn main() -> Result<(), Box> { //! use aes_siv::{ -//! aead::{AeadCore, AeadInPlace, KeyInit, rand_core::OsRng, heapless::Vec}, +//! aead::{AeadCore, AeadInOut, KeyInit, rand_core::OsRng, heapless::Vec}, //! Aes256SivAead, Nonce, // Or `Aes128SivAead` //! }; //! @@ -83,15 +83,14 @@ extern crate alloc; pub mod siv; -pub use aead::{ - self, AeadCore, AeadInPlace, AeadInPlaceDetached, Error, Key, KeyInit, KeySizeUser, -}; +pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; use crate::siv::Siv; use aead::{ - Buffer, + TagPosition, array::Array, consts::{U1, U16, U32, U64}, + inout::InOutBuf, }; use aes::{Aes128, Aes256}; use cipher::{BlockCipherEncrypt, BlockSizeUser, array::ArraySize, typenum::IsGreaterOrEqual}; @@ -206,42 +205,10 @@ where // https://tools.ietf.org/html/rfc5297#section-6 type NonceSize = NonceSize; type TagSize = U16; + const TAG_POSITION: TagPosition = TagPosition::Prefix; } -impl AeadInPlace for SivAead -where - Self: KeySizeUser, - Siv: KeyInit + KeySizeUser::KeySize>, - C: BlockSizeUser + BlockCipherEncrypt + KeyInit + KeySizeUser, - M: Mac + FixedOutputReset + KeyInit, - ::KeySize: Add, - NonceSize: ArraySize + IsGreaterOrEqual, -{ - fn encrypt_in_place( - &self, - nonce: &Array, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<(), Error> { - // "SIV performs nonce-based authenticated encryption when a component of - // the associated data is a nonce. For purposes of interoperability the - // final component -- i.e., the string immediately preceding the - // plaintext in the vector input to S2V -- is used for the nonce." - // https://tools.ietf.org/html/rfc5297#section-3 - Siv::::new(&self.key).encrypt_in_place([associated_data, nonce.as_slice()], buffer) - } - - fn decrypt_in_place( - &self, - nonce: &Array, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<(), Error> { - Siv::::new(&self.key).decrypt_in_place([associated_data, nonce.as_slice()], buffer) - } -} - -impl AeadInPlaceDetached for SivAead +impl AeadInOut for SivAead where Self: KeySizeUser, Siv: KeyInit + KeySizeUser::KeySize>, @@ -250,24 +217,24 @@ where ::KeySize: Add, NonceSize: ArraySize + IsGreaterOrEqual, { - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Array, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result, Error> { Siv::::new(&self.key) - .encrypt_in_place_detached([associated_data, nonce.as_slice()], buffer) + .encrypt_inout_detached([associated_data, nonce.as_slice()], buffer) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Array, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Array, ) -> Result<(), Error> { - Siv::::new(&self.key).decrypt_in_place_detached( + Siv::::new(&self.key).decrypt_inout_detached( [associated_data, nonce.as_slice()], buffer, tag, diff --git a/aes-siv/src/siv.rs b/aes-siv/src/siv.rs index 7880ec2e..2f646e42 100644 --- a/aes-siv/src/siv.rs +++ b/aes-siv/src/siv.rs @@ -72,6 +72,7 @@ use crate::Tag; use aead::{ Buffer, Error, array::{Array, ArraySize, typenum::U16}, + inout::InOutBuf, }; use aes::{Aes128, Aes256}; use cipher::{ @@ -209,10 +210,10 @@ where // Make room in the buffer for the SIV tag. It needs to be prepended. buffer.extend_from_slice(Tag::default().as_slice())?; - // TODO(tarcieri): add offset param to `encrypt_in_place_detached` + // TODO(tarcieri): add offset param to `encrypt_inout_detached` buffer.as_mut().copy_within(..pt_len, IV_SIZE); - let tag = self.encrypt_in_place_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(()) } @@ -223,17 +224,17 @@ where /// /// Returns [`Error`] if `plaintext.len()` is less than `M::OutputSize`. /// Returns [`Error`] if `headers.len()` is greater than [`MAX_HEADERS`]. - pub fn encrypt_in_place_detached( + pub fn encrypt_inout_detached( &mut self, headers: I, - plaintext: &mut [u8], + 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)?; + let siv_tag = s2v(&mut self.mac, headers, plaintext.get_in())?; self.xor_with_keystream(siv_tag, plaintext); Ok(siv_tag) } @@ -270,11 +271,11 @@ where } let siv_tag = Tag::try_from(&buffer.as_ref()[..IV_SIZE]).expect("tag size mismatch"); - self.decrypt_in_place_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; - // TODO(tarcieri): add offset param to `encrypt_in_place_detached` + // TODO(tarcieri): add offset param to `encrypt_inout_detached` buffer.as_mut().copy_within(IV_SIZE.., 0); buffer.truncate(pt_len); Ok(()) @@ -286,18 +287,18 @@ where /// # Errors /// /// Returns [`Error`] if the ciphertext is not authentic - pub fn decrypt_in_place_detached( + pub fn decrypt_inout_detached( &mut self, headers: I, - ciphertext: &mut [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.reborrow()); + let computed_siv_tag = s2v(&mut self.mac, headers, ciphertext.get_out())?; // Note: `CtOutput` provides constant-time equality if CtOutput::::new(computed_siv_tag) == CtOutput::new(*siv_tag) { @@ -310,7 +311,7 @@ where } /// XOR the given buffer with the keystream for the given IV - fn xor_with_keystream(&mut self, mut iv: Tag, msg: &mut [u8]) { + fn xor_with_keystream(&mut self, mut iv: Tag, msg: InOutBuf<'_, '_, u8>) { // "We zero-out the top bit in each of the last two 32-bit words // of the IV before assigning it to Ctr" // — http://web.cs.ucdavis.edu/~rogaway/papers/siv.pdf @@ -318,7 +319,7 @@ where iv[12] &= 0x7f; Ctr128BE::::inner_iv_init(C::new(&self.encryption_key), &iv) - .apply_keystream_partial(msg.into()); + .apply_keystream_partial(msg); } } diff --git a/aes-siv/tests/aead.rs b/aes-siv/tests/aead.rs index ea61a96a..4dcf1e38 100644 --- a/aes-siv/tests/aead.rs +++ b/aes-siv/tests/aead.rs @@ -32,7 +32,7 @@ macro_rules! tests { } #[test] - fn encrypt_in_place_detached() { + fn encrypt_inout_detached() { for vector in $vectors { let key = Array(*vector.key); let nonce = Array(*vector.nonce); @@ -40,11 +40,11 @@ macro_rules! tests { let cipher = <$aead>::new(&key); let tag = cipher - .encrypt_in_place_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[..]); - assert_eq!(expected_ciphertext, &buffer[..]); + assert_eq!(expected_ciphertext, buffer); } } @@ -67,7 +67,7 @@ macro_rules! tests { } #[test] - fn decrypt_in_place_detached() { + fn decrypt_inout_detached() { for vector in $vectors { let key = Array(*vector.key); let nonce = Array(*vector.nonce); @@ -75,10 +75,10 @@ macro_rules! tests { let mut buffer = vector.ciphertext[16..].to_vec(); <$aead>::new(&key) - .decrypt_in_place_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()); + assert_eq!(vector.plaintext, buffer); } } @@ -108,7 +108,7 @@ macro_rules! tests { mod aes128cmacsivaead { use super::TestVector; use aes_siv::Aes128SivAead; - use aes_siv::aead::{Aead, AeadInPlaceDetached, KeyInit, Payload, array::Array}; + use aes_siv::aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; /// AES-128-CMAC-SIV test vectors const TEST_VECTORS: &[TestVector<[u8; 32]>] = &[TestVector { @@ -132,7 +132,7 @@ mod aes128cmacsivaead { mod aes128pmacsivaead { use super::TestVector; use aes_siv::Aes128PmacSivAead; - use aes_siv::aead::{Aead, AeadInPlaceDetached, KeyInit, Payload, array::Array}; + use aes_siv::aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; /// AES-128-PMAC-SIV test vectors const AES_128_PMAC_SIV_TEST_VECTORS: &[TestVector<[u8; 32]>] = &[TestVector { diff --git a/ascon-aead128/Cargo.toml b/ascon-aead128/Cargo.toml index 20861034..028320fb 100644 --- a/ascon-aead128/Cargo.toml +++ b/ascon-aead128/Cargo.toml @@ -16,7 +16,6 @@ aead = { version = "0.6.0-rc.0", default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1.6", optional = true, default-features = false, features = ["derive"] } ascon = "0.4" -inout = { version = "0.2.0-rc.4", default-features = false } [dev-dependencies] aead = { version = "0.6.0-rc.0", features = ["dev"] } diff --git a/ascon-aead128/src/asconcore.rs b/ascon-aead128/src/asconcore.rs index e708d565..0507d747 100644 --- a/ascon-aead128/src/asconcore.rs +++ b/ascon-aead128/src/asconcore.rs @@ -2,9 +2,9 @@ use aead::{ Error, array::{Array, ArraySize}, consts::U16, + inout::InOutBuf, }; use ascon::State; -use inout::InOutBuf; use subtle::ConstantTimeEq; /// Produce mask for padding. @@ -245,30 +245,30 @@ impl<'a, P: Parameters> AsconCore<'a, P> { tag } - pub(crate) fn encrypt_inplace( + pub(crate) fn encrypt_inout( &mut self, - message: &mut [u8], + message: InOutBuf<'_, '_, u8>, associated_data: &[u8], ) -> Array { self.process_associated_data(associated_data); - self.process_encrypt_inout(message.into()); + self.process_encrypt_inout(message); 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_inout(ciphertext.into()); + self.process_decrypt_inout(ciphertext.reborrow()); 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-aead128/src/lib.rs b/ascon-aead128/src/lib.rs index 048008b2..3cff18ac 100644 --- a/ascon-aead128/src/lib.rs +++ b/ascon-aead128/src/lib.rs @@ -58,7 +58,7 @@ //! This crate has an optional `alloc` feature which can be disabled in e.g. //! microcontroller environments that don't have a heap. //! -//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! The [`AeadInOut::encrypt_in_place`] and [`AeadInOut::decrypt_in_place`] //! methods accept any type that impls the [`aead::Buffer`] trait which //! contains the plaintext for encryption or ciphertext for decryption. //! @@ -71,7 +71,7 @@ //! ``` //! # #[cfg(feature = "heapless")] { //! use ascon_aead128::{AsconAead128, Key, Nonce}; -//! use ascon_aead128::aead::{AeadInPlace, KeyInit}; +//! use ascon_aead128::aead::{AeadInOut, KeyInit}; //! use ascon_aead128::aead::heapless::Vec; //! //! let key = Key::::from_slice(b"very secret key."); @@ -104,7 +104,7 @@ pub use zeroize; pub use aead::{self, Error, Key, Nonce, Tag}; -use aead::{AeadCore, AeadInPlaceDetached, KeyInit, KeySizeUser, PostfixTagged, consts::U16}; +use aead::{AeadCore, AeadInOut, KeyInit, KeySizeUser, TagPosition, consts::U16, inout::InOutBuf}; mod asconcore; @@ -134,16 +134,15 @@ impl KeyInit for Ascon

{ impl AeadCore for Ascon

{ type NonceSize = U16; type TagSize = U16; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } -impl PostfixTagged for Ascon

{} - -impl AeadInPlaceDetached for Ascon

{ - fn encrypt_in_place_detached( +impl AeadInOut for Ascon

{ + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result, Error> { if (buffer.len() as u64) .checked_add(associated_data.len() as u64) @@ -153,14 +152,14 @@ impl AeadInPlaceDetached 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_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { if (buffer.len() as u64) @@ -171,7 +170,7 @@ impl AeadInPlaceDetached for Ascon

{ } let mut core = AsconCore::

::new(&self.key, nonce); - core.decrypt_inplace(buffer, associated_data, tag) + core.decrypt_inout(buffer, associated_data, tag) } } @@ -197,31 +196,30 @@ impl KeyInit for AsconAead128 { impl AeadCore for AsconAead128 { type NonceSize = U16; type TagSize = U16; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } -impl PostfixTagged for AsconAead128 {} - -impl AeadInPlaceDetached for AsconAead128 { +impl AeadInOut for AsconAead128 { #[inline(always)] - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result, Error> { self.0 - .encrypt_in_place_detached(nonce, associated_data, buffer) + .encrypt_inout_detached(nonce, associated_data, buffer) } #[inline(always)] - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { self.0 - .decrypt_in_place_detached(nonce, associated_data, buffer, tag) + .decrypt_inout_detached(nonce, associated_data, buffer, tag) } } diff --git a/belt-dwp/src/lib.rs b/belt-dwp/src/lib.rs index 9f602766..e49114c4 100644 --- a/belt-dwp/src/lib.rs +++ b/belt-dwp/src/lib.rs @@ -32,7 +32,7 @@ //! This crate has an optional `alloc` feature which can be disabled in e.g. //! microcontroller environments that don't have a heap. //! -//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! The [`AeadInOut::encrypt_in_place`] and [`AeadInOut::decrypt_in_place`] //! methods accept any type that impls the [`aead::Buffer`] trait which //! contains the plaintext for encryption or ciphertext for decryption. //! @@ -46,7 +46,7 @@ //! # fn main() -> Result<(), Box> { //! # #[cfg(all(feature = "os_rng", feature = "heapless"))] { //! use belt_dwp::{ -//! aead::{AeadInPlace, AeadInPlaceDetached, KeyInit, heapless::Vec}, +//! aead::{AeadInOut, KeyInit, heapless::Vec}, //! Nonce, BeltDwp //! }; //! @@ -73,11 +73,11 @@ //! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as //! [`aead::arrayvec::ArrayVec`]). -pub use aead::{self, AeadCore, AeadInPlace, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; pub use belt_block::BeltBlock; use aead::consts::{U8, U16}; -use aead::{AeadInPlaceDetached, PostfixTagged}; +use aead::{TagPosition, inout::InOutBuf}; use belt_block::cipher::crypto_common::InnerUser; use belt_block::cipher::{Block, BlockCipherEncrypt, StreamCipher}; use belt_ctr::cipher::InnerIvInit; @@ -128,15 +128,15 @@ where } } -impl AeadInPlaceDetached for Dwp +impl AeadInOut for Dwp where C: BlockCipherEncrypt + BlockSizeUser, { - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + mut buffer: InOutBuf<'_, '_, u8>, ) -> aead::Result { let sizes_block = get_sizes_block(associated_data.len(), buffer.len()); @@ -165,8 +165,8 @@ where // 4.2 𝑌𝑖 ← 𝑋𝑖 ⊕ Lo(belt-block(𝑠, 𝐾), |𝑋𝑖|) // 4.3 𝑡 ← 𝑡 ⊕ (𝑌𝑖 ‖ 0^{128−|𝑌𝑖|}) // 4.4 𝑡 ← 𝑡 * 𝑟. - enc_cipher.apply_keystream(buffer); - ghash.update_padded(buffer); + enc_cipher.apply_keystream_inout(buffer.reborrow()); + ghash.update_padded(buffer.get_out()); // 5. 𝑡 ← 𝑡 ⊕ (⟨|𝐼|⟩_64 ‖ ⟨|𝑋|⟩_64) ghash.xor_s(&sizes_block); @@ -178,11 +178,11 @@ where Ok(Tag::try_from(&tag[..8]).expect("Tag is always 8 bytes")) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> aead::Result<()> { let sizes_block = get_sizes_block(associated_data.len(), buffer.len()); @@ -206,7 +206,7 @@ where // 4. For 𝑖 = 1, 2, . . . , 𝑛 do: // 4.1 𝑡 ← 𝑡 ⊕ (𝑌𝑖 ‖ 0^{128−|𝑌𝑖|}) // 4.2 𝑡 ← 𝑡 * 𝑟. - ghash.update_padded(buffer); + ghash.update_padded(buffer.get_in()); // 5. 𝑡 ← 𝑡 ⊕ (⟨|𝐼|⟩_64 ‖ ⟨|𝑋|⟩_64) ghash.xor_s(&sizes_block); @@ -223,7 +223,7 @@ where // 8.2. 𝑋𝑖 ← 𝑌𝑖 ⊕ Lo(belt-block(𝑠, 𝐾), |𝑌𝑖|) let core = BeltCtrCore::inner_iv_init(&self.cipher, nonce); let mut enc_cipher = BeltCtr::from_core(core); - enc_cipher.apply_keystream(buffer); + enc_cipher.apply_keystream_inout(buffer); Ok(()) } else { Err(Error) @@ -231,14 +231,13 @@ where } } -impl PostfixTagged for Dwp where C: BlockCipherEncrypt + BlockSizeUser {} - impl AeadCore for Dwp where C: BlockCipherEncrypt + BlockSizeUser, { type NonceSize = C::BlockSize; type TagSize = U8; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } /// Get the sizes block for the GHASH diff --git a/belt-dwp/tests/belt.rs b/belt-dwp/tests/belt.rs index f405a71b..84c03c71 100644 --- a/belt-dwp/tests/belt.rs +++ b/belt-dwp/tests/belt.rs @@ -1,4 +1,4 @@ -use aead::AeadInPlaceDetached; +use aead::AeadInOut; use belt_dwp::{BeltDwp, KeyInit}; use hex_literal::hex; @@ -37,11 +37,11 @@ fn test_belt_dwp() { for vec in test_vectors { let mut x = vec.x; let belt_dwp = BeltDwp::new_from_slice(&vec.k).unwrap(); - let tag = belt_dwp.encrypt_in_place_detached(&vec.s.into(), &vec.i, &mut x); + let tag = belt_dwp.encrypt_inout_detached(&vec.s.into(), &vec.i, (&mut x[..]).into()); assert_eq!(vec.t, *tag.unwrap()); assert_eq!(vec.y, x); belt_dwp - .decrypt_in_place_detached(&vec.s.into(), &vec.i, &mut x, &tag.unwrap()) + .decrypt_inout_detached(&vec.s.into(), &vec.i, (&mut x[..]).into(), &tag.unwrap()) .unwrap(); assert_eq!(x, vec.x); } diff --git a/ccm/src/lib.rs b/ccm/src/lib.rs index bd51999b..a75e094f 100644 --- a/ccm/src/lib.rs +++ b/ccm/src/lib.rs @@ -42,12 +42,13 @@ //! [aead]: https://docs.rs/aead //! [1]: https://en.wikipedia.org/wiki/Authenticated_encryption -pub use aead::{self, AeadCore, AeadInPlaceDetached, Error, Key, KeyInit, KeySizeUser, consts}; +pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, consts}; use aead::{ - PostfixTagged, + TagPosition, array::{Array, ArraySize, typenum::Unsigned}, consts::U16, + inout::InOutBuf, }; use cipher::{ Block, BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipher, StreamCipherSeek, @@ -211,29 +212,22 @@ where { type NonceSize = N; type TagSize = M; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } -impl PostfixTagged for Ccm +impl AeadInOut for Ccm where C: BlockSizeUser + BlockCipherEncrypt, M: ArraySize + TagSize, N: ArraySize + NonceSize, { -} - -impl AeadInPlaceDetached for Ccm -where - C: BlockSizeUser + BlockCipherEncrypt, - M: ArraySize + TagSize, - N: ArraySize + NonceSize, -{ - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Nonce, adata: &[u8], - buffer: &mut [u8], + 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) @@ -242,21 +236,21 @@ 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_inout(buffer); } 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_inout(buffer); } Ok(Tag::try_from(&full_tag[..M::to_usize()]).expect("tag size mismatch")) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, adata: &[u8], - buffer: &mut [u8], + mut buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { let ext_nonce = Self::extend_nonce(nonce); @@ -266,14 +260,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_inout(buffer.reborrow()); } 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_inout(buffer.reborrow()); } - let mut full_tag = self.calc_mac(nonce, adata, buffer)?; + let mut full_tag = self.calc_mac(nonce, adata, buffer.get_out())?; if cb > 4 { let mut ctr = Ctr64BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce)); @@ -286,7 +280,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 10ce7276..f4b20fb8 100644 --- a/ccm/tests/mod.rs +++ b/ccm/tests/mod.rs @@ -1,6 +1,6 @@ #![cfg(feature = "alloc")] -use aead::{Aead, AeadInPlaceDetached, KeyInit, Payload, array::Array}; +use aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; use aes::{Aes128, Aes192, Aes256}; use ccm::{ Ccm, @@ -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_in_place_detached(&nonce, &[], &mut buf1); + let res = c.encrypt_inout_detached(&nonce, &[], buf1.as_mut_slice().into()); assert!(res.is_ok()); let mut buf2 = [1; u16::MAX as usize + 1]; - let res = c.encrypt_in_place_detached(&nonce, &[], &mut buf2); + let res = c.encrypt_inout_detached(&nonce, &[], buf2.as_mut_slice().into()); assert!(res.is_err()); } diff --git a/chacha20poly1305/src/cipher.rs b/chacha20poly1305/src/cipher.rs index 76bb4bf8..5c8df500 100644 --- a/chacha20poly1305/src/cipher.rs +++ b/chacha20poly1305/src/cipher.rs @@ -2,7 +2,7 @@ use ::cipher::{StreamCipher, StreamCipherSeek}; use aead::Error; -use aead::array::Array; +use aead::{array::Array, inout::InOutBuf}; use poly1305::{ Poly1305, universal_hash::{KeyInit, UniversalHash}, @@ -50,10 +50,10 @@ where } /// Encrypt the given message in-place, returning the authentication tag - pub(crate) fn encrypt_in_place_detached( + pub(crate) fn encrypt_inout_detached( mut self, associated_data: &[u8], - buffer: &mut [u8], + mut buffer: InOutBuf<'_, '_, u8>, ) -> Result { if buffer.len() / BLOCK_SIZE >= MAX_BLOCKS { return Err(Error); @@ -63,19 +63,19 @@ where // TODO(tarcieri): interleave encryption with Poly1305 // See: - self.cipher.apply_keystream(buffer); - self.mac.update_padded(buffer); + self.cipher.apply_keystream_inout(buffer.reborrow()); + self.mac.update_padded(buffer.get_out()); - self.authenticate_lengths(associated_data, buffer)?; + self.authenticate_lengths(associated_data, buffer.get_out())?; Ok(self.mac.finalize()) } /// Decrypt the given message, first authenticating ciphertext integrity /// and returning an error if it's been tampered with. - pub(crate) fn decrypt_in_place_detached( + pub(crate) fn decrypt_inout_detached( mut self, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { if buffer.len() / BLOCK_SIZE >= MAX_BLOCKS { @@ -83,14 +83,14 @@ where } self.mac.update_padded(associated_data); - self.mac.update_padded(buffer); - self.authenticate_lengths(associated_data, buffer)?; + self.mac.update_padded(buffer.get_in()); + self.authenticate_lengths(associated_data, buffer.get_in())?; // This performs a constant-time comparison using the `subtle` crate if self.mac.verify(tag).is_ok() { // TODO(tarcieri): interleave decryption with Poly1305 // See: - self.cipher.apply_keystream(buffer); + self.cipher.apply_keystream_inout(buffer); Ok(()) } else { Err(Error) diff --git a/chacha20poly1305/src/lib.rs b/chacha20poly1305/src/lib.rs index c42e057d..d829f8a7 100644 --- a/chacha20poly1305/src/lib.rs +++ b/chacha20poly1305/src/lib.rs @@ -46,7 +46,7 @@ //! This crate has an optional `alloc` feature which can be disabled in e.g. //! microcontroller environments that don't have a heap. //! -//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! The [`AeadInOut::encrypt_in_place`] and [`AeadInOut::decrypt_in_place`] //! methods accept any type that impls the [`aead::Buffer`] trait which //! contains the plaintext for encryption or ciphertext for decryption. //! @@ -60,7 +60,7 @@ #![cfg_attr(not(all(feature = "os_rng", feature = "heapless")), doc = "```ignore")] //! # fn main() -> Result<(), Box> { //! use chacha20poly1305::{ -//! aead::{AeadCore, AeadInPlace, KeyInit, rand_core::OsRng, heapless::Vec}, +//! aead::{AeadCore, AeadInOut, KeyInit, rand_core::OsRng, heapless::Vec}, //! ChaCha20Poly1305, Nonce, //! }; //! @@ -139,14 +139,15 @@ mod cipher; -pub use aead::{self, AeadCore, AeadInPlaceDetached, Error, KeyInit, KeySizeUser, consts}; +pub use aead::{self, AeadCore, AeadInOut, Error, KeyInit, KeySizeUser, consts}; use self::cipher::Cipher; use ::cipher::{KeyIvInit, StreamCipher, StreamCipherSeek}; use aead::{ - PostfixTagged, + TagPosition, array::{Array, ArraySize}, consts::{U12, U16, U24, U32}, + inout::InOutBuf, }; use core::marker::PhantomData; @@ -245,41 +246,31 @@ where { type NonceSize = N; type TagSize = U16; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } -impl PostfixTagged for ChaChaPoly1305 +impl AeadInOut for ChaChaPoly1305 where C: KeyIvInit + StreamCipher + StreamCipherSeek, N: ArraySize, { -} - -impl AeadInPlaceDetached for ChaChaPoly1305 -where - C: KeyIvInit + StreamCipher + StreamCipherSeek, - N: ArraySize, -{ - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &aead::Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result { - Cipher::new(C::new(&self.key, nonce)).encrypt_in_place_detached(associated_data, buffer) + Cipher::new(C::new(&self.key, nonce)).encrypt_inout_detached(associated_data, buffer) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &aead::Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { - Cipher::new(C::new(&self.key, nonce)).decrypt_in_place_detached( - associated_data, - buffer, - tag, - ) + Cipher::new(C::new(&self.key, nonce)).decrypt_inout_detached(associated_data, buffer, tag) } } diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index dbf9bef8..7c360207 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -20,7 +20,6 @@ rust-version = "1.85" [dependencies] aead = { version = "0.6.0-rc.0", default-features = false } aes = { version = "=0.9.0-pre.3", features = ["hazmat"], default-features = false } -inout = { version = "0.2.0-rc.4", 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 f7c78841..8e414df9 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -62,7 +62,7 @@ //! This crate has an optional `alloc` feature which can be disabled in e.g. //! microcontroller environments that don't have a heap. //! -//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! The [`AeadInOut::encrypt_in_place`] and [`AeadInOut::decrypt_in_place`] //! methods accept any type that impls the [`aead::Buffer`] trait which //! contains the plaintext for encryption or ciphertext for decryption. //! @@ -76,7 +76,7 @@ //! # #[cfg(feature = "heapless")] //! # { //! use deoxys::{DeoxysII256, Nonce}; // Can be `DeoxysI128`, `DeoxysI256`, `DeoxysII128` of `DeoxysII256` -//! use deoxys::aead::{AeadCore, AeadInPlace, KeyInit, rand_core::OsRng, heapless::Vec}; +//! use deoxys::aead::{AeadCore, AeadInOut, KeyInit, rand_core::OsRng, heapless::Vec}; //! //! let key = DeoxysII256::generate_key().expect("generate key"); //! let cipher = DeoxysII256::new(&key); @@ -110,15 +110,15 @@ mod deoxys_bc; /// Operation modes for Deoxys. mod modes; -pub use aead::{self, AeadCore, AeadInPlaceDetached, Error, Key, KeyInit, KeySizeUser, consts}; +pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, consts}; use aead::{ - PostfixTagged, + TagPosition, array::{Array, ArraySize}, consts::U16, + inout::{InOut, InOutBuf}, }; use core::marker::PhantomData; -use inout::{InOut, InOutBuf}; /// Deoxys-I with 128-bit keys pub type DeoxysI128 = Deoxys, deoxys_bc::DeoxysBc256>; @@ -262,42 +262,36 @@ where { type NonceSize = M::NonceSize; type TagSize = U16; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } -impl PostfixTagged for Deoxys +impl AeadInOut for Deoxys where M: DeoxysMode, B: DeoxysBcType, { -} - -impl AeadInPlaceDetached for Deoxys -where - M: DeoxysMode, - B: DeoxysBcType, -{ - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result { Ok(Tag::from(M::encrypt_inout( nonce, associated_data, - buffer.into(), + buffer, &self.subkeys, ))) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { - M::decrypt_inout(nonce, associated_data, buffer.into(), tag, &self.subkeys) + M::decrypt_inout(nonce, associated_data, buffer, tag, &self.subkeys) } } diff --git a/deoxys/src/modes.rs b/deoxys/src/modes.rs index a4e01bb9..dd56e030 100644 --- a/deoxys/src/modes.rs +++ b/deoxys/src/modes.rs @@ -2,9 +2,9 @@ use super::{Block, DeoxysBcType, DeoxysKey, DeoxysMode, Tag, Tweak}; use aead::{ array::Array, consts::{U8, U15, U16}, + inout::InOutBuf, }; use core::marker::PhantomData; -use inout::InOutBuf; use subtle::ConstantTimeEq; const TWEAK_AD: u8 = 0x20; diff --git a/eax/src/lib.rs b/eax/src/lib.rs index c4d6cf03..1abc7c64 100644 --- a/eax/src/lib.rs +++ b/eax/src/lib.rs @@ -38,7 +38,7 @@ //! This crate has an optional `alloc` feature which can be disabled in e.g. //! microcontroller environments that don't have a heap. //! -//! The [`AeadInPlace::encrypt_in_place`] and [`AeadInPlace::decrypt_in_place`] +//! The [`AeadInOut::encrypt_in_place`] and [`AeadInOut::decrypt_in_place`] //! methods accept any type that impls the [`aead::Buffer`] trait which //! contains the plaintext for encryption or ciphertext for decryption. //! @@ -56,7 +56,7 @@ //! use eax::aead::{ //! array::Array, //! heapless::Vec, -//! AeadCore, AeadInPlace, KeyInit, rand_core::OsRng +//! AeadCore, AeadInOut, KeyInit, rand_core::OsRng //! }; //! //! pub type Aes256Eax = Eax; @@ -97,7 +97,7 @@ //! # { //! use aes::Aes256; //! use eax::Eax; -//! use eax::aead::{AeadInPlaceDetached, KeyInit, array::Array}; +//! use eax::aead::{AeadInOut, KeyInit, array::Array}; //! use eax::aead::heapless::Vec; //! use eax::aead::consts::{U8, U128}; //! @@ -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_in_place_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,15 +119,15 @@ //! assert_ne!(&buffer, b"plaintext message"); //! //! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place_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"); //! # } //! ``` -pub use aead::{self, AeadCore, AeadInPlaceDetached, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; pub use cipher; -use aead::PostfixTagged; +use aead::{TagPosition, inout::InOutBuf}; use cipher::{ BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore, array::Array, consts::U16, crypto_common::OutputSizeUser, typenum::Unsigned, @@ -210,25 +210,19 @@ where { type NonceSize = Cipher::BlockSize; type TagSize = M; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } -impl PostfixTagged for Eax +impl AeadInOut for Eax where Cipher: BlockSizeUser + BlockCipherEncrypt + Clone + KeyInit, M: TagSize, { -} - -impl AeadInPlaceDetached for Eax -where - Cipher: BlockSizeUser + BlockCipherEncrypt + Clone + KeyInit, - M: TagSize, -{ - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [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 +241,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_out()); // 5. tag ← n ^ h ^ c // (^ means xor) @@ -267,11 +261,11 @@ where Ok(tag) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX { @@ -285,7 +279,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 +299,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 74991c49..4e7fd1c2 100644 --- a/ocb3/Cargo.toml +++ b/ocb3/Cargo.toml @@ -23,7 +23,6 @@ dbl = "0.4.0-rc.2" subtle = { version = "2", default-features = false } aead-stream = { version = "=0.6.0-pre", optional = true, default-features = false } zeroize = { version = "1", optional = true, default-features = false } -inout = { version = "0.2.0-rc.4", default-features = false } [dev-dependencies] aead = { version = "0.6.0-rc.0", features = ["dev"], default-features = false } diff --git a/ocb3/src/lib.rs b/ocb3/src/lib.rs index afcde3a5..44838eb5 100644 --- a/ocb3/src/lib.rs +++ b/ocb3/src/lib.rs @@ -14,11 +14,15 @@ pub mod consts { } pub use aead::{ - self, AeadCore, AeadInPlaceDetached, Error, KeyInit, KeySizeUser, + self, AeadCore, AeadInOut, Error, KeyInit, KeySizeUser, array::{Array, AssocArraySize}, }; -use aead::{PostfixTagged, array::ArraySize}; +use aead::{ + TagPosition, + array::ArraySize, + inout::{InOut, InOutBuf}, +}; use cipher::{ BlockCipherDecrypt, BlockCipherEncrypt, BlockSizeUser, consts::{U2, U12, U16}, @@ -26,7 +30,6 @@ use cipher::{ }; use core::marker::PhantomData; use dbl::Dbl; -use inout::{InOut, InOutBuf}; use subtle::ConstantTimeEq; /// Number of L values to be precomputed. Precomputing m values, allows @@ -171,6 +174,7 @@ where { type NonceSize = NonceSize; type TagSize = TagSize; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } impl From for Ocb3 @@ -193,27 +197,18 @@ where } } -impl PostfixTagged for Ocb3 -where - Cipher: BlockSizeUser + BlockCipherEncrypt + BlockCipherDecrypt, - NonceSize: sealed::NonceSizes, - TagSize: sealed::TagSizes, -{ -} - -impl AeadInPlaceDetached for Ocb3 +impl AeadInOut for Ocb3 where Cipher: BlockSizeUser + BlockCipherEncrypt + BlockCipherDecrypt, NonceSize: sealed::NonceSizes, TagSize: sealed::TagSizes, { - fn encrypt_in_place_detached( + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> aead::Result> { - let buffer = InOutBuf::from(buffer); if (buffer.len() > P_MAX) || (associated_data.len() > A_MAX) { unimplemented!() } @@ -266,14 +261,14 @@ where Ok(tag) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + 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_inout_return_tag(nonce, associated_data, buffer); if expected_tag.ct_eq(tag).into() { Ok(()) } else { @@ -289,16 +284,15 @@ where TagSize: sealed::TagSizes, { /// Decrypts in place and returns expected tag. - pub(crate) fn decrypt_in_place_return_tag( + pub(crate) fn decrypt_inout_return_tag( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> aead::Tag { if (buffer.len() > C_MAX) || (associated_data.len() > A_MAX) { unimplemented!() } - let buffer = InOutBuf::from(buffer); // First, try to process many blocks at once. let (tail, index, mut offset_i, mut checksum_i) = self.wide_decrypt(nonce, buffer); diff --git a/ocb3/tests/kats.rs b/ocb3/tests/kats.rs index 7181c5c9..1b30c726 100644 --- a/ocb3/tests/kats.rs +++ b/ocb3/tests/kats.rs @@ -1,7 +1,7 @@ #![allow(non_snake_case)] use aead::{ - AeadInPlaceDetached, KeyInit, + AeadInOut, KeyInit, consts::{U8, U12}, }; use aes::{Aes128, Aes192, Aes256}; @@ -38,7 +38,11 @@ macro_rules! rfc7253_wider_variety { let N = num2str96(3 * i + 1); let mut buffer = S.clone(); let tag = ocb - .encrypt_in_place_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_in_place_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_in_place_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_in_place_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)) diff --git a/xaes-256-gcm/src/lib.rs b/xaes-256-gcm/src/lib.rs index a89ff81e..d36c8fc3 100644 --- a/xaes-256-gcm/src/lib.rs +++ b/xaes-256-gcm/src/lib.rs @@ -56,7 +56,7 @@ pub use aes_gcm; use core::ops::{Div, Mul}; use aead::{ - AeadCore, AeadInPlaceDetached, Error, KeyInit, KeySizeUser, PostfixTagged, array::Array, + AeadCore, AeadInOut, Error, KeyInit, KeySizeUser, TagPosition, array::Array, inout::InOutBuf, }; use aes::Aes256; use aes_gcm::Aes256Gcm; @@ -96,6 +96,7 @@ pub const C_MAX: u64 = (1 << 36) + 16; impl AeadCore for Xaes256Gcm { type NonceSize = NonceSize; type TagSize = TagSize; + const TAG_POSITION: TagPosition = TagPosition::Postfix; } impl KeySizeUser for Xaes256Gcm { @@ -126,14 +127,12 @@ impl KeyInit for Xaes256Gcm { } } -impl PostfixTagged for Xaes256Gcm {} - -impl AeadInPlaceDetached for Xaes256Gcm { - fn encrypt_in_place_detached( +impl AeadInOut for Xaes256Gcm { + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result { if buffer.len() as u64 > P_MAX || associated_data.len() as u64 > A_MAX { return Err(Error); @@ -141,14 +140,14 @@ impl AeadInPlaceDetached for Xaes256Gcm { let (n1, n) = nonce.split_ref::<>::Output>(); let k = self.derive_key(n1); - Aes256Gcm::new(&k).encrypt_in_place_detached(n, associated_data, buffer) + Aes256Gcm::new(&k).encrypt_inout_detached(n, associated_data, buffer) } - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<(), Error> { if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX { @@ -157,7 +156,7 @@ impl AeadInPlaceDetached for Xaes256Gcm { let (n1, n) = nonce.split_ref::<>::Output>(); let k = self.derive_key(n1); - Aes256Gcm::new(&k).decrypt_in_place_detached(n, associated_data, buffer, tag) + Aes256Gcm::new(&k).decrypt_inout_detached(n, associated_data, buffer, tag) } } diff --git a/xaes-256-gcm/tests/xaes256gcm.rs b/xaes-256-gcm/tests/xaes256gcm.rs index 1bb04ce1..62b85d7e 100644 --- a/xaes-256-gcm/tests/xaes256gcm.rs +++ b/xaes-256-gcm/tests/xaes256gcm.rs @@ -4,7 +4,7 @@ #[path = "../../aes-gcm/tests/common/mod.rs"] mod common; -use aes_gcm::aead::{Aead, AeadInPlaceDetached, KeyInit, Payload, array::Array}; +use aes_gcm::aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; use common::TestVector; use hex_literal::hex; use xaes_256_gcm::Xaes256Gcm;