diff --git a/Cargo.lock b/Cargo.lock index 7c6f9516..76024806 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,28 +6,18 @@ version = 4 [[package]] name = "aead" version = "0.6.0-rc.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b657e772794c6b04730ea897b66a058ccd866c16d1967da05eeeecec39043fe" +source = "git+https://github.com/RustCrypto/traits?branch=aead%2Fminimize#6bbdcb757e8d2f88296a12f12707559bd19d8dbc" dependencies = [ - "arrayvec", "blobby", - "bytes", "crypto-common", "inout", ] -[[package]] -name = "aead-stream" -version = "0.6.0-rc.3" -dependencies = [ - "aead", -] - [[package]] name = "aes" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" +checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138" dependencies = [ "cipher", "cpubits", @@ -84,12 +74,6 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - [[package]] name = "ascon" version = "0.5.0-rc.0" @@ -120,9 +104,9 @@ dependencies = [ [[package]] name = "belt-ctr" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618f4ade7527d77aa56ba5fb98d483ef83e42030f7c572cd9b0fb3e047cc66d7" +checksum = "56a9423f9b33256ccd2fd40dd42e3de48dac0772107cb772325988a76646b45a" dependencies = [ "belt-block", "cipher", @@ -143,9 +127,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "blobby" @@ -163,12 +147,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "bytes" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" - [[package]] name = "ccm" version = "0.6.0-rc.3" @@ -212,9 +190,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ "block-buffer", "crypto-common", @@ -235,15 +213,15 @@ dependencies = [ [[package]] name = "cmov" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0758edba32d61d1fd9f4d69491b47604b91ee2f7e6b33de7e54ca4ebe55dc3" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" [[package]] name = "cpubits" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" @@ -256,9 +234,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "getrandom", "hybrid-array", @@ -267,18 +245,18 @@ dependencies = [ [[package]] name = "ctr" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17469f8eb9bdbfad10f71f4cfddfd38b01143520c0e717d8796ccb4d44d44e42" +checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21" dependencies = [ "cipher", ] [[package]] name = "ctutils" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1005a6d4446f5120ef475ad3d2af2b30c49c2c9c6904258e3bb30219bebed5e4" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" dependencies = [ "cmov", ] @@ -305,9 +283,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", "crypto-common", @@ -372,9 +350,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -390,9 +368,9 @@ checksum = "e712f64ec3850b98572bffac52e2c6f282b29fe6c5fa6d42334b30be438d95c1" [[package]] name = "hybrid-array" -version = "0.4.8" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8655f91cd07f2b9d0c24137bd650fe69617773435ee5ec83022377777ce65ef1" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" dependencies = [ "typenum", "zeroize", @@ -406,12 +384,12 @@ checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -439,28 +417,27 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "log" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "ocb3" version = "0.2.0-rc.3" dependencies = [ "aead", - "aead-stream", "aes", "cipher", "ctr", @@ -538,15 +515,15 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand_core" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" @@ -579,9 +556,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -609,9 +586,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "unicode-ident" @@ -786,7 +763,6 @@ name = "xaes-256-gcm" version = "0.1.0-rc.3" dependencies = [ "aead", - "aead-stream", "aes", "aes-gcm", "cipher", diff --git a/Cargo.toml b/Cargo.toml index d5fdeb67..d58bc9e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] resolver = "3" members = [ - "aead-stream", + #"aead-stream", "aes-gcm", "aes-gcm-siv", "aes-siv", @@ -16,5 +16,5 @@ members = [ ] [patch.crates-io] -aead-stream = { path = "aead-stream" } aes-gcm = { path = "aes-gcm" } +aead = { git = "https://github.com/RustCrypto/traits", branch = "aead/minimize" } diff --git a/aead-stream/src/lib.rs b/aead-stream/src/lib.rs index 91c2040f..48e4d4ae 100644 --- a/aead-stream/src/lib.rs +++ b/aead-stream/src/lib.rs @@ -6,11 +6,11 @@ extern crate alloc; use aead::{ - AeadCore, AeadInOut, Buffer, Error, Result, array::{ + typenum::{Unsigned, U4, U5}, Array, ArraySize, - typenum::{U4, U5, Unsigned}, }, + AeadCore, Error, Result, }; use core::ops::{AddAssign, Sub}; @@ -32,7 +32,7 @@ pub type NonceSize = /// Create a new STREAM from the provided AEAD. pub trait NewStream: StreamPrimitive where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, NonceSize: ArraySize, { @@ -57,7 +57,7 @@ where /// Deliberately immutable and stateless to permit parallel operation. pub trait StreamPrimitive where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, NonceSize: ArraySize, { @@ -165,7 +165,7 @@ macro_rules! impl_stream_object { #[derive(Debug)] pub struct $name where - A: AeadInOut, + A: AeadCore, S: StreamPrimitive, A::NonceSize: Sub<>::NonceOverhead>, NonceSize: ArraySize, @@ -179,7 +179,7 @@ macro_rules! impl_stream_object { impl $name where - A: AeadInOut, + A: AeadCore, S: StreamPrimitive, A::NonceSize: Sub<>::NonceOverhead>, NonceSize: ArraySize, @@ -343,7 +343,7 @@ pub type DecryptorLE31 = Decryptor>; #[derive(Debug)] pub struct StreamBE32 where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -356,7 +356,7 @@ where impl NewStream for StreamBE32 where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -370,7 +370,7 @@ where impl StreamPrimitive for StreamBE32 where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -404,7 +404,7 @@ where impl StreamBE32 where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -433,7 +433,7 @@ where #[derive(Debug)] pub struct StreamLE31 where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -446,7 +446,7 @@ where impl NewStream for StreamLE31 where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -460,7 +460,7 @@ where impl StreamPrimitive for StreamLE31 where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { @@ -494,7 +494,7 @@ where impl StreamLE31 where - A: AeadInOut, + A: AeadCore, A::NonceSize: Sub, <::NonceSize as Sub>::Output: ArraySize, { diff --git a/aes-gcm-siv/Cargo.toml b/aes-gcm-siv/Cargo.toml index c739f2cd..721f0f29 100644 --- a/aes-gcm-siv/Cargo.toml +++ b/aes-gcm-siv/Cargo.toml @@ -31,9 +31,7 @@ aead = { version = "0.6.0-rc.10", features = ["dev"], default-features = false } [features] default = ["aes", "alloc", "getrandom"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] [package.metadata.docs.rs] diff --git a/aes-gcm-siv/src/lib.rs b/aes-gcm-siv/src/lib.rs index 385ddbb8..74b1842e 100644 --- a/aes-gcm-siv/src/lib.rs +++ b/aes-gcm-siv/src/lib.rs @@ -32,59 +32,8 @@ //! # Ok(()) //! # } //! ``` -//! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]), and enabling the `bytes` feature of this crate will -//! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the -//! [`aead`] crate as [`aead::bytes::BytesMut`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! // NOTE: requires the `arrayvec` and `getrandom` features are enabled -//! -//! use aes_gcm_siv::{ -//! aead::{AeadInOut, AeadCore, Buffer, Generate, Key, KeyInit, arrayvec::ArrayVec}, -//! Aes256GcmSiv, Nonce, // Or `Aes128GcmSiv` -//! }; -//! -//! let key = Key::::generate(); -//! let cipher = Aes256GcmSiv::new(&key); -//! -//! let nonce = Nonce::generate(); // 96-bits; unique per message -//! let mut buffer: ArrayVec = ArrayVec::new(); // Note: buffer needs 16-bytes overhead for auth tag -//! buffer.extend_from_slice(b"plaintext message"); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer)?; -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer)?; -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) -//! # } -//! ``` -pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadTagPosition, Error, Key, KeyInit, KeySizeUser}; #[cfg(feature = "aes")] pub use aes; @@ -167,13 +116,7 @@ where { type NonceSize = U12; type TagSize = U16; - const TAG_POSITION: TagPosition = TagPosition::Postfix; -} -impl AeadInOut for AesGcmSiv -where - Aes: BlockSizeUser + BlockCipherEncrypt + KeyInit, -{ fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -199,6 +142,13 @@ where } } +impl AeadTagPosition for AesGcmSiv +where + Aes: BlockSizeUser + BlockCipherEncrypt + KeyInit, +{ + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + /// AES-GCM-SIV: Misuse-Resistant Authenticated Encryption Cipher (RFC8452). struct Cipher where diff --git a/aes-gcm/Cargo.toml b/aes-gcm/Cargo.toml index dcec3a8a..7e3c8568 100644 --- a/aes-gcm/Cargo.toml +++ b/aes-gcm/Cargo.toml @@ -35,10 +35,8 @@ hex-literal = "1" default = ["aes", "alloc", "getrandom"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] hazmat = [] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] [package.metadata.docs.rs] diff --git a/aes-gcm/src/lib.rs b/aes-gcm/src/lib.rs index c101d646..7ccd8cac 100644 --- a/aes-gcm/src/lib.rs +++ b/aes-gcm/src/lib.rs @@ -33,58 +33,8 @@ //! # Ok(()) //! # } //! ``` -//! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]), and enabling the `bytes` feature of this crate will -//! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the -//! [`aead`] crate as [`aead::bytes::BytesMut`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! // NOTE: requires the `arrayvec` and `getrandom` features are enabled -//! -//! use aes_gcm::{ -//! aead::{AeadCore, AeadInOut, Generate, Key, KeyInit, arrayvec::ArrayVec}, -//! Aes256Gcm, Nonce, // Or `Aes128Gcm` -//! }; -//! -//! let key = Key::::generate(); -//! let cipher = Aes256Gcm::new(&key); -//! -//! let nonce = Nonce::generate(); // MUST be unique per message -//! let mut buffer: ArrayVec = ArrayVec::new(); // Note: buffer needs 16-bytes overhead for auth tag -//! buffer.try_extend_from_slice(b"plaintext message").unwrap(); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer)?; -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer)?; -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) -//! # } -pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadTagPosition, Error, Key, KeyInit, KeySizeUser}; #[cfg(feature = "aes")] pub use aes; @@ -246,20 +196,13 @@ where impl AeadCore for AesGcm where + Aes: BlockSizeUser + BlockCipherEncrypt, NonceSize: ArraySize, TagSize: self::TagSize, { type NonceSize = NonceSize; type TagSize = TagSize; - const TAG_POSITION: TagPosition = TagPosition::Postfix; -} -impl AeadInOut for AesGcm -where - Aes: BlockSizeUser + BlockCipherEncrypt, - NonceSize: ArraySize, - TagSize: self::TagSize, -{ fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -307,6 +250,15 @@ where } } +impl AeadTagPosition for AesGcm +where + Aes: BlockSizeUser + BlockCipherEncrypt, + NonceSize: ArraySize, + TagSize: self::TagSize, +{ + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + impl AesGcm where Aes: BlockSizeUser + BlockCipherEncrypt, diff --git a/aes-gcm/tests/aes128gcm.rs b/aes-gcm/tests/aes128gcm.rs index 475f2f2b..98d41821 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, AeadInOut, KeyInit, Payload, array::Array}; +use aes_gcm::aead::{Aead, AeadCore, 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 b9910d32..47ec82cf 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, AeadInOut, KeyInit, Payload, array::Array}; +use aes_gcm::aead::{Aead, AeadCore, KeyInit, Payload, array::Array}; use hex_literal::hex; /// NIST CAVS vectors diff --git a/aes-siv/Cargo.toml b/aes-siv/Cargo.toml index 41260ae3..562d9712 100644 --- a/aes-siv/Cargo.toml +++ b/aes-siv/Cargo.toml @@ -37,10 +37,7 @@ hex-literal = "1" [features] default = ["alloc", "getrandom"] alloc = ["aead/alloc"] - -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] [package.metadata.docs.rs] diff --git a/aes-siv/src/lib.rs b/aes-siv/src/lib.rs index 7ded3b96..fcdc2cd2 100644 --- a/aes-siv/src/lib.rs +++ b/aes-siv/src/lib.rs @@ -32,64 +32,13 @@ //! # Ok(()) //! # } //! ``` -//! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]), and enabling the `bytes` feature of this crate will -//! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the -//! [`aead`] crate as [`aead::bytes::BytesMut`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! // NOTE: requires the `arrayvec` and `getrandom` features are enabled -//! -//! use aes_siv::{ -//! aead::{AeadCore, AeadInOut, Generate, Key, KeyInit, arrayvec::ArrayVec}, -//! Aes256SivAead, Nonce, // Or `Aes128SivAead` -//! }; -//! -//! let key = Key::::generate(); -//! let cipher = Aes256SivAead::new(&key); -//! -//! let nonce = Nonce::generate(); // MUST be unique per message -//! let mut buffer: ArrayVec = ArrayVec::new(); // Note: buffer needs 16-bytes overhead for auth tag -//! buffer.try_extend_from_slice(b"plaintext message").unwrap(); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer)?; -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer)?; -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) -//! # } -//! ``` #[cfg(feature = "alloc")] extern crate alloc; pub mod siv; -pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadTagPosition, Error, Key, KeyInit, KeySizeUser}; use crate::siv::Siv; use aead::{ @@ -200,6 +149,7 @@ where impl AeadCore for SivAead where Self: KeySizeUser, + Siv: KeyInit + KeySizeUser::KeySize>, C: BlockSizeUser + BlockCipherEncrypt + KeyInit + KeySizeUser, M: Mac + FixedOutputReset + KeyInit, ::KeySize: Add, @@ -211,18 +161,7 @@ where // https://tools.ietf.org/html/rfc5297#section-6 type NonceSize = NonceSize; type TagSize = U16; - const TAG_POSITION: TagPosition = TagPosition::Prefix; -} -impl AeadInOut 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_inout_detached( &self, nonce: &Array, @@ -247,3 +186,15 @@ where ) } } + +impl AeadTagPosition for SivAead +where + Self: KeySizeUser, + Siv: KeyInit + KeySizeUser::KeySize>, + C: BlockSizeUser + BlockCipherEncrypt + KeyInit + KeySizeUser, + M: Mac + FixedOutputReset + KeyInit, + ::KeySize: Add, + NonceSize: ArraySize + IsGreaterOrEqual, +{ + const TAG_POSITION: TagPosition = TagPosition::Prefix; +} diff --git a/aes-siv/src/siv.rs b/aes-siv/src/siv.rs index 593cfe71..c0e5d0f5 100644 --- a/aes-siv/src/siv.rs +++ b/aes-siv/src/siv.rs @@ -70,7 +70,7 @@ use crate::Tag; use aead::{ - Buffer, Error, + Error, array::{Array, ArraySize, typenum::U16}, inout::InOutBuf, }; @@ -83,12 +83,12 @@ use core::ops::Add; use dbl::Dbl; use digest::{CtOutput, FixedOutputReset, Mac}; -#[cfg(feature = "alloc")] -use alloc::vec::Vec; - #[cfg(feature = "pmac")] use pmac::Pmac; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + /// Size of the (synthetic) initialization vector in bytes pub const IV_SIZE: usize = 16; @@ -171,53 +171,6 @@ where C: BlockSizeUser + BlockCipherEncrypt + KeyInit + KeySizeUser, M: Mac + FixedOutputReset + KeyInit, { - /// Encrypt the given plaintext, allocating and returning a `Vec` for - /// the ciphertext. - /// - /// # Errors - /// - /// Returns [`Error`] if `plaintext.len()` is less than `M::OutputSize`. - /// Returns [`Error`] if `headers.len()` is greater than [`MAX_HEADERS`]. - #[cfg(feature = "alloc")] - pub fn encrypt(&mut self, headers: I, plaintext: &[u8]) -> Result, Error> - where - I: IntoIterator, - T: AsRef<[u8]>, - { - let mut buffer = Vec::with_capacity(plaintext.len() + IV_SIZE); - buffer.extend_from_slice(plaintext); - self.encrypt_in_place(headers, &mut buffer)?; - Ok(buffer) - } - - /// Encrypt the given buffer containing a plaintext message in-place. - /// - /// # Errors - /// - /// 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( - &mut self, - headers: I, - buffer: &mut dyn Buffer, - ) -> Result<(), Error> - where - I: IntoIterator, - T: AsRef<[u8]>, - { - let pt_len = buffer.len(); - - // 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_inout_detached` - buffer.as_mut().copy_within(..pt_len, 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(()) - } - /// Encrypt the given plaintext in-place, returning the SIV tag on success. /// /// # Errors @@ -239,48 +192,6 @@ where Ok(siv_tag) } - /// Decrypt the given ciphertext, allocating and returning a `Vec` for the plaintext. - /// Or returning an error in the event the provided authentication tag does not match the given ciphertext. - #[cfg(feature = "alloc")] - pub fn decrypt(&mut self, headers: I, ciphertext: &[u8]) -> Result, Error> - where - I: IntoIterator, - T: AsRef<[u8]>, - { - let mut buffer = ciphertext.to_vec(); - self.decrypt_in_place(headers, &mut buffer)?; - Ok(buffer) - } - - /// 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. - pub fn decrypt_in_place( - &mut self, - headers: I, - buffer: &mut dyn Buffer, - ) -> Result<(), Error> - where - I: IntoIterator, - T: AsRef<[u8]>, - { - if buffer.len() < IV_SIZE { - return Err(Error); - } - - 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..]).into(), &siv_tag)?; - - let pt_len = buffer.len() - IV_SIZE; - - // TODO(tarcieri): add offset param to `encrypt_inout_detached` - buffer.as_mut().copy_within(IV_SIZE.., 0); - buffer.truncate(pt_len); - Ok(()) - } - /// Decrypt the given ciphertext in-place, authenticating it against the /// provided SIV tag. /// @@ -310,6 +221,48 @@ where } } + /// Encrypt the given plaintext, and return the resulting + /// ciphertext as a vector of bytes. + #[cfg(feature = "alloc")] + pub fn encrypt(&mut self, headers: I, plaintext: &[u8]) -> Result, Error> + where + I: IntoIterator, + T: AsRef<[u8]>, + { + let tag_len = size_of::(); + let ct_len = plaintext.len().checked_add(tag_len).ok_or(Error)?; + let mut buffer = alloc::vec![0u8; ct_len]; + + let (tag_dst, ct_dst) = buffer.split_at_mut(tag_len); + + let buf = InOutBuf::new(plaintext, ct_dst).expect("`pt` and `ct_dst` have the same length"); + let tag = self.encrypt_inout_detached(headers, buf)?; + tag_dst.copy_from_slice(&tag); + + Ok(buffer) + } + + /// Decrypt the given ciphertext, and return the resulting plaintext + /// as a vector of bytes. + #[cfg(feature = "alloc")] + pub fn decrypt(&mut self, headers: I, ciphertext: &[u8]) -> Result, Error> + where + I: IntoIterator, + T: AsRef<[u8]>, + { + let tag_len = size_of::(); + let ct_len = ciphertext.len().checked_sub(tag_len).ok_or(Error)?; + + let (tag, ct) = ciphertext.split_at(tag_len); + + let tag = tag.try_into().expect("`tag` has correct length"); + let mut pt_dst = alloc::vec![0u8; ct_len]; + let buf = InOutBuf::new(ct, &mut pt_dst).expect("`ct` and `pt_dst` have the same length"); + self.decrypt_inout_detached(headers, buf, tag)?; + + Ok(pt_dst) + } + /// XOR the given buffer with the keystream for the given IV 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 diff --git a/aes-siv/tests/aead.rs b/aes-siv/tests/aead.rs index 4dcf1e38..ef6ab270 100644 --- a/aes-siv/tests/aead.rs +++ b/aes-siv/tests/aead.rs @@ -108,7 +108,7 @@ macro_rules! tests { mod aes128cmacsivaead { use super::TestVector; use aes_siv::Aes128SivAead; - use aes_siv::aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; + use aes_siv::aead::{Aead, AeadCore, 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, AeadInOut, KeyInit, Payload, array::Array}; + use aes_siv::aead::{Aead, AeadCore, 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 2f916af4..4525c05a 100644 --- a/ascon-aead128/Cargo.toml +++ b/ascon-aead128/Cargo.toml @@ -23,9 +23,7 @@ aead = { version = "0.6.0-rc.10", features = ["dev"] } [features] default = ["alloc", "getrandom"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] zeroize = ["dep:zeroize", "ascon/zeroize"] diff --git a/ascon-aead128/src/lib.rs b/ascon-aead128/src/lib.rs index 6282a237..51a9c566 100644 --- a/ascon-aead128/src/lib.rs +++ b/ascon-aead128/src/lib.rs @@ -32,63 +32,14 @@ //! # Ok(()) //! # } //! ``` -//! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]), and enabling the `bytes` feature of this crate will -//! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the -//! [`aead`] crate as [`aead::bytes::BytesMut`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! // NOTE: requires the `arrayvec` and `getrandom` features are enabled -//! -//! use ascon_aead128::{ -//! aead::{AeadCore, AeadInOut, Generate, KeyInit, arrayvec::ArrayVec}, -//! AsconAead128, AsconAead128Key, AsconAead128Nonce -//! }; -//! -//! let key = AsconAead128Key::generate(); -//! let cipher = AsconAead128::new(&key); -//! -//! let nonce = AsconAead128Nonce::generate(); // MUST be unique per message -//! let mut buffer: ArrayVec = ArrayVec::new(); // Buffer needs 16-bytes overhead for authentication tag -//! buffer.try_extend_from_slice(b"plaintext message").unwrap(); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer).expect("encryption failure!"); -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer).expect("decryption failure!"); -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) -//! # } -//! ``` #[cfg(feature = "zeroize")] pub use zeroize; pub use aead::{self, Error, Key, Nonce, Tag}; -use aead::{AeadCore, AeadInOut, KeyInit, KeySizeUser, TagPosition, consts::U16, inout::InOutBuf}; +use aead::{ + AeadCore, AeadTagPosition, KeyInit, KeySizeUser, TagPosition, consts::U16, inout::InOutBuf, +}; mod asconcore; @@ -118,10 +69,7 @@ impl KeyInit for Ascon

{ impl AeadCore for Ascon

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

{ fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -158,6 +106,10 @@ impl AeadInOut for Ascon

{ } } +impl AeadTagPosition for Ascon

{ + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + /// Ascon-AEAD128 pub struct AsconAead128(Ascon); /// Key for Ascon-AEAD128 @@ -180,10 +132,7 @@ impl KeyInit for AsconAead128 { impl AeadCore for AsconAead128 { type NonceSize = U16; type TagSize = U16; - const TAG_POSITION: TagPosition = TagPosition::Postfix; -} -impl AeadInOut for AsconAead128 { #[inline(always)] fn encrypt_inout_detached( &self, @@ -207,3 +156,7 @@ impl AeadInOut for AsconAead128 { .decrypt_inout_detached(nonce, associated_data, buffer, tag) } } + +impl AeadTagPosition for AsconAead128 { + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} diff --git a/belt-dwp/Cargo.toml b/belt-dwp/Cargo.toml index aac33d13..c1ec05c5 100644 --- a/belt-dwp/Cargo.toml +++ b/belt-dwp/Cargo.toml @@ -25,9 +25,7 @@ hex-literal = "1" [features] default = ["alloc", "getrandom"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] reduced-round = [] zeroize = ["dep:zeroize", "belt-ctr/zeroize"] diff --git a/belt-dwp/benches/mod.rs b/belt-dwp/benches/mod.rs index 745b2eec..673e106e 100644 --- a/belt-dwp/benches/mod.rs +++ b/belt-dwp/benches/mod.rs @@ -2,7 +2,7 @@ extern crate test; use aead::{ - AeadInOut, KeyInit, + AeadCore, KeyInit, array::Array, consts::{U16, U32}, }; diff --git a/belt-dwp/src/lib.rs b/belt-dwp/src/lib.rs index da94cf70..59d689ff 100644 --- a/belt-dwp/src/lib.rs +++ b/belt-dwp/src/lib.rs @@ -27,54 +27,8 @@ //! assert_eq!(&plaintext, b"plaintext message"); //! # Ok(()) } //! ``` -//! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! use belt_dwp::{ -//! aead::{AeadInOut, Generate, Key, KeyInit, arrayvec::ArrayVec}, -//! BeltDwp, Nonce -//! }; -//! -//! let key = Key::::generate(); -//! let cipher = BeltDwp::new(&key); -//! let nonce = Nonce::generate(); // 128-bits; MUST be unique per message -//! -//! let mut buffer: ArrayVec = ArrayVec::new(); // Note: buffer needs 16-bytes overhead for auth tag -//! buffer.try_extend_from_slice(b"plaintext message").unwrap(); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer)?; -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer)?; -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) } -//! ``` -pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, Tag}; +pub use aead::{self, AeadCore, AeadTagPosition, Error, Key, KeyInit, KeySizeUser, Tag}; pub use belt_block::BeltBlock; use aead::array::ArraySize; @@ -137,11 +91,14 @@ where } } -impl AeadInOut for Dwp +impl AeadCore for Dwp where C: BlockCipherEncrypt + BlockSizeUser, TagSize: ArraySize + NonZero + IsLessOrEqual, { + type NonceSize = C::BlockSize; + type TagSize = TagSize; + fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -242,13 +199,11 @@ where } } -impl AeadCore for Dwp +impl AeadTagPosition for Dwp where C: BlockCipherEncrypt + BlockSizeUser, TagSize: ArraySize + NonZero + IsLessOrEqual, { - type NonceSize = C::BlockSize; - type TagSize = TagSize; const TAG_POSITION: TagPosition = TagPosition::Postfix; } diff --git a/belt-dwp/tests/belt.rs b/belt-dwp/tests/belt.rs index 84c03c71..00d50958 100644 --- a/belt-dwp/tests/belt.rs +++ b/belt-dwp/tests/belt.rs @@ -1,4 +1,4 @@ -use aead::AeadInOut; +use aead::AeadCore; use belt_dwp::{BeltDwp, KeyInit}; use hex_literal::hex; diff --git a/ccm/Cargo.toml b/ccm/Cargo.toml index c39c902c..762bffec 100644 --- a/ccm/Cargo.toml +++ b/ccm/Cargo.toml @@ -27,7 +27,5 @@ hex-literal = "1" [features] default = ["alloc", "getrandom"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] diff --git a/ccm/src/lib.rs b/ccm/src/lib.rs index 550f86dd..acb2d910 100644 --- a/ccm/src/lib.rs +++ b/ccm/src/lib.rs @@ -37,61 +37,8 @@ //! # Ok(()) //! # } //! ``` -//! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]), and enabling the `bytes` feature of this crate will -//! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the -//! [`aead`] crate as [`aead::bytes::BytesMut`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! use aes::Aes256; -//! use ccm::{ -//! aead::{AeadCore, AeadInOut, Generate, Key, KeyInit, Nonce, arrayvec::ArrayVec}, -//! consts::{U10, U13}, -//! Ccm, -//! }; -//! -//! // AES-256-CCM type with tag and nonce size equal to 10 and 13 bytes respectively -//! pub type Aes256Ccm = Ccm; -//! -//! let key = Key::::generate(); -//! let cipher = Aes256Ccm::new(&key); -//! -//! let nonce = Nonce::::generate(); // MUST be unique per message -//! let mut buffer: ArrayVec = ArrayVec::new(); // Note: buffer needs 16-bytes overhead for auth tag -//! buffer.try_extend_from_slice(b"plaintext message").unwrap(); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer)?; -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer)?; -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) -//! # } -pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, consts}; +pub use aead::{self, AeadCore, AeadTagPosition, Error, Key, KeyInit, KeySizeUser, consts}; use aead::{ TagPosition, @@ -261,15 +208,7 @@ where { type NonceSize = N; type TagSize = M; - const TAG_POSITION: TagPosition = TagPosition::Postfix; -} -impl AeadInOut for Ccm -where - C: BlockSizeUser + BlockCipherEncrypt, - M: ArraySize + TagSize, - N: ArraySize + NonceSize, -{ fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -335,6 +274,15 @@ where } } +impl AeadTagPosition for Ccm +where + C: BlockSizeUser + BlockCipherEncrypt, + M: ArraySize + TagSize, + N: ArraySize + NonceSize, +{ + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + struct CbcMac<'a, C: BlockCipherEncrypt> { cipher: &'a C, state: Block, diff --git a/ccm/tests/mod.rs b/ccm/tests/mod.rs index 3288f8b8..12a584e7 100644 --- a/ccm/tests/mod.rs +++ b/ccm/tests/mod.rs @@ -1,6 +1,6 @@ #![cfg(feature = "alloc")] -use aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; +use aead::{Aead, AeadCore, KeyInit, Payload, array::Array}; use aes::{Aes128, Aes192, Aes256}; use ccm::{ Ccm, diff --git a/chacha20poly1305/Cargo.toml b/chacha20poly1305/Cargo.toml index 56e529fe..9e6798ae 100644 --- a/chacha20poly1305/Cargo.toml +++ b/chacha20poly1305/Cargo.toml @@ -32,9 +32,7 @@ aead = { version = "0.6.0-rc.10", features = ["dev"], default-features = false } [features] default = ["alloc", "getrandom"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] reduced-round = [] zeroize = ["dep:zeroize", "chacha20/zeroize"] diff --git a/chacha20poly1305/src/lib.rs b/chacha20poly1305/src/lib.rs index aa565216..6974216c 100644 --- a/chacha20poly1305/src/lib.rs +++ b/chacha20poly1305/src/lib.rs @@ -45,57 +45,6 @@ //! # } //! ``` //! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]), and enabling the `bytes` feature of this crate will -//! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the -//! [`aead`] crate as [`aead::bytes::BytesMut`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! // NOTE: requires the `arrayvec` and `getrandom` features are enabled -//! -//! use chacha20poly1305::{ -//! aead::{AeadCore, AeadInOut, Generate, Key, KeyInit, arrayvec::ArrayVec}, -//! ChaCha20Poly1305, Nonce, -//! }; -//! -//! let key = Key::::generate(); -//! let cipher = ChaCha20Poly1305::new(&key); -//! -//! let nonce = Nonce::generate(); // MUST be unique per message -//! let mut buffer: ArrayVec = ArrayVec::new(); // Note: buffer needs 16-bytes overhead for auth tag -//! buffer.try_extend_from_slice(b"plaintext message").unwrap(); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer)?; -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer)?; -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) -//! # } -//! ``` -//! //! ## [`XChaCha20Poly1305`] //! //! ChaCha20Poly1305 variant with an extended 192-bit (24-byte) nonce. @@ -147,7 +96,7 @@ mod cipher; -pub use aead::{self, AeadCore, AeadInOut, Error, KeyInit, KeySizeUser, consts}; +pub use aead::{self, AeadCore, AeadTagPosition, Error, KeyInit, KeySizeUser, consts}; use self::cipher::Cipher; use ::cipher::{KeyIvInit, StreamCipher, StreamCipherSeek}; @@ -250,18 +199,12 @@ where impl AeadCore for ChaChaPoly1305 where + C: KeyIvInit + StreamCipher + StreamCipherSeek, N: ArraySize, { type NonceSize = N; type TagSize = U16; - const TAG_POSITION: TagPosition = TagPosition::Postfix; -} -impl AeadInOut for ChaChaPoly1305 -where - C: KeyIvInit + StreamCipher + StreamCipherSeek, - N: ArraySize, -{ fn encrypt_inout_detached( &self, nonce: &aead::Nonce, @@ -282,6 +225,14 @@ where } } +impl AeadTagPosition for ChaChaPoly1305 +where + C: KeyIvInit + StreamCipher + StreamCipherSeek, + N: ArraySize, +{ + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + impl Clone for ChaChaPoly1305 where N: ArraySize, diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index 38d81a0a..c765b10d 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -30,9 +30,7 @@ hex-literal = "1" [features] default = ["alloc", "getrandom"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] [package.metadata.docs.rs] diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 7f01484b..05a7402b 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -67,59 +67,6 @@ //! # Ok(()) //! # } //! ``` -//! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]), and enabling the `bytes` feature of this crate will -//! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the -//! [`aead`] crate as [`aead::bytes::BytesMut`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! // NOTE: requires the `arrayvec` and `getrandom` features are enabled -//! -//! use deoxys::{ -//! aead::{AeadCore, AeadInOut, Generate, Key, KeyInit, arrayvec::ArrayVec}, -//! DeoxysII256, // Can be `DeoxysI128`, `DeoxysI256`, `DeoxysII128` of `DeoxysII256` -//! Nonce -//! }; -//! -//! let key = Key::::generate(); -//! let cipher = DeoxysII256::new(&key); -//! -//! let nonce = Nonce::generate(); // MUST be unique per message -//! -//! let mut buffer: ArrayVec = ArrayVec::new(); // Buffer needs 16-bytes overhead for tag -//! buffer.try_extend_from_slice(b"plaintext message").unwrap(); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer)?; -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer)?; -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) -//! # } -//! ``` /// Deoxys-BC implementations. mod deoxys_bc; @@ -127,7 +74,7 @@ mod deoxys_bc; /// Operation modes for Deoxys. mod modes; -pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, consts}; +pub use aead::{self, AeadCore, AeadTagPosition, Error, Key, KeyInit, KeySizeUser, consts}; use aead::{ TagPosition, @@ -279,14 +226,6 @@ where { type NonceSize = M::NonceSize; type TagSize = U16; - const TAG_POSITION: TagPosition = TagPosition::Postfix; -} - -impl AeadInOut for Deoxys -where - M: DeoxysMode, - B: DeoxysBcType, -{ fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -312,6 +251,14 @@ where } } +impl AeadTagPosition for Deoxys +where + M: DeoxysMode, + B: DeoxysBcType, +{ + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + impl Drop for Deoxys where M: DeoxysMode, diff --git a/eax/Cargo.toml b/eax/Cargo.toml index d2542bc1..dc85bb86 100644 --- a/eax/Cargo.toml +++ b/eax/Cargo.toml @@ -33,9 +33,7 @@ aes = "0.9" [features] default = ["alloc"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] [package.metadata.docs.rs] diff --git a/eax/src/lib.rs b/eax/src/lib.rs index d2e6c7f0..5545c6dc 100644 --- a/eax/src/lib.rs +++ b/eax/src/lib.rs @@ -33,64 +33,6 @@ //! # } //! ``` //! -//! ## In-place Usage (eliminates `alloc` requirement) -//! -//! This crate has an optional `alloc` feature which can be disabled in e.g. -//! microcontroller environments that don't have a heap. -//! -//! 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. -//! -//! Enabling the `arrayvec` feature of this crate will provide an impl of -//! [`aead::Buffer`] for `arrayvec::ArrayVec` (re-exported from the [`aead`] crate as -//! [`aead::arrayvec::ArrayVec`]), and enabling the `bytes` feature of this crate will -//! provide an impl of [`aead::Buffer`] for `bytes::BytesMut` (re-exported from the -//! [`aead`] crate as [`aead::bytes::BytesMut`]). -//! -//! It can then be passed as the `buffer` parameter to the in-place encrypt -//! and decrypt methods: -//! -#![cfg_attr(all(feature = "getrandom", feature = "arrayvec"), doc = "```")] -#![cfg_attr( - not(all(feature = "getrandom", feature = "arrayvec")), - doc = "```ignore" -)] -//! # fn main() -> Result<(), Box> { -//! // NOTE: requires the `arrayvec` and `getrandom` features are enabled -//! -//! use aes::Aes256; -//! use eax::{ -//! aead::{ -//! arrayvec::ArrayVec, -//! AeadCore, AeadInOut, Generate, Key, KeyInit, -//! }, -//! Eax, Nonce -//! }; -//! -//! pub type Aes256Eax = Eax; -//! -//! let key = Key::::generate(); -//! let cipher = Aes256Eax::new(&key); -//! -//! let nonce = Nonce::generate(); // 128-bits; MUST be unique per message -//! -//! let mut buffer: ArrayVec = ArrayVec::new(); -//! buffer.try_extend_from_slice(b"plaintext message").unwrap(); -//! -//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(&nonce, b"", &mut buffer).expect("encryption failure!"); -//! -//! // `buffer` now contains the message ciphertext -//! assert_ne!(buffer.as_ref(), b"plaintext message"); -//! -//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(&nonce, b"", &mut buffer).expect("decryption failure!"); -//! assert_eq!(buffer.as_ref(), b"plaintext message"); -//! # Ok(()) -//! # } -//! ``` -//! //! ## Custom Tag Length //! //! The tag for eax is usually 16 bytes long but it can be shortened if needed. @@ -128,7 +70,7 @@ //! # } //! ``` -pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser}; +pub use aead::{self, AeadCore, AeadTagPosition, Error, Key, KeyInit, KeySizeUser}; pub use cipher; use aead::{TagPosition, inout::InOutBuf}; @@ -210,14 +152,7 @@ where { type NonceSize = Cipher::BlockSize; type TagSize = M; - const TAG_POSITION: TagPosition = TagPosition::Postfix; -} -impl AeadInOut for Eax -where - Cipher: BlockSizeUser + BlockCipherEncrypt + Clone + KeyInit, - M: TagSize, -{ fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -289,6 +224,14 @@ where } } +impl AeadTagPosition for Eax +where + Cipher: BlockSizeUser + BlockCipherEncrypt + Clone + KeyInit, + M: TagSize, +{ + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + impl Eax where Cipher: BlockSizeUser + BlockCipherEncrypt + Clone + KeyInit, diff --git a/mgm/Cargo.toml b/mgm/Cargo.toml index 8084ca06..2d8b3329 100644 --- a/mgm/Cargo.toml +++ b/mgm/Cargo.toml @@ -34,8 +34,6 @@ hex-literal = "1" default = ["alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] stream = ["aead/stream"] diff --git a/ocb3/Cargo.toml b/ocb3/Cargo.toml index e8e749e7..53eb7750 100644 --- a/ocb3/Cargo.toml +++ b/ocb3/Cargo.toml @@ -21,7 +21,6 @@ cipher = "0.5" ctr = "0.10" dbl = "0.5" subtle = { version = "2", default-features = false } -aead-stream = { version = "0.6.0-rc.3", optional = true, default-features = false } zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] @@ -31,10 +30,8 @@ hex-literal = "1" [features] default = ["alloc", "getrandom"] -alloc = ["aead/alloc", "aead-stream?/alloc"] -arrayvec = ["aead/arrayvec"] -bytes = ["aead/bytes"] -getrandom = ["aead/getrandom"] +alloc = ["aead/alloc"] +getrandom = ["aead/getrandom", "rand_core"] rand_core = ["aead/rand_core"] [package.metadata.docs.rs] diff --git a/ocb3/src/lib.rs b/ocb3/src/lib.rs index b17338db..cf62365b 100644 --- a/ocb3/src/lib.rs +++ b/ocb3/src/lib.rs @@ -14,12 +14,12 @@ pub mod consts { } pub use aead::{ - self, AeadCore, AeadInOut, Error, KeyInit, KeySizeUser, + self, AeadCore, Error, KeyInit, KeySizeUser, array::{Array, AsArrayRef, AssocArraySize}, }; use aead::{ - TagPosition, + AeadTagPosition, TagPosition, array::ArraySize, inout::{InOut, InOutBuf}, }; @@ -157,17 +157,6 @@ where } } -impl AeadCore - for Ocb3 -where - NonceSize: sealed::NonceSizes, - TagSize: sealed::TagSizes, -{ - type NonceSize = NonceSize; - type TagSize = TagSize; - const TAG_POSITION: TagPosition = TagPosition::Postfix; -} - impl From for Ocb3 where @@ -189,13 +178,17 @@ where } } -impl AeadInOut +impl AeadCore for Ocb3 where Cipher: BlockSizeUser + BlockCipherEncrypt + BlockCipherDecrypt, NonceSize: sealed::NonceSizes, TagSize: sealed::TagSizes, { + type NonceSize = NonceSize; + type TagSize = TagSize; + + #[allow(clippy::explicit_counter_loop)] fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -271,6 +264,16 @@ where } } +impl AeadTagPosition + for Ocb3 +where + Cipher: BlockSizeUser + BlockCipherEncrypt + BlockCipherDecrypt, + NonceSize: sealed::NonceSizes, + TagSize: sealed::TagSizes, +{ + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + impl Ocb3 where @@ -279,6 +282,7 @@ where TagSize: sealed::TagSizes, { /// Decrypts in place and returns expected tag. + #[allow(clippy::explicit_counter_loop)] pub(crate) fn decrypt_inout_return_tag( &self, nonce: &Nonce, diff --git a/ocb3/tests/kats.rs b/ocb3/tests/kats.rs index 1b4355d2..7737d625 100644 --- a/ocb3/tests/kats.rs +++ b/ocb3/tests/kats.rs @@ -1,7 +1,7 @@ #![allow(non_snake_case)] use aead::{ - AeadInOut, KeyInit, + AeadCore, KeyInit, consts::{U8, U12}, }; use aes::{Aes128, Aes192, Aes256}; diff --git a/ocb3/tests/len_check.rs b/ocb3/tests/len_check.rs index a1bb20da..62b517ab 100644 --- a/ocb3/tests/len_check.rs +++ b/ocb3/tests/len_check.rs @@ -1,5 +1,5 @@ use aead::{ - AeadInOut, KeyInit, + AeadCore, KeyInit, consts::{U12, U16}, }; use aes::Aes128; diff --git a/xaes-256-gcm/Cargo.toml b/xaes-256-gcm/Cargo.toml index 8fe9155b..b9235447 100644 --- a/xaes-256-gcm/Cargo.toml +++ b/xaes-256-gcm/Cargo.toml @@ -20,7 +20,6 @@ aead = { version = "0.6.0-rc.10", default-features = false } aes = "0.9" aes-gcm = { version = "0.11.0-rc.3", default-features = false, features = ["aes"] } cipher = "0.5" -aead-stream = { version = "0.6.0-rc.2", optional = true, default-features = false } [dev-dependencies] aead = { version = "0.6.0-rc.10", features = ["dev"], default-features = false } @@ -28,9 +27,8 @@ hex-literal = "1" [features] default = ["alloc", "getrandom"] -alloc = ["aead/alloc", "aead-stream?/alloc", "aes-gcm/alloc"] -arrayvec = ["aead/arrayvec", "aes-gcm/arrayvec"] -getrandom = ["aes-gcm/getrandom"] +alloc = ["aead/alloc", "aes-gcm/alloc"] +getrandom = ["aes-gcm/getrandom", "rand_core"] rand_core = ["aead/rand_core", "aes-gcm/rand_core"] [package.metadata.docs.rs] diff --git a/xaes-256-gcm/src/lib.rs b/xaes-256-gcm/src/lib.rs index ecd1e7f2..11231652 100644 --- a/xaes-256-gcm/src/lib.rs +++ b/xaes-256-gcm/src/lib.rs @@ -39,7 +39,8 @@ pub use aes_gcm; use core::ops::{Div, Mul}; use aead::{ - AeadCore, AeadInOut, Error, KeyInit, KeySizeUser, TagPosition, array::Array, inout::InOutBuf, + AeadCore, AeadTagPosition, Error, KeyInit, KeySizeUser, TagPosition, array::Array, + inout::InOutBuf, }; use aes::Aes256; use aes_gcm::Aes256Gcm; @@ -76,12 +77,6 @@ pub const A_MAX: u64 = 1 << 36; /// Maximum length of ciphertext. 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 { type KeySize = KeySize; } @@ -110,7 +105,10 @@ impl KeyInit for Xaes256Gcm { } } -impl AeadInOut for Xaes256Gcm { +impl AeadCore for Xaes256Gcm { + type NonceSize = NonceSize; + type TagSize = TagSize; + fn encrypt_inout_detached( &self, nonce: &Nonce, @@ -143,6 +141,10 @@ impl AeadInOut for Xaes256Gcm { } } +impl AeadTagPosition for Xaes256Gcm { + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + impl Xaes256Gcm { // Implements steps 3 - 5 of the spec. fn derive_key(&self, n1: &Nonce<>::Output>) -> Key { diff --git a/xaes-256-gcm/tests/xaes256gcm.rs b/xaes-256-gcm/tests/xaes256gcm.rs index 62b85d7e..eda8a24c 100644 --- a/xaes-256-gcm/tests/xaes256gcm.rs +++ b/xaes-256-gcm/tests/xaes256gcm.rs @@ -1,11 +1,6 @@ //! XAES-256-GCM test vectors -#[macro_use] -#[path = "../../aes-gcm/tests/common/mod.rs"] -mod common; - -use aes_gcm::aead::{Aead, AeadInOut, KeyInit, Payload, array::Array}; -use common::TestVector; +use aes_gcm::aead::{Aead, AeadCore, KeyInit, Payload, array::Array}; use hex_literal::hex; use xaes_256_gcm::Xaes256Gcm; @@ -31,4 +26,105 @@ const TEST_VECTORS: &[TestVector<[u8; 32], [u8; 24]>] = &[ }, ]; +/// Test vectors +#[derive(Debug)] +pub struct TestVector { + pub key: &'static K, + pub nonce: &'static N, + pub aad: &'static [u8], + pub plaintext: &'static [u8], + pub ciphertext: &'static [u8], + pub tag: &'static [u8; 16], +} + +#[macro_export] +macro_rules! tests { + ($aead:ty, $vectors:expr) => { + #[test] + fn encrypt() { + for vector in $vectors { + let key = Array(*vector.key); + let nonce = Array(*vector.nonce); + let payload = Payload { + msg: vector.plaintext, + aad: vector.aad, + }; + + let cipher = <$aead>::new(&key); + let ciphertext = cipher.encrypt(&nonce, payload).unwrap(); + let (ct, tag) = ciphertext.split_at(ciphertext.len() - 16); + assert_eq!( + vector.ciphertext, ct, + "ciphertext mismatch (expected != actual)" + ); + assert_eq!(vector.tag, tag, "tag mismatch (expected != actual)"); + } + } + + #[test] + fn decrypt() { + for vector in $vectors { + let key = Array(*vector.key); + let nonce = Array(*vector.nonce); + let mut ciphertext = Vec::from(vector.ciphertext); + ciphertext.extend_from_slice(vector.tag); + + let payload = Payload { + msg: &ciphertext, + aad: vector.aad, + }; + + let cipher = <$aead>::new(&key); + let plaintext = cipher.decrypt(&nonce, payload).unwrap(); + + assert_eq!(vector.plaintext, plaintext.as_slice(), "plaintext mismatch"); + } + } + + #[test] + fn decrypt_modified() { + let vector = &$vectors[0]; + let key = Array(*vector.key); + let nonce = Array(*vector.nonce); + + let mut ciphertext = Vec::from(vector.ciphertext); + ciphertext.extend_from_slice(vector.tag); + + // Tweak the first byte + ciphertext[0] ^= 0xaa; + + let payload = Payload { + msg: &ciphertext, + aad: vector.aad, + }; + + let cipher = <$aead>::new(&key); + assert!(cipher.decrypt(&nonce, payload).is_err()); + } + + #[test] + fn decrypt_in_place_detached_modified() { + let vector = &$vectors.iter().last().unwrap(); + let key = Array(*vector.key); + let nonce = Array(*vector.nonce); + + let mut buffer = Vec::from(vector.ciphertext); + assert!(!buffer.is_empty()); + + // Tweak the first byte + let mut tag = Array(*vector.tag); + tag[0] ^= 0xaa; + + let cipher = <$aead>::new(&key); + assert!( + cipher + .decrypt_inout_detached(&nonce, &[], buffer.as_mut_slice().into(), &tag) + .is_err() + ); + + assert_eq!(vector.ciphertext, buffer); + } + }; +} + tests!(Xaes256Gcm, TEST_VECTORS);