diff --git a/Cargo.lock b/Cargo.lock index eb049d4..0132974 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,8 +5,7 @@ version = 3 [[package]] name = "aes" version = "0.9.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183b3b4639f8f7237857117abb74f3dc8648b77e67ff78d9cb6959fd7e76f387" +source = "git+https://github.com/RustCrypto/block-ciphers?branch=cipher_new#d27085f764b9d961fd03ff25f166cfb6255fccd5" dependencies = [ "cfg-if", "cipher", @@ -16,8 +15,7 @@ dependencies = [ [[package]] name = "belt-block" version = "0.2.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3342994f00336827ff9ae0e20e21d38eb88aa4e40aa1795a2a4d14d7af264a5b" +source = "git+https://github.com/RustCrypto/block-ciphers?branch=cipher_new#d27085f764b9d961fd03ff25f166cfb6255fccd5" dependencies = [ "cipher", ] @@ -82,9 +80,8 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.5.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71c893d5a1e8257048dbb29954d2e1f85f091a150304f1defe4ca2806da5d3f" +version = "0.5.0-pre.7" +source = "git+https://github.com/RustCrypto/traits?branch=block_backends#19e6b3f01614cbb5232e99dbf60883f846e31626" dependencies = [ "blobby", "crypto-common", @@ -103,9 +100,8 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b" +version = "0.2.0-rc.1" +source = "git+https://github.com/RustCrypto/traits?branch=block_backends#19e6b3f01614cbb5232e99dbf60883f846e31626" dependencies = [ "getrandom", "hybrid-array", @@ -171,9 +167,9 @@ dependencies = [ [[package]] name = "kuznyechik" version = "0.9.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7984e78a88c94f87c94a1a17f8fb3bff3f466c2b8bddf341ae9616d7519c888" +source = "git+https://github.com/RustCrypto/block-ciphers?branch=cipher_new#d27085f764b9d961fd03ff25f166cfb6255fccd5" dependencies = [ + "cfg-if", "cipher", ] @@ -186,8 +182,7 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "magma" version = "0.10.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef645dc7cf374c71e44deb3f045f59873da9bbfaab4e062fcfd3529ee9e52318" +source = "git+https://github.com/RustCrypto/block-ciphers?branch=cipher_new#d27085f764b9d961fd03ff25f166cfb6255fccd5" dependencies = [ "cipher", ] diff --git a/Cargo.toml b/Cargo.toml index 947bb0f..2856fca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,14 @@ [workspace] resolver = "2" -members = [ - "belt-ctr", - "cbc", - "cfb8", - "cfb-mode", - "ctr", - "ige", - "ofb", - "pcbc", -] +members = ["belt-ctr", "cbc", "cfb8", "cfb-mode", "ctr", "ige", "ofb", "pcbc"] + +[profile.dev] +opt-level = 2 + +[patch.crates-io] +cipher = { git = "https://github.com/RustCrypto/traits", branch = "block_backends" } + +aes = { git = "https://github.com/RustCrypto/block-ciphers", branch = "cipher_new" } +belt-block = { git = "https://github.com/RustCrypto/block-ciphers", branch = "cipher_new" } +kuznyechik = { git = "https://github.com/RustCrypto/block-ciphers", branch = "cipher_new" } +magma = { git = "https://github.com/RustCrypto/block-ciphers", branch = "cipher_new" } diff --git a/belt-ctr/Cargo.toml b/belt-ctr/Cargo.toml index c3e9dcf..9345dd6 100644 --- a/belt-ctr/Cargo.toml +++ b/belt-ctr/Cargo.toml @@ -13,13 +13,13 @@ keywords = ["crypto", "block-mode", "stream-cipher", "ciphers", "belt"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "=0.5.0-pre.7" belt-block = "=0.2.0-pre.1" [dev-dependencies] hex-literal = "0.4" belt-block = "=0.2.0-pre.1" -cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +cipher = { version = "=0.5.0-pre.7", features = ["dev"] } [features] alloc = ["cipher/alloc"] diff --git a/belt-ctr/src/backend.rs b/belt-ctr/src/backend.rs deleted file mode 100644 index f965d49..0000000 --- a/belt-ctr/src/backend.rs +++ /dev/null @@ -1,76 +0,0 @@ -use cipher::{ - consts::U16, Block, BlockBackend, BlockClosure, BlockSizeUser, ParBlocks, ParBlocksSizeUser, - StreamBackend, StreamClosure, -}; - -struct Backend<'a, B> -where - B: BlockBackend, -{ - s: &'a mut u128, - backend: &'a mut B, -} - -impl<'a, B> BlockSizeUser for Backend<'a, B> -where - B: BlockBackend, -{ - type BlockSize = B::BlockSize; -} - -impl<'a, B> ParBlocksSizeUser for Backend<'a, B> -where - B: BlockBackend, -{ - type ParBlocksSize = B::ParBlocksSize; -} - -impl<'a, B> StreamBackend for Backend<'a, B> -where - B: BlockBackend, -{ - #[inline(always)] - fn gen_ks_block(&mut self, block: &mut Block) { - *self.s = self.s.wrapping_add(1); - let tmp = self.s.to_le_bytes().into(); - self.backend.proc_block((&tmp, block).into()); - } - - #[inline(always)] - fn gen_par_ks_blocks(&mut self, blocks: &mut ParBlocks) { - let mut tmp = ParBlocks::::default(); - let mut s = *self.s; - for block in tmp.iter_mut() { - s = s.wrapping_add(1); - *block = s.to_le_bytes().into(); - } - *self.s = s; - self.backend.proc_par_blocks((&tmp, blocks).into()); - } -} - -pub(crate) struct Closure<'a, SC> -where - SC: StreamClosure, -{ - pub(crate) s: &'a mut u128, - pub(crate) f: SC, -} - -impl<'a, SC> BlockSizeUser for Closure<'a, SC> -where - SC: StreamClosure, -{ - type BlockSize = U16; -} - -impl<'a, SC> BlockClosure for Closure<'a, SC> -where - SC: StreamClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { s, f } = self; - f.call(&mut Backend:: { s, backend }) - } -} diff --git a/belt-ctr/src/lib.rs b/belt-ctr/src/lib.rs index 869e6d6..c6c9da5 100644 --- a/belt-ctr/src/lib.rs +++ b/belt-ctr/src/lib.rs @@ -12,14 +12,13 @@ pub use cipher; use belt_block::BeltBlock; use cipher::{ - array::Array, consts::U16, crypto_common::InnerUser, AlgorithmName, BlockCipherDecrypt, - BlockCipherEncrypt, BlockSizeUser, InnerIvInit, Iv, IvSizeUser, IvState, StreamCipherCore, - StreamCipherCoreWrapper, StreamCipherSeekCore, StreamClosure, + array::Array, consts::U16, crypto_common::InnerUser, AlgorithmName, Block, BlockCipherDecrypt, + BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, InOut, + InnerIvInit, Iv, IvSizeUser, IvState, ParBlocks, ParBlocksSizeUser, StreamBackend, + StreamCipherCore, StreamCipherCoreWrapper, StreamCipherSeekCore, StreamClosure, }; use core::fmt; -mod backend; - /// Byte-level BelT CTR pub type BeltCtr = StreamCipherCoreWrapper>; @@ -43,8 +42,25 @@ where } fn process_with_backend(&mut self, f: impl StreamClosure) { + struct Closure<'a, C: StreamClosure> { + s: &'a mut u128, + f: C, + } + + impl<'a, C: StreamClosure> BlockSizeUser for Closure<'a, C> { + type BlockSize = U16; + } + + impl<'a, C: StreamClosure> BlockCipherEncClosure for Closure<'a, C> { + #[inline(always)] + fn call>(self, cipher_backend: &B) { + let Self { s, f } = self; + f.call(&mut Backend { s, cipher_backend }) + } + } + let Self { cipher, s, .. } = self; - cipher.encrypt_with_backend(backend::Closure { s, f }); + cipher.encrypt_with_backend(Closure { s, f }); } } @@ -129,3 +145,38 @@ impl> fmt::Debug for Belt f.write_str("BeltCtrCore { ... }") } } + +struct Backend<'a, B: BlockCipherEncBackend> { + s: &'a mut u128, + cipher_backend: &'a B, +} + +impl<'a, B: BlockCipherEncBackend> BlockSizeUser for Backend<'a, B> { + type BlockSize = B::BlockSize; +} + +impl<'a, B: BlockCipherEncBackend> ParBlocksSizeUser for Backend<'a, B> { + type ParBlocksSize = B::ParBlocksSize; +} + +impl<'a, B: BlockCipherEncBackend> StreamBackend for Backend<'a, B> { + #[inline(always)] + fn gen_ks_block(&mut self, block: &mut Block) { + *self.s = self.s.wrapping_add(1); + let tmp = self.s.to_le_bytes().into(); + self.cipher_backend.encrypt_block((&tmp, block).into()); + } + + #[inline(always)] + fn gen_par_ks_blocks(&mut self, blocks: &mut ParBlocks) { + let mut tmp = ParBlocks::::default(); + let mut s = *self.s; + for block in tmp.iter_mut() { + s = s.wrapping_add(1); + *block = s.to_le_bytes().into(); + } + *self.s = s; + let io_blocks = InOut::from((&tmp, blocks)); + self.cipher_backend.encrypt_par_blocks(io_blocks); + } +} diff --git a/cbc/Cargo.toml b/cbc/Cargo.toml index f15b821..e816dce 100644 --- a/cbc/Cargo.toml +++ b/cbc/Cargo.toml @@ -13,11 +13,11 @@ keywords = ["crypto", "block-mode", "ciphers"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "=0.5.0-pre.7" [dev-dependencies] aes = "=0.9.0-pre.1" -cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +cipher = { version = "=0.5.0-pre.7", features = ["dev"] } hex-literal = "0.4" [features] diff --git a/cbc/src/decrypt.rs b/cbc/src/decrypt.rs index 77fd40b..b35e8cc 100644 --- a/cbc/src/decrypt.rs +++ b/cbc/src/decrypt.rs @@ -3,8 +3,9 @@ use cipher::{ array::Array, crypto_common::{BlockSizes, InnerUser, IvSizeUser}, inout::InOut, - AlgorithmName, Block, BlockBackend, BlockCipher, BlockCipherDecrypt, BlockClosure, - BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocks, ParBlocksSizeUser, + AlgorithmName, Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, + BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv, + IvState, ParBlocks, ParBlocksSizeUser, }; use core::fmt; @@ -15,7 +16,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { cipher: C, iv: Block, @@ -23,38 +24,38 @@ where impl BlockSizeUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { type BlockSize = C::BlockSize; } impl BlockModeDecrypt for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { - fn decrypt_with_backend(&mut self, f: impl BlockClosure) { + fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure) { let Self { cipher, iv } = self; - cipher.decrypt_with_backend(Closure { iv, f }) + cipher.decrypt_with_backend(ClosurePassedToCipher { iv, f }) } } impl InnerUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { type Inner = C; } impl IvSizeUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { type IvSize = C::BlockSize; } impl InnerIvInit for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { @@ -67,7 +68,7 @@ where impl IvState for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -77,7 +78,7 @@ where impl AlgorithmName for Decryptor where - C: BlockCipherDecrypt + BlockCipher + AlgorithmName, + C: BlockCipherDecrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cbc::Decryptor<")?; @@ -88,7 +89,7 @@ where impl fmt::Debug for Decryptor where - C: BlockCipherDecrypt + BlockCipher + AlgorithmName, + C: BlockCipherDecrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cbc::Decryptor<")?; @@ -97,60 +98,58 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for Decryptor { +impl Drop for Decryptor { fn drop(&mut self) { + #[cfg(feature = "zeroize")] self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for Decryptor {} +impl ZeroizeOnDrop for Decryptor {} -struct Closure<'a, BS, BC> +struct ClosurePassedToCipher<'a, BS, BC> where BS: BlockSizes, - BC: BlockClosure, + BC: BlockModeDecClosure, { iv: &'a mut Array, f: BC, } -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> +impl<'a, BS, BC> BlockSizeUser for ClosurePassedToCipher<'a, BS, BC> where BS: BlockSizes, - BC: BlockClosure, + BC: BlockModeDecClosure, { type BlockSize = BS; } -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> +impl<'a, BS, BC> BlockCipherDecClosure for ClosurePassedToCipher<'a, BS, BC> where BS: BlockSizes, - BC: BlockClosure, + BC: BlockModeDecClosure, { #[inline(always)] - fn call>(self, backend: &mut B) { + fn call>(self, cipher_backend: &B) { let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); + f.call(&mut Backend { iv, cipher_backend }); } } struct Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { iv: &'a mut Array, - backend: &'a mut BK, + cipher_backend: &'a BK, } impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { type BlockSize = BS; } @@ -158,32 +157,32 @@ where impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { type ParBlocksSize = BK::ParBlocksSize; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeDecBackend for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn decrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { let in_block = block.clone_in(); let mut t = block.clone_in(); - self.backend.proc_block((&mut t).into()); + self.cipher_backend.decrypt_block((&mut t).into()); xor(&mut t, self.iv); *block.get_out() = t; *self.iv = in_block; } #[inline(always)] - fn proc_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { + fn decrypt_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { let in_blocks = blocks.clone_in(); let mut t = blocks.clone_in(); - self.backend.proc_par_blocks((&mut t).into()); + self.cipher_backend.decrypt_par_blocks((&mut t).into()); let n = t.len(); xor(&mut t[0], self.iv); for i in 1..n { diff --git a/cbc/src/encrypt.rs b/cbc/src/encrypt.rs index 2c42629..edecabb 100644 --- a/cbc/src/encrypt.rs +++ b/cbc/src/encrypt.rs @@ -1,11 +1,8 @@ use crate::xor; use cipher::{ - array::Array, - consts::U1, - crypto_common::{BlockSizes, InnerUser, IvSizeUser}, - inout::InOut, - AlgorithmName, Block, BlockBackend, BlockCipher, BlockCipherEncrypt, BlockClosure, - BlockModeEncrypt, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, + consts::U1, crypto_common::InnerUser, AlgorithmName, Block, BlockCipherEncrypt, + BlockModeEncBackend, BlockModeEncClosure, BlockModeEncrypt, BlockSizeUser, InOut, InnerIvInit, + Iv, IvSizeUser, IvState, ParBlocksSizeUser, }; use core::fmt; @@ -16,7 +13,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { cipher: C, iv: Block, @@ -24,38 +21,28 @@ where impl BlockSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type BlockSize = C::BlockSize; } -impl BlockModeEncrypt for Encryptor -where - C: BlockCipherEncrypt + BlockCipher, -{ - fn encrypt_with_backend(&mut self, f: impl BlockClosure) { - let Self { cipher, iv } = self; - cipher.encrypt_with_backend(Closure { iv, f }) - } -} - impl InnerUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type Inner = C; } impl IvSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type IvSize = C::BlockSize; } impl InnerIvInit for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { @@ -68,7 +55,7 @@ where impl IvState for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -76,9 +63,39 @@ where } } +impl BlockModeEncrypt for Encryptor +where + C: BlockCipherEncrypt, +{ + fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure) { + f.call(self) + } +} + +impl ParBlocksSizeUser for Encryptor +where + C: BlockCipherEncrypt, +{ + type ParBlocksSize = U1; +} + +impl BlockModeEncBackend for Encryptor +where + C: BlockCipherEncrypt, +{ + #[inline(always)] + fn encrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { + let mut t = block.clone_in(); + xor(&mut t, &self.iv); + self.cipher.encrypt_block(&mut t); + self.iv = t.clone(); + *block.get_out() = t; + } +} + impl AlgorithmName for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cbc::Encryptor<")?; @@ -89,7 +106,7 @@ where impl fmt::Debug for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cbc::Encryptor<")?; @@ -98,83 +115,12 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for Encryptor { +impl Drop for Encryptor { fn drop(&mut self) { + #[cfg(feature = "zeroize")] self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for Encryptor {} - -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - iv: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} - -struct Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - iv: &'a mut Array, - backend: &'a mut BK, -} - -impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - type BlockSize = BS; -} - -impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - type ParBlocksSize = U1; -} - -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { - let mut t = block.clone_in(); - xor(&mut t, self.iv); - self.backend.proc_block((&mut t).into()); - *self.iv = t.clone(); - *block.get_out() = t; - } -} +impl ZeroizeOnDrop for Encryptor {} diff --git a/cbc/src/lib.rs b/cbc/src/lib.rs index 4597ed2..e1e87af 100644 --- a/cbc/src/lib.rs +++ b/cbc/src/lib.rs @@ -94,7 +94,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![forbid(unsafe_code)] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)] mod decrypt; diff --git a/cfb-mode/Cargo.toml b/cfb-mode/Cargo.toml index b202822..94b0c6b 100644 --- a/cfb-mode/Cargo.toml +++ b/cfb-mode/Cargo.toml @@ -13,12 +13,12 @@ keywords = ["crypto", "block-mode", "stream-cipher", "ciphers"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "=0.5.0-pre.7" [dev-dependencies] aes = "=0.9.0-pre.1" belt-block = "=0.2.0-pre.1" -cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +cipher = { version = "=0.5.0-pre.7", features = ["dev"] } hex-literal = "0.4" [features] diff --git a/cfb-mode/src/decrypt.rs b/cfb-mode/src/decrypt.rs index 2af7eeb..d0d4b80 100644 --- a/cfb-mode/src/decrypt.rs +++ b/cfb-mode/src/decrypt.rs @@ -1,10 +1,10 @@ use cipher::{ - array::Array, - crypto_common::{BlockSizes, InnerUser, IvSizeUser}, - inout::InOut, - AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockCipherDecrypt, - BlockCipherEncrypt, BlockClosure, BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv, IvState, - ParBlocks, ParBlocksSizeUser, Unsigned, + crypto_common::{BlockSizes, InnerUser}, + typenum::Unsigned, + AlgorithmName, Array, AsyncStreamCipher, Block, BlockCipherDecrypt, BlockCipherEncBackend, + BlockCipherEncClosure, BlockCipherEncrypt, BlockModeDecBackend, BlockModeDecClosure, + BlockModeDecrypt, BlockSizeUser, InOut, InnerIvInit, Iv, IvSizeUser, IvState, ParBlocks, + ParBlocksSizeUser, }; use core::fmt; @@ -15,7 +15,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { cipher: C, iv: Block, @@ -25,7 +25,7 @@ where #[derive(Clone)] pub struct BufDecryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { cipher: C, iv: Block, @@ -34,11 +34,11 @@ where impl BufDecryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { /// Decrypt a buffer in multiple parts. pub fn decrypt(&mut self, mut data: &mut [u8]) { - let bs = C::BlockSize::to_usize(); + let bs = C::BlockSize::USIZE; let n = data.len(); if n < bs - self.pos { @@ -79,80 +79,146 @@ where } } -impl BlockSizeUser for Decryptor +impl InnerUser for BufDecryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - type BlockSize = C::BlockSize; + type Inner = C; } -impl BlockModeDecrypt for Decryptor +impl IvSizeUser for BufDecryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - fn decrypt_with_backend(&mut self, f: impl BlockClosure) { - let Self { cipher, iv } = self; - cipher.encrypt_with_backend(Closure { iv, f }) + type IvSize = C::BlockSize; +} + +impl InnerIvInit for BufDecryptor +where + C: BlockCipherEncrypt, +{ + #[inline] + fn inner_iv_init(cipher: C, iv: &Iv) -> Self { + let mut iv = iv.clone(); + cipher.encrypt_block(&mut iv); + Self { cipher, iv, pos: 0 } } } -impl AsyncStreamCipher for Decryptor where C: BlockCipherEncrypt + BlockCipher {} +impl AlgorithmName for BufDecryptor +where + C: BlockCipherEncrypt + AlgorithmName, +{ + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("cfb::BufDecryptor<")?; + ::write_alg_name(f)?; + f.write_str(">") + } +} -impl InnerUser for Decryptor +impl fmt::Debug for BufDecryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt + AlgorithmName, { - type Inner = C; + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("cfb::BufDecryptor<")?; + ::write_alg_name(f)?; + f.write_str("> { ... }") + } } -impl InnerUser for BufDecryptor +impl Drop for BufDecryptor { + fn drop(&mut self) { + #[cfg(feature = "zeroize")] + self.iv.zeroize(); + } +} + +#[cfg(feature = "zeroize")] +impl ZeroizeOnDrop for BufDecryptor {} + +impl BlockSizeUser for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - type Inner = C; + type BlockSize = C::BlockSize; } -impl IvSizeUser for Decryptor +impl BlockModeDecrypt for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - type IvSize = C::BlockSize; + fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure) { + /// This closure is used to recieve block cipher backend and + /// create respective [`CbcDecryptBackend`] based on it. + struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + iv: &'a mut Array, + f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherEncClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + #[inline(always)] + fn call>( + self, + cipher_backend: &B, + ) { + let Self { iv, f } = self; + f.call(&mut CbcDecryptBackend { iv, cipher_backend }); + } + } + + let Self { cipher, iv } = self; + cipher.encrypt_with_backend(Closure { iv, f }) + } } -impl IvSizeUser for BufDecryptor +impl AsyncStreamCipher for Decryptor where C: BlockCipherEncrypt {} + +impl InnerUser for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - type IvSize = C::BlockSize; + type Inner = C; } -impl InnerIvInit for Decryptor +impl IvSizeUser for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - #[inline] - fn inner_iv_init(cipher: C, iv: &Iv) -> Self { - let mut iv = iv.clone(); - cipher.encrypt_block(&mut iv); - Self { cipher, iv } - } + type IvSize = C::BlockSize; } -impl InnerIvInit for BufDecryptor +impl InnerIvInit for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { let mut iv = iv.clone(); cipher.encrypt_block(&mut iv); - Self { cipher, iv, pos: 0 } + Self { cipher, iv } } } impl IvState for Decryptor where - C: BlockCipherEncrypt + BlockCipherDecrypt + BlockCipher, + C: BlockCipherEncrypt + BlockCipherDecrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -164,7 +230,7 @@ where impl AlgorithmName for Decryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb::Decryptor<")?; @@ -173,20 +239,9 @@ where } } -impl AlgorithmName for BufDecryptor -where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, -{ - fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("cfb::BufDecryptor<")?; - ::write_alg_name(f)?; - f.write_str(">") - } -} - impl fmt::Debug for Decryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb::Decryptor<")?; @@ -195,113 +250,59 @@ where } } -impl fmt::Debug for BufDecryptor -where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("cfb::BufDecryptor<")?; - ::write_alg_name(f)?; - f.write_str("> { ... }") - } -} - -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for Decryptor { - fn drop(&mut self) { - self.iv.zeroize(); - } -} - -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for BufDecryptor { +impl Drop for Decryptor { fn drop(&mut self) { + #[cfg(feature = "zeroize")] self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for Decryptor {} - -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for BufDecryptor {} - -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - iv: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} +impl ZeroizeOnDrop for Decryptor {} -struct Backend<'a, BS, BK> +struct CbcDecryptBackend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { iv: &'a mut Array, - backend: &'a mut BK, + cipher_backend: &'a BK, } -impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockSizeUser for CbcDecryptBackend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type BlockSize = BS; } -impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> +impl<'a, BS, BK> ParBlocksSizeUser for CbcDecryptBackend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type ParBlocksSize = BK::ParBlocksSize; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeDecBackend for CbcDecryptBackend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn decrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { let mut t = block.clone_in(); block.xor_in2out(self.iv); - self.backend.proc_block((&mut t).into()); + self.cipher_backend.encrypt_block((&mut t).into()); *self.iv = t; } #[inline(always)] - fn proc_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { + fn decrypt_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { let mut t = ParBlocks::::default(); let b = (blocks.get_in(), &mut t).into(); - self.backend.proc_par_blocks(b); + self.cipher_backend.encrypt_par_blocks(b); let n = t.len(); blocks.get(0).xor_in2out(self.iv); diff --git a/cfb-mode/src/encrypt.rs b/cfb-mode/src/encrypt.rs index b974fb0..257f495 100644 --- a/cfb-mode/src/encrypt.rs +++ b/cfb-mode/src/encrypt.rs @@ -1,136 +1,100 @@ use cipher::{ array::Array, consts::U1, - crypto_common::{BlockSizes, InnerUser, IvSizeUser}, - inout::InOut, - AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockCipherDecrypt, - BlockCipherEncrypt, BlockClosure, BlockModeEncrypt, BlockSizeUser, InnerIvInit, Iv, IvState, - ParBlocksSizeUser, Unsigned, + crypto_common::{BlockSizes, InnerUser}, + AlgorithmName, AsyncStreamCipher, Block, BlockCipherDecrypt, BlockCipherEncBackend, + BlockCipherEncClosure, BlockCipherEncrypt, BlockModeEncBackend, BlockModeEncClosure, + BlockModeEncrypt, BlockSizeUser, InOut, InnerIvInit, Iv, IvSizeUser, IvState, + ParBlocksSizeUser, }; use core::fmt; #[cfg(feature = "zeroize")] use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; +mod buf; +pub use buf::BufEncryptor; + /// CFB mode encryptor. #[derive(Clone)] pub struct Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { cipher: C, iv: Block, } -/// CFB mode buffered encryptor. -#[derive(Clone)] -pub struct BufEncryptor +impl BlockSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - cipher: C, - iv: Block, - pos: usize, + type BlockSize = C::BlockSize; } -impl BufEncryptor +impl BlockModeEncrypt for Encryptor where - C: BlockCipherEncrypt + BlockCipher, -{ - /// Encrypt a buffer in multiple parts. - pub fn encrypt(&mut self, mut data: &mut [u8]) { - let bs = C::BlockSize::USIZE; - let n = data.len(); - - if n < bs - self.pos { - xor_set1(data, &mut self.iv[self.pos..self.pos + n]); - self.pos += n; - return; + C: BlockCipherEncrypt, +{ + fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure) { + /// This closure is used to recieve block cipher backend and create + /// respective `Backend` based on it. + struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + iv: &'a mut Array, + f: BC, } - let (left, right) = { data }.split_at_mut(bs - self.pos); - data = right; - let mut iv = self.iv.clone(); - xor_set1(left, &mut iv[self.pos..]); - self.cipher.encrypt_block(&mut iv); - - let mut chunks = data.chunks_exact_mut(bs); - for chunk in &mut chunks { - xor_set1(chunk, iv.as_mut_slice()); - self.cipher.encrypt_block(&mut iv); + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + type BlockSize = BS; } - let rem = chunks.into_remainder(); - xor_set1(rem, iv.as_mut_slice()); - self.pos = rem.len(); - self.iv = iv; - } - - /// Returns the current state (block and position) of the decryptor. - pub fn get_state(&self) -> (&Block, usize) { - (&self.iv, self.pos) - } - - /// Restore from the given state for resumption. - pub fn from_state(cipher: C, iv: &Block, pos: usize) -> Self { - Self { - cipher, - iv: iv.clone(), - pos, + impl<'a, BS, BC> BlockCipherEncClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + #[inline(always)] + fn call>( + self, + cipher_backend: &B, + ) { + let Self { iv, f } = self; + f.call(&mut CbcEncryptBackend { iv, cipher_backend }); + } } - } -} - -impl BlockSizeUser for Encryptor -where - C: BlockCipherEncrypt + BlockCipher, -{ - type BlockSize = C::BlockSize; -} -impl BlockModeEncrypt for Encryptor -where - C: BlockCipherEncrypt + BlockCipher, -{ - fn encrypt_with_backend(&mut self, f: impl BlockClosure) { let Self { cipher, iv } = self; cipher.encrypt_with_backend(Closure { iv, f }) } } -impl AsyncStreamCipher for Encryptor where C: BlockCipherEncrypt + BlockCipher {} +impl AsyncStreamCipher for Encryptor where C: BlockCipherEncrypt {} impl InnerUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, -{ - type Inner = C; -} - -impl InnerUser for BufEncryptor -where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type Inner = C; } impl IvSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, -{ - type IvSize = C::BlockSize; -} - -impl IvSizeUser for BufEncryptor -where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type IvSize = C::BlockSize; } impl InnerIvInit for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { @@ -140,21 +104,9 @@ where } } -impl InnerIvInit for BufEncryptor -where - C: BlockCipherEncrypt + BlockCipher, -{ - #[inline] - fn inner_iv_init(cipher: C, iv: &Iv) -> Self { - let mut iv = iv.clone(); - cipher.encrypt_block(&mut iv); - Self { cipher, iv, pos: 0 } - } -} - impl IvState for Encryptor where - C: BlockCipherEncrypt + BlockCipherDecrypt + BlockCipher, + C: BlockCipherEncrypt + BlockCipherDecrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -164,20 +116,9 @@ where } } -impl AlgorithmName for BufEncryptor -where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, -{ - fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("cfb::BufEncryptor<")?; - ::write_alg_name(f)?; - f.write_str(">") - } -} - impl AlgorithmName for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb::Encryptor<")?; @@ -188,7 +129,7 @@ where impl fmt::Debug for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb::Encryptor<")?; @@ -197,105 +138,51 @@ where } } -impl fmt::Debug for BufEncryptor -where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("cfb::BufEncryptor<")?; - ::write_alg_name(f)?; - f.write_str("> { ... }") - } -} - -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for Encryptor { - fn drop(&mut self) { - self.iv.zeroize(); - } -} - -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for BufEncryptor { +impl Drop for Encryptor { fn drop(&mut self) { + #[cfg(feature = "zeroize")] self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for Encryptor {} - -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for BufEncryptor {} - -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - iv: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} +impl ZeroizeOnDrop for Encryptor {} -struct Backend<'a, BS, BK> +struct CbcEncryptBackend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { iv: &'a mut Array, - backend: &'a mut BK, + cipher_backend: &'a BK, } -impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockSizeUser for CbcEncryptBackend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type BlockSize = BS; } -impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> +impl<'a, BS, BK> ParBlocksSizeUser for CbcEncryptBackend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeEncBackend for CbcEncryptBackend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn encrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { block.xor_in2out(self.iv); let mut t = block.get_out().clone(); - self.backend.proc_block((&mut t).into()); + self.cipher_backend.encrypt_block((&mut t).into()); *self.iv = t; } } diff --git a/cfb-mode/src/encrypt/buf.rs b/cfb-mode/src/encrypt/buf.rs new file mode 100644 index 0000000..2c93036 --- /dev/null +++ b/cfb-mode/src/encrypt/buf.rs @@ -0,0 +1,126 @@ +use super::xor_set1; +use cipher::{ + crypto_common::InnerUser, typenum::Unsigned, AlgorithmName, Block, BlockCipherEncrypt, + InnerIvInit, Iv, IvSizeUser, +}; +use core::fmt; + +#[cfg(feature = "zeroize")] +use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; + +/// CFB mode buffered encryptor. +#[derive(Clone)] +pub struct BufEncryptor +where + C: BlockCipherEncrypt, +{ + cipher: C, + iv: Block, + pos: usize, +} + +impl BufEncryptor +where + C: BlockCipherEncrypt, +{ + /// Encrypt a buffer in multiple parts. + pub fn encrypt(&mut self, mut data: &mut [u8]) { + let bs = C::BlockSize::USIZE; + let n = data.len(); + + if n < bs - self.pos { + xor_set1(data, &mut self.iv[self.pos..self.pos + n]); + self.pos += n; + return; + } + + let (left, right) = { data }.split_at_mut(bs - self.pos); + data = right; + let mut iv = self.iv.clone(); + xor_set1(left, &mut iv[self.pos..]); + self.cipher.encrypt_block(&mut iv); + + let mut chunks = data.chunks_exact_mut(bs); + for chunk in &mut chunks { + xor_set1(chunk, iv.as_mut_slice()); + self.cipher.encrypt_block(&mut iv); + } + + let rem = chunks.into_remainder(); + xor_set1(rem, iv.as_mut_slice()); + self.pos = rem.len(); + self.iv = iv; + } + + /// Returns the current state (block and position) of the decryptor. + pub fn get_state(&self) -> (&Block, usize) { + (&self.iv, self.pos) + } + + /// Restore from the given state for resumption. + pub fn from_state(cipher: C, iv: &Block, pos: usize) -> Self { + Self { + cipher, + iv: iv.clone(), + pos, + } + } +} + +impl InnerUser for BufEncryptor +where + C: BlockCipherEncrypt, +{ + type Inner = C; +} + +impl IvSizeUser for BufEncryptor +where + C: BlockCipherEncrypt, +{ + type IvSize = C::BlockSize; +} + +impl InnerIvInit for BufEncryptor +where + C: BlockCipherEncrypt, +{ + #[inline] + fn inner_iv_init(cipher: C, iv: &Iv) -> Self { + let mut iv = iv.clone(); + cipher.encrypt_block(&mut iv); + Self { cipher, iv, pos: 0 } + } +} + +impl AlgorithmName for BufEncryptor +where + C: BlockCipherEncrypt + AlgorithmName, +{ + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("cfb::BufEncryptor<")?; + ::write_alg_name(f)?; + f.write_str(">") + } +} + +impl fmt::Debug for BufEncryptor +where + C: BlockCipherEncrypt + AlgorithmName, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("cfb::BufEncryptor<")?; + ::write_alg_name(f)?; + f.write_str("> { ... }") + } +} + +impl Drop for BufEncryptor { + fn drop(&mut self) { + #[cfg(feature = "zeroize")] + self.iv.zeroize(); + } +} + +#[cfg(feature = "zeroize")] +impl ZeroizeOnDrop for BufEncryptor {} diff --git a/cfb-mode/src/lib.rs b/cfb-mode/src/lib.rs index 43f0299..40908ee 100644 --- a/cfb-mode/src/lib.rs +++ b/cfb-mode/src/lib.rs @@ -58,7 +58,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![forbid(unsafe_code)] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)] mod decrypt; diff --git a/cfb8/Cargo.toml b/cfb8/Cargo.toml index 0bf80a8..7e4f6a6 100644 --- a/cfb8/Cargo.toml +++ b/cfb8/Cargo.toml @@ -13,11 +13,11 @@ keywords = ["crypto", "block-mode", "stream-cipher", "ciphers"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "=0.5.0-pre.7" [dev-dependencies] aes = "=0.9.0-pre.1" -cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +cipher = { version = "=0.5.0-pre.7", features = ["dev"] } hex-literal = "0.4" [features] diff --git a/cfb8/src/decrypt.rs b/cfb8/src/decrypt.rs index a759964..8876c2b 100644 --- a/cfb8/src/decrypt.rs +++ b/cfb8/src/decrypt.rs @@ -3,9 +3,9 @@ use cipher::{ consts::U1, crypto_common::{BlockSizes, InnerUser, IvSizeUser}, inout::InOut, - AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockCipherDecrypt, - BlockCipherEncrypt, BlockClosure, BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv, IvState, - ParBlocksSizeUser, + AlgorithmName, AsyncStreamCipher, Block, BlockCipherEncBackend, BlockCipherEncClosure, + BlockCipherEncrypt, BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockSizeUser, + InnerIvInit, Iv, IvState, ParBlocksSizeUser, }; use core::fmt; @@ -16,7 +16,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { cipher: C, iv: Block, @@ -24,40 +24,69 @@ where impl BlockSizeUser for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type BlockSize = U1; } impl BlockModeDecrypt for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - fn decrypt_with_backend(&mut self, f: impl BlockClosure) { + fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure) { + struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + iv: &'a mut Array, + f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherEncClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + #[inline(always)] + fn call>(self, backend: &B) { + let Self { iv, f } = self; + f.call(&mut Backend { iv, backend }); + } + } + let Self { cipher, iv } = self; cipher.encrypt_with_backend(Closure { iv, f }) } } -impl AsyncStreamCipher for Decryptor {} +impl AsyncStreamCipher for Decryptor {} impl InnerUser for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type Inner = C; } impl IvSizeUser for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type IvSize = C::BlockSize; } impl InnerIvInit for Decryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { @@ -68,7 +97,7 @@ where impl IvState for Decryptor where - C: BlockCipherEncrypt + BlockCipherDecrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -78,7 +107,7 @@ where impl AlgorithmName for Decryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb8::Decryptor<")?; @@ -89,7 +118,7 @@ where impl fmt::Debug for Decryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb8::Decryptor<")?; @@ -98,60 +127,29 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for Decryptor { +impl Drop for Decryptor { fn drop(&mut self) { + #[cfg(feature = "zeroize")] self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for Decryptor {} - -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - iv: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} +impl ZeroizeOnDrop for Decryptor {} struct Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { iv: &'a mut Array, - backend: &'a mut BK, + backend: &'a BK, } impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type BlockSize = U1; } @@ -159,23 +157,23 @@ where impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeDecBackend for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn decrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { let mut t = self.iv.clone(); - self.backend.proc_block((&mut t).into()); + self.backend.encrypt_block((&mut t).into()); let r = block.get(0).clone_in(); - #[allow(deprecated)] - block.xor_in2out(Array::from_slice(&t[..1])); + let k: &Array = t[..1].try_into().unwrap(); + block.xor_in2out(k); let n = self.iv.len(); for i in 0..n - 1 { self.iv[i] = self.iv[i + 1]; diff --git a/cfb8/src/encrypt.rs b/cfb8/src/encrypt.rs index 80a5987..bea07ab 100644 --- a/cfb8/src/encrypt.rs +++ b/cfb8/src/encrypt.rs @@ -3,8 +3,9 @@ use cipher::{ consts::U1, crypto_common::{BlockSizes, InnerUser, IvSizeUser}, inout::InOut, - AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockCipherEncrypt, - BlockClosure, BlockModeEncrypt, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, + AlgorithmName, AsyncStreamCipher, Block, BlockCipherEncBackend, BlockCipherEncClosure, + BlockCipherEncrypt, BlockModeEncBackend, BlockModeEncClosure, BlockModeEncrypt, BlockSizeUser, + InnerIvInit, Iv, IvState, ParBlocksSizeUser, }; use core::fmt; @@ -15,7 +16,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { cipher: C, iv: Block, @@ -23,40 +24,69 @@ where impl BlockSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type BlockSize = U1; } impl BlockModeEncrypt for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { - fn encrypt_with_backend(&mut self, f: impl BlockClosure) { + fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure) { + struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + iv: &'a mut Array, + f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherEncClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + #[inline(always)] + fn call>(self, backend: &B) { + let Self { iv, f } = self; + f.call(&mut Backend { iv, backend }); + } + } + let Self { cipher, iv } = self; cipher.encrypt_with_backend(Closure { iv, f }) } } -impl AsyncStreamCipher for Encryptor {} +impl AsyncStreamCipher for Encryptor {} impl InnerUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type Inner = C; } impl IvSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type IvSize = C::BlockSize; } impl InnerIvInit for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { @@ -67,7 +97,7 @@ where impl IvState for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -77,7 +107,7 @@ where impl AlgorithmName for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb8::Encryptor<")?; @@ -88,7 +118,7 @@ where impl fmt::Debug for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb8::Encryptor<")?; @@ -97,60 +127,29 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for Encryptor { +impl Drop for Encryptor { fn drop(&mut self) { + #[cfg(feature = "zeroize")] self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for Encryptor {} - -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - iv: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} +impl ZeroizeOnDrop for Encryptor {} struct Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { iv: &'a mut Array, - backend: &'a mut BK, + backend: &'a BK, } impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type BlockSize = U1; } @@ -158,22 +157,22 @@ where impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeEncBackend for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn encrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { let mut t = self.iv.clone(); - self.backend.proc_block((&mut t).into()); - #[allow(deprecated)] - block.xor_in2out(Array::from_slice(&t[..1])); + self.backend.encrypt_block((&mut t).into()); + let k: &Array = t[..1].try_into().unwrap(); + block.xor_in2out(k); let r = block.get_out()[0]; let n = self.iv.len(); for i in 0..n - 1 { diff --git a/ctr/Cargo.toml b/ctr/Cargo.toml index 67a97e3..536e7eb 100644 --- a/ctr/Cargo.toml +++ b/ctr/Cargo.toml @@ -13,13 +13,13 @@ keywords = ["crypto", "block-mode", "stream-cipher", "ciphers"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "=0.5.0-pre.7" [dev-dependencies] aes = "=0.9.0-pre.1" magma = "=0.10.0-pre.1" kuznyechik = "=0.9.0-pre.1" -cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +cipher = { version = "=0.5.0-pre.7", features = ["dev"] } hex-literal = "0.4" [features] diff --git a/ctr/src/backend.rs b/ctr/src/backend.rs deleted file mode 100644 index 691a5dc..0000000 --- a/ctr/src/backend.rs +++ /dev/null @@ -1,83 +0,0 @@ -use crate::CtrFlavor; -use cipher::{ - array::ArraySize, crypto_common::BlockSizes, Block, BlockBackend, BlockClosure, BlockSizeUser, - ParBlocks, ParBlocksSizeUser, StreamBackend, StreamClosure, -}; - -struct Backend<'a, F, B> -where - F: CtrFlavor, - B: BlockBackend, -{ - ctr_nonce: &'a mut F::CtrNonce, - backend: &'a mut B, -} - -impl<'a, F, B> BlockSizeUser for Backend<'a, F, B> -where - F: CtrFlavor, - B: BlockBackend, -{ - type BlockSize = B::BlockSize; -} - -impl<'a, F, B> ParBlocksSizeUser for Backend<'a, F, B> -where - F: CtrFlavor, - B: BlockBackend, -{ - type ParBlocksSize = B::ParBlocksSize; -} - -impl<'a, F, B> StreamBackend for Backend<'a, F, B> -where - F: CtrFlavor, - B: BlockBackend, -{ - #[inline(always)] - fn gen_ks_block(&mut self, block: &mut Block) { - let tmp = F::next_block(self.ctr_nonce); - self.backend.proc_block((&tmp, block).into()); - } - - #[inline(always)] - fn gen_par_ks_blocks(&mut self, blocks: &mut ParBlocks) { - let mut tmp = ParBlocks::::default(); - for block in tmp.iter_mut() { - *block = F::next_block(self.ctr_nonce); - } - self.backend.proc_par_blocks((&tmp, blocks).into()); - } -} - -pub(crate) struct Closure<'a, F, BS, SC> -where - F: CtrFlavor, - BS: ArraySize, - SC: StreamClosure, -{ - pub(crate) ctr_nonce: &'a mut F::CtrNonce, - pub(crate) f: SC, -} - -impl<'a, F, BS, SC> BlockSizeUser for Closure<'a, F, BS, SC> -where - F: CtrFlavor, - BS: BlockSizes, - SC: StreamClosure, -{ - type BlockSize = BS; -} - -impl<'a, F, BS, SC> BlockClosure for Closure<'a, F, BS, SC> -where - F: CtrFlavor, - BS: BlockSizes, - SC: StreamClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { ctr_nonce, f } = self; - f.call(&mut Backend:: { ctr_nonce, backend }) - } -} diff --git a/ctr/src/ctr_core.rs b/ctr/src/ctr_core.rs index ec65296..5284b6b 100644 --- a/ctr/src/ctr_core.rs +++ b/ctr/src/ctr_core.rs @@ -1,7 +1,9 @@ -use crate::{backend::Closure, CtrFlavor}; +use crate::CtrFlavor; use cipher::{ - crypto_common::{InnerUser, IvSizeUser}, - AlgorithmName, BlockCipher, BlockCipherEncrypt, BlockSizeUser, InnerIvInit, Iv, IvState, + array::ArraySize, + crypto_common::{BlockSizes, InnerUser, IvSizeUser}, + AlgorithmName, Block, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, + BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocks, ParBlocksSizeUser, StreamBackend, StreamCipherCore, StreamCipherSeekCore, StreamClosure, }; use core::fmt; @@ -12,7 +14,7 @@ use cipher::zeroize::ZeroizeOnDrop; /// Generic CTR block mode instance. pub struct CtrCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, F: CtrFlavor, { cipher: C, @@ -21,7 +23,7 @@ where impl BlockSizeUser for CtrCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, F: CtrFlavor, { type BlockSize = C::BlockSize; @@ -29,7 +31,7 @@ where impl StreamCipherCore for CtrCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, F: CtrFlavor, { #[inline] @@ -39,6 +41,38 @@ where #[inline] fn process_with_backend(&mut self, f: impl StreamClosure) { + struct Closure<'a, F, BS, SC> + where + BS: ArraySize, + F: CtrFlavor, + SC: StreamClosure, + { + ctr_nonce: &'a mut F::CtrNonce, + f: SC, + } + + impl<'a, F, BS, SC> BlockSizeUser for Closure<'a, F, BS, SC> + where + BS: BlockSizes, + F: CtrFlavor, + SC: StreamClosure, + { + type BlockSize = BS; + } + + impl<'a, F, BS, SC> BlockCipherEncClosure for Closure<'a, F, BS, SC> + where + BS: BlockSizes, + F: CtrFlavor, + SC: StreamClosure, + { + #[inline(always)] + fn call>(self, backend: &B) { + let Self { ctr_nonce, f } = self; + f.call(&mut Backend:: { ctr_nonce, backend }) + } + } + let Self { cipher, ctr_nonce } = self; cipher.encrypt_with_backend(Closure:: { ctr_nonce, f }); } @@ -46,7 +80,7 @@ where impl StreamCipherSeekCore for CtrCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, F: CtrFlavor, { type Counter = F::Backend; @@ -64,7 +98,7 @@ where impl InnerUser for CtrCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, F: CtrFlavor, { type Inner = C; @@ -72,7 +106,7 @@ where impl IvSizeUser for CtrCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, F: CtrFlavor, { type IvSize = C::BlockSize; @@ -80,7 +114,7 @@ where impl InnerIvInit for CtrCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, F: CtrFlavor, { #[inline] @@ -94,7 +128,7 @@ where impl IvState for CtrCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, F: CtrFlavor, { #[inline] @@ -105,7 +139,7 @@ where impl AlgorithmName for CtrCore where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, F: CtrFlavor, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -119,7 +153,7 @@ where impl Clone for CtrCore where - C: BlockCipherEncrypt + BlockCipher + Clone, + C: BlockCipherEncrypt + Clone, F: CtrFlavor, { #[inline] @@ -133,7 +167,7 @@ where impl fmt::Debug for CtrCore where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, F: CtrFlavor, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -146,11 +180,56 @@ where } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl ZeroizeOnDrop for CtrCore where - C: BlockCipherEncrypt + BlockCipher + ZeroizeOnDrop, + C: BlockCipherEncrypt + ZeroizeOnDrop, F: CtrFlavor, F::CtrNonce: ZeroizeOnDrop, { } + +struct Backend<'a, F, B> +where + F: CtrFlavor, + B: BlockCipherEncBackend, +{ + ctr_nonce: &'a mut F::CtrNonce, + backend: &'a B, +} + +impl<'a, F, B> BlockSizeUser for Backend<'a, F, B> +where + F: CtrFlavor, + B: BlockCipherEncBackend, +{ + type BlockSize = B::BlockSize; +} + +impl<'a, F, B> ParBlocksSizeUser for Backend<'a, F, B> +where + F: CtrFlavor, + B: BlockCipherEncBackend, +{ + type ParBlocksSize = B::ParBlocksSize; +} + +impl<'a, F, B> StreamBackend for Backend<'a, F, B> +where + F: CtrFlavor, + B: BlockCipherEncBackend, +{ + #[inline(always)] + fn gen_ks_block(&mut self, block: &mut Block) { + let tmp = F::next_block(self.ctr_nonce); + self.backend.encrypt_block((&tmp, block).into()); + } + + #[inline(always)] + fn gen_par_ks_blocks(&mut self, blocks: &mut ParBlocks) { + let mut tmp = ParBlocks::::default(); + for block in tmp.iter_mut() { + *block = F::next_block(self.ctr_nonce); + } + self.backend.encrypt_par_blocks((&tmp, blocks).into()); + } +} diff --git a/ctr/src/flavors/ctr32.rs b/ctr/src/flavors/ctr32.rs index 92f8a94..184dc7a 100644 --- a/ctr/src/flavors/ctr32.rs +++ b/ctr/src/flavors/ctr32.rs @@ -26,11 +26,13 @@ impl fmt::Debug for CtrNonce32 { } } -#[cfg(feature = "zeroize")] impl Drop for CtrNonce32 { fn drop(&mut self) { - self.ctr.zeroize(); - self.nonce.zeroize(); + #[cfg(feature = "zeroize")] + { + self.ctr.zeroize(); + self.nonce.zeroize(); + } } } @@ -52,7 +54,7 @@ where #[inline] fn remaining(cn: &Self::CtrNonce) -> Option { - (core::u32::MAX - cn.ctr).try_into().ok() + (u32::MAX - cn.ctr).try_into().ok() } #[inline(always)] @@ -117,7 +119,7 @@ where #[inline] fn remaining(cn: &Self::CtrNonce) -> Option { - (core::u32::MAX - cn.ctr).try_into().ok() + (u32::MAX - cn.ctr).try_into().ok() } #[inline(always)] diff --git a/ctr/src/flavors/ctr64.rs b/ctr/src/flavors/ctr64.rs index 08eb287..67831c0 100644 --- a/ctr/src/flavors/ctr64.rs +++ b/ctr/src/flavors/ctr64.rs @@ -26,11 +26,13 @@ impl fmt::Debug for CtrNonce64 { } } -#[cfg(feature = "zeroize")] impl Drop for CtrNonce64 { fn drop(&mut self) { - self.ctr.zeroize(); - self.nonce.zeroize(); + #[cfg(feature = "zeroize")] + { + self.ctr.zeroize(); + self.nonce.zeroize(); + } } } @@ -52,7 +54,7 @@ where #[inline] fn remaining(cn: &Self::CtrNonce) -> Option { - (core::u64::MAX - cn.ctr).try_into().ok() + (u64::MAX - cn.ctr).try_into().ok() } #[inline(always)] @@ -117,7 +119,7 @@ where #[inline] fn remaining(cn: &Self::CtrNonce) -> Option { - (core::u64::MAX - cn.ctr).try_into().ok() + (u64::MAX - cn.ctr).try_into().ok() } #[inline(always)] diff --git a/ctr/src/lib.rs b/ctr/src/lib.rs index 5cfb603..fd22570 100644 --- a/ctr/src/lib.rs +++ b/ctr/src/lib.rs @@ -67,10 +67,8 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)] -pub mod flavors; - -mod backend; mod ctr_core; +pub mod flavors; pub use cipher; pub use flavors::CtrFlavor; diff --git a/ige/Cargo.toml b/ige/Cargo.toml index dda583d..73c21a1 100644 --- a/ige/Cargo.toml +++ b/ige/Cargo.toml @@ -13,11 +13,11 @@ keywords = ["crypto", "block-mode", "ciphers"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "=0.5.0-pre.7" [dev-dependencies] aes = "=0.9.0-pre.1" -cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +cipher = { version = "=0.5.0-pre.7", features = ["dev"] } hex-literal = "0.4" [features] diff --git a/ige/src/decrypt.rs b/ige/src/decrypt.rs index 92f4458..2dab0b4 100644 --- a/ige/src/decrypt.rs +++ b/ige/src/decrypt.rs @@ -4,8 +4,9 @@ use cipher::{ crypto_common::{BlockSizes, InnerUser, IvSizeUser}, inout::InOut, typenum::{Unsigned, U1}, - AlgorithmName, Block, BlockBackend, BlockCipher, BlockCipherDecrypt, BlockClosure, - BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, + AlgorithmName, Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, + BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv, + IvState, ParBlocksSizeUser, }; use core::{fmt, ops::Add}; @@ -16,7 +17,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -27,11 +28,48 @@ where impl BlockModeDecrypt for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { - fn decrypt_with_backend(&mut self, f: impl BlockClosure) { + fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure) { + struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + x: &'a mut Array, + y: &'a mut Array, + f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherDecClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + #[inline(always)] + fn call>( + self, + cipher_backend: &B, + ) { + let Self { x, y, f } = self; + f.call(&mut Backend { + x, + y, + cipher_backend, + }); + } + } + let Self { cipher, x, y } = self; cipher.decrypt_with_backend(Closure { x, y, f }) } @@ -39,7 +77,7 @@ where impl BlockSizeUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -48,7 +86,7 @@ where impl InnerUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -57,7 +95,7 @@ where impl IvSizeUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -66,25 +104,22 @@ where impl InnerIvInit for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { #[inline] - #[allow(deprecated)] // clone_from_slice fn inner_iv_init(cipher: C, iv: &Iv) -> Self { - let (y, x) = iv.split_at(C::BlockSize::to_usize()); - Self { - cipher, - x: Array::clone_from_slice(x), - y: Array::clone_from_slice(y), - } + let n = C::BlockSize::USIZE; + let y = iv[..n].try_into().unwrap(); + let x = iv[n..].try_into().unwrap(); + Self { cipher, x, y } } } impl IvState for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -96,7 +131,7 @@ where impl AlgorithmName for Decryptor where - C: BlockCipherDecrypt + BlockCipher + AlgorithmName, + C: BlockCipherDecrypt + AlgorithmName, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -109,7 +144,7 @@ where impl fmt::Debug for Decryptor where - C: BlockCipherDecrypt + BlockCipher + AlgorithmName, + C: BlockCipherDecrypt + AlgorithmName, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -120,74 +155,44 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl Drop for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { fn drop(&mut self) { - self.x.zeroize(); - self.y.zeroize(); + #[cfg(feature = "zeroize")] + { + self.x.zeroize(); + self.y.zeroize(); + } } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl ZeroizeOnDrop for Decryptor where - C: BlockCipherDecrypt + BlockCipher + ZeroizeOnDrop, + C: BlockCipherDecrypt + ZeroizeOnDrop, C::BlockSize: Add, IgeIvSize: ArraySize, { } -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - x: &'a mut Array, - y: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { x, y, f } = self; - f.call(&mut Backend { x, y, backend }); - } -} - struct Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { x: &'a mut Array, y: &'a mut Array, - backend: &'a mut BK, + cipher_backend: &'a BK, } impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { type BlockSize = BS; } @@ -195,22 +200,22 @@ where impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeDecBackend for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn decrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { let new_y = block.clone_in(); let mut t = new_y.clone(); xor(&mut t, self.x); - self.backend.proc_block((&mut t).into()); + self.cipher_backend.decrypt_block((&mut t).into()); xor(&mut t, self.y); *block.get_out() = t.clone(); *self.x = t; diff --git a/ige/src/encrypt.rs b/ige/src/encrypt.rs index 171af96..b88db91 100644 --- a/ige/src/encrypt.rs +++ b/ige/src/encrypt.rs @@ -4,8 +4,9 @@ use cipher::{ crypto_common::{BlockSizes, InnerUser, IvSizeUser}, inout::InOut, typenum::{Unsigned, U1}, - AlgorithmName, Block, BlockBackend, BlockCipher, BlockCipherEncrypt, BlockClosure, - BlockModeEncrypt, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, + AlgorithmName, Block, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, + BlockModeEncBackend, BlockModeEncClosure, BlockModeEncrypt, BlockSizeUser, InnerIvInit, Iv, + IvState, ParBlocksSizeUser, }; use core::{fmt, ops::Add}; @@ -16,7 +17,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -27,11 +28,48 @@ where impl BlockModeEncrypt for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { - fn encrypt_with_backend(&mut self, f: impl BlockClosure) { + fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure) { + struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + x: &'a mut Array, + y: &'a mut Array, + f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherEncClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + #[inline(always)] + fn call>( + self, + cipher_backend: &B, + ) { + let Self { x, y, f } = self; + f.call(&mut Backend { + x, + y, + cipher_backend, + }); + } + } + let Self { cipher, x, y } = self; cipher.encrypt_with_backend(Closure { x, y, f }) } @@ -39,7 +77,7 @@ where impl BlockSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -48,7 +86,7 @@ where impl InnerUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -57,7 +95,7 @@ where impl IvSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -66,25 +104,22 @@ where impl InnerIvInit for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { - let (y, x) = iv.split_at(C::BlockSize::to_usize()); - #[allow(deprecated)] // clone_from_slice - Self { - cipher, - x: Array::clone_from_slice(x), - y: Array::clone_from_slice(y), - } + let n = C::BlockSize::USIZE; + let y = iv[..n].try_into().unwrap(); + let x = iv[n..].try_into().unwrap(); + Self { cipher, x, y } } } impl IvState for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -96,7 +131,7 @@ where impl AlgorithmName for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -109,7 +144,7 @@ where impl fmt::Debug for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, C::BlockSize: Add, IgeIvSize: ArraySize, { @@ -120,74 +155,44 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl Drop for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, C::BlockSize: Add, IgeIvSize: ArraySize, { fn drop(&mut self) { - self.x.zeroize(); - self.y.zeroize(); + #[cfg(feature = "zeroize")] + { + self.x.zeroize(); + self.y.zeroize(); + } } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl ZeroizeOnDrop for Encryptor where - C: BlockCipherEncrypt + BlockCipher + ZeroizeOnDrop, + C: BlockCipherEncrypt + ZeroizeOnDrop, C::BlockSize: Add, IgeIvSize: ArraySize, { } -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - x: &'a mut Array, - y: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { x, y, f } = self; - f.call(&mut Backend { x, y, backend }); - } -} - struct Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { x: &'a mut Array, y: &'a mut Array, - backend: &'a mut BK, + cipher_backend: &'a BK, } impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type BlockSize = BS; } @@ -195,22 +200,22 @@ where impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeEncBackend for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn encrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { let new_x = block.clone_in(); let mut t = new_x.clone(); xor(&mut t, self.y); - self.backend.proc_block((&mut t).into()); + self.cipher_backend.encrypt_block((&mut t).into()); xor(&mut t, self.x); *block.get_out() = t.clone(); *self.x = new_x; diff --git a/ige/src/lib.rs b/ige/src/lib.rs index 1c37744..15be7f3 100644 --- a/ige/src/lib.rs +++ b/ige/src/lib.rs @@ -93,7 +93,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![forbid(unsafe_code)] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)] mod decrypt; diff --git a/ofb/Cargo.toml b/ofb/Cargo.toml index 22db8bb..3eaad26 100644 --- a/ofb/Cargo.toml +++ b/ofb/Cargo.toml @@ -13,11 +13,11 @@ keywords = ["crypto", "block-mode", "stream-cipher", "ciphers"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "=0.5.0-pre.7" [dev-dependencies] aes = "=0.9.0-pre.1" -cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +cipher = { version = "=0.5.0-pre.7", features = ["dev"] } hex-literal = "0.4" [features] diff --git a/ofb/src/backend.rs b/ofb/src/backend.rs deleted file mode 100644 index d2fa770..0000000 --- a/ofb/src/backend.rs +++ /dev/null @@ -1,111 +0,0 @@ -use cipher::{ - array::Array, consts::U1, crypto_common::BlockSizes, inout::InOut, Block, BlockBackend, - BlockClosure, BlockSizeUser, ParBlocksSizeUser, StreamBackend, StreamClosure, -}; - -pub(crate) struct Closure1<'a, BS, SC> -where - BS: BlockSizes, - SC: StreamClosure, -{ - pub(crate) iv: &'a mut Array, - pub(crate) f: SC, -} - -impl<'a, BS, SC> BlockSizeUser for Closure1<'a, BS, SC> -where - BS: BlockSizes, - SC: StreamClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, SC> BlockClosure for Closure1<'a, BS, SC> -where - BS: BlockSizes, - SC: StreamClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} - -pub(crate) struct Closure2<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - pub(crate) iv: &'a mut Array, - pub(crate) f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure2<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure2<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} - -struct Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - iv: &'a mut Array, - backend: &'a mut BK, -} - -impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - type BlockSize = BS; -} - -impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - type ParBlocksSize = U1; -} - -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { - self.backend.proc_block(self.iv.into()); - block.xor_in2out(self.iv); - } -} - -impl<'a, BS, BK> StreamBackend for Backend<'a, BS, BK> -where - BS: BlockSizes, - BK: BlockBackend, -{ - #[inline(always)] - fn gen_ks_block(&mut self, block: &mut Block) { - self.backend.proc_block(self.iv.into()); - *block = self.iv.clone(); - } -} diff --git a/ofb/src/lib.rs b/ofb/src/lib.rs index 0429466..c99ce92 100644 --- a/ofb/src/lib.rs +++ b/ofb/src/lib.rs @@ -65,18 +65,18 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)] -pub use cipher; - -mod backend; - use cipher::{ - crypto_common::{InnerUser, IvSizeUser}, - AlgorithmName, Block, BlockCipher, BlockCipherEncrypt, BlockClosure, BlockModeDecrypt, - BlockModeEncrypt, BlockSizeUser, InnerIvInit, Iv, IvState, StreamCipherCore, - StreamCipherCoreWrapper, StreamClosure, + consts::U1, + crypto_common::{BlockSizes, InnerUser, IvSizeUser}, + AlgorithmName, Array, Block, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, + BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockModeEncBackend, + BlockModeEncClosure, BlockModeEncrypt, BlockSizeUser, InOut, InnerIvInit, Iv, IvState, + ParBlocksSizeUser, StreamBackend, StreamCipherCore, StreamCipherCoreWrapper, StreamClosure, }; use core::fmt; +pub use cipher; + #[cfg(feature = "zeroize")] use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; @@ -87,7 +87,7 @@ pub type Ofb = StreamCipherCoreWrapper>; #[derive(Clone)] pub struct OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { cipher: C, iv: Block, @@ -95,28 +95,28 @@ where impl BlockSizeUser for OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type BlockSize = C::BlockSize; } impl InnerUser for OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type Inner = C; } impl IvSizeUser for OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type IvSize = C::BlockSize; } impl InnerIvInit for OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { @@ -129,7 +129,7 @@ where impl IvState for OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -139,43 +139,130 @@ where impl StreamCipherCore for OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { fn remaining_blocks(&self) -> Option { None } fn process_with_backend(&mut self, f: impl StreamClosure) { + pub(crate) struct Closure<'a, BS, SC> + where + BS: BlockSizes, + SC: StreamClosure, + { + pub(crate) iv: &'a mut Array, + pub(crate) f: SC, + } + + impl<'a, BS, SC> BlockSizeUser for Closure<'a, BS, SC> + where + BS: BlockSizes, + SC: StreamClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, SC> BlockCipherEncClosure for Closure<'a, BS, SC> + where + BS: BlockSizes, + SC: StreamClosure, + { + #[inline(always)] + fn call>(self, backend: &B) { + let Self { iv, f } = self; + f.call(&mut Backend { iv, backend }); + } + } + let Self { cipher, iv } = self; - cipher.encrypt_with_backend(backend::Closure1 { iv, f }); + cipher.encrypt_with_backend(Closure { iv, f }); } } impl BlockModeEncrypt for OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] - fn encrypt_with_backend(&mut self, f: impl BlockClosure) { + fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure) { + pub(crate) struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + pub(crate) iv: &'a mut Array, + pub(crate) f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherEncClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + #[inline(always)] + fn call>(self, backend: &B) { + let Self { iv, f } = self; + f.call(&mut Backend { iv, backend }); + } + } + let Self { cipher, iv } = self; - cipher.encrypt_with_backend(backend::Closure2 { iv, f }) + cipher.encrypt_with_backend(Closure { iv, f }) } } impl BlockModeDecrypt for OfbCore where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] - fn decrypt_with_backend(&mut self, f: impl BlockClosure) { + fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure) { + pub(crate) struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + pub(crate) iv: &'a mut Array, + pub(crate) f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherEncClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + #[inline(always)] + fn call>(self, backend: &B) { + let Self { iv, f } = self; + f.call(&mut Backend { iv, backend }); + } + } + let Self { cipher, iv } = self; - cipher.encrypt_with_backend(backend::Closure2 { iv, f }) + cipher.encrypt_with_backend(Closure { iv, f }) } } impl AlgorithmName for OfbCore where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("Ofb<")?; @@ -186,7 +273,7 @@ where impl fmt::Debug for OfbCore where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("OfbCore<")?; @@ -195,14 +282,73 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for OfbCore { +impl Drop for OfbCore { fn drop(&mut self) { + #[cfg(feature = "zeroize")] self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for OfbCore {} +impl ZeroizeOnDrop for OfbCore {} + +pub(crate) struct Backend<'a, BS, BK> +where + BS: BlockSizes, + BK: BlockCipherEncBackend, +{ + pub iv: &'a mut Array, + pub backend: &'a BK, +} + +impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> +where + BS: BlockSizes, + BK: BlockCipherEncBackend, +{ + type BlockSize = BS; +} + +impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> +where + BS: BlockSizes, + BK: BlockCipherEncBackend, +{ + type ParBlocksSize = U1; +} + +impl<'a, BS, BK> StreamBackend for Backend<'a, BS, BK> +where + BS: BlockSizes, + BK: BlockCipherEncBackend, +{ + #[inline(always)] + fn gen_ks_block(&mut self, block: &mut Block) { + self.backend.encrypt_block(self.iv.into()); + *block = self.iv.clone(); + } +} + +impl<'a, BS, BK> BlockModeEncBackend for Backend<'a, BS, BK> +where + BS: BlockSizes, + BK: BlockCipherEncBackend, +{ + #[inline(always)] + fn encrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { + self.backend.encrypt_block(self.iv.into()); + block.xor_in2out(self.iv); + } +} + +impl<'a, BS, BK> BlockModeDecBackend for Backend<'a, BS, BK> +where + BS: BlockSizes, + BK: BlockCipherEncBackend, +{ + #[inline(always)] + fn decrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { + self.backend.encrypt_block(self.iv.into()); + block.xor_in2out(self.iv); + } +} diff --git a/pcbc/Cargo.toml b/pcbc/Cargo.toml index b7df0e6..f4f2bec 100644 --- a/pcbc/Cargo.toml +++ b/pcbc/Cargo.toml @@ -13,11 +13,11 @@ keywords = ["crypto", "block-mode", "ciphers"] categories = ["cryptography", "no-std"] [dependencies] -cipher = "=0.5.0-pre.6" +cipher = "=0.5.0-pre.7" [dev-dependencies] aes = "=0.9.0-pre.1" -cipher = { version = "=0.5.0-pre.6", features = ["dev"] } +cipher = { version = "=0.5.0-pre.7", features = ["dev"] } hex-literal = "0.4" [features] diff --git a/pcbc/src/decrypt.rs b/pcbc/src/decrypt.rs index 0c57dcf..46be953 100644 --- a/pcbc/src/decrypt.rs +++ b/pcbc/src/decrypt.rs @@ -4,8 +4,9 @@ use cipher::{ consts::U1, crypto_common::{BlockSizes, InnerUser, IvSizeUser}, inout::InOut, - AlgorithmName, Block, BlockBackend, BlockCipher, BlockCipherDecrypt, BlockClosure, - BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, + AlgorithmName, Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, + BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv, + IvState, ParBlocksSizeUser, }; use core::fmt; @@ -16,7 +17,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { cipher: C, iv: Block, @@ -24,16 +25,50 @@ where impl BlockSizeUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { type BlockSize = C::BlockSize; } impl BlockModeDecrypt for Decryptor where - C: BlockCipherDecrypt + BlockCipher, -{ - fn decrypt_with_backend(&mut self, f: impl BlockClosure) { + C: BlockCipherDecrypt, +{ + fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure) { + /// This closure is used to recieve block cipher backend and create + /// respective `Backend` based on it. + struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + iv: &'a mut Array, + f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherDecClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeDecClosure, + { + #[inline(always)] + fn call>( + self, + cipher_backend: &B, + ) { + let Self { iv, f } = self; + f.call(&mut Backend { iv, cipher_backend }); + } + } + let Self { cipher, iv } = self; cipher.decrypt_with_backend(Closure { iv, f }) } @@ -41,21 +76,21 @@ where impl InnerUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { type Inner = C; } impl IvSizeUser for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { type IvSize = C::BlockSize; } impl InnerIvInit for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { @@ -68,7 +103,7 @@ where impl IvState for Decryptor where - C: BlockCipherDecrypt + BlockCipher, + C: BlockCipherDecrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -78,7 +113,7 @@ where impl AlgorithmName for Decryptor where - C: BlockCipherDecrypt + BlockCipher + AlgorithmName, + C: BlockCipherDecrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("pcbc::Decryptor<")?; @@ -89,7 +124,7 @@ where impl fmt::Debug for Decryptor where - C: BlockCipherDecrypt + BlockCipher + AlgorithmName, + C: BlockCipherDecrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("pcbc::Decryptor<")?; @@ -99,59 +134,28 @@ where } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for Decryptor { +impl Drop for Decryptor { fn drop(&mut self) { self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for Decryptor {} - -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - iv: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} +impl ZeroizeOnDrop for Decryptor {} struct Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { iv: &'a mut Array, - backend: &'a mut BK, + cipher_backend: &'a BK, } impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { type BlockSize = BS; } @@ -159,21 +163,21 @@ where impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeDecBackend for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherDecBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn decrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { let mut t1 = block.clone_in(); let mut t2 = block.clone_in(); - self.backend.proc_block((&mut t1).into()); + self.cipher_backend.decrypt_block((&mut t1).into()); xor(&mut t1, self.iv); xor(&mut t2, &t1); *self.iv = t2; diff --git a/pcbc/src/encrypt.rs b/pcbc/src/encrypt.rs index 2e4700e..e32f3ea 100644 --- a/pcbc/src/encrypt.rs +++ b/pcbc/src/encrypt.rs @@ -4,8 +4,9 @@ use cipher::{ consts::U1, crypto_common::{BlockSizes, InnerUser, IvSizeUser}, inout::InOut, - AlgorithmName, Block, BlockBackend, BlockCipher, BlockCipherEncrypt, BlockClosure, - BlockModeEncrypt, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, + AlgorithmName, Block, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, + BlockModeEncBackend, BlockModeEncClosure, BlockModeEncrypt, BlockSizeUser, InnerIvInit, Iv, + IvState, ParBlocksSizeUser, }; use core::fmt; @@ -16,7 +17,7 @@ use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; #[derive(Clone)] pub struct Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { cipher: C, iv: Block, @@ -24,16 +25,47 @@ where impl BlockSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type BlockSize = C::BlockSize; } impl BlockModeEncrypt for Encryptor where - C: BlockCipherEncrypt + BlockCipher, -{ - fn encrypt_with_backend(&mut self, f: impl BlockClosure) { + C: BlockCipherEncrypt, +{ + fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure) { + /// This closure is used to recieve block cipher backend and create + /// respective `Backend` based on it. + struct Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + iv: &'a mut Array, + f: BC, + } + + impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + type BlockSize = BS; + } + + impl<'a, BS, BC> BlockCipherEncClosure for Closure<'a, BS, BC> + where + BS: BlockSizes, + BC: BlockModeEncClosure, + { + #[inline(always)] + fn call>(self, backend: &B) { + let Self { iv, f } = self; + f.call(&mut Backend { iv, backend }); + } + } + let Self { cipher, iv } = self; cipher.encrypt_with_backend(Closure { iv, f }) } @@ -41,21 +73,21 @@ where impl InnerUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type Inner = C; } impl IvSizeUser for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { type IvSize = C::BlockSize; } impl InnerIvInit for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn inner_iv_init(cipher: C, iv: &Iv) -> Self { @@ -68,7 +100,7 @@ where impl IvState for Encryptor where - C: BlockCipherEncrypt + BlockCipher, + C: BlockCipherEncrypt, { #[inline] fn iv_state(&self) -> Iv { @@ -78,7 +110,7 @@ where impl AlgorithmName for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("pcbc::Encryptor<")?; @@ -89,7 +121,7 @@ where impl fmt::Debug for Encryptor where - C: BlockCipherEncrypt + BlockCipher + AlgorithmName, + C: BlockCipherEncrypt + AlgorithmName, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("pcbc::Encryptor<")?; @@ -98,60 +130,29 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for Encryptor { +impl Drop for Encryptor { fn drop(&mut self) { + #[cfg(feature = "zeroize")] self.iv.zeroize(); } } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl ZeroizeOnDrop for Encryptor {} - -struct Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - iv: &'a mut Array, - f: BC, -} - -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - type BlockSize = BS; -} - -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> -where - BS: BlockSizes, - BC: BlockClosure, -{ - #[inline(always)] - fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); - } -} +impl ZeroizeOnDrop for Encryptor {} struct Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { iv: &'a mut Array, - backend: &'a mut BK, + backend: &'a BK, } impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type BlockSize = BS; } @@ -159,22 +160,22 @@ where impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, BS, BK> BlockModeEncBackend for Backend<'a, BS, BK> where BS: BlockSizes, - BK: BlockBackend, + BK: BlockCipherEncBackend, { #[inline(always)] - fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { + fn encrypt_block(&mut self, mut block: InOut<'_, '_, Block>) { let mut t1 = block.clone_in(); let mut t2 = block.clone_in(); xor(&mut t1, self.iv); - self.backend.proc_block((&mut t1).into()); + self.backend.encrypt_block((&mut t1).into()); xor(&mut t2, &t1); *block.get_out() = t1; *self.iv = t2; diff --git a/pcbc/src/lib.rs b/pcbc/src/lib.rs index 245406c..5c0190a 100644 --- a/pcbc/src/lib.rs +++ b/pcbc/src/lib.rs @@ -94,7 +94,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![forbid(unsafe_code)] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)] mod decrypt;