From bf4377a020d85e19b1454d5fd25171a2721706fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 6 Jan 2023 23:04:07 +0300 Subject: [PATCH 1/4] cfb-mode: generic mode block size --- cfb-mode/src/buf_decrypt.rs | 135 ++++++++++++++++ cfb-mode/src/buf_encrypt.rs | 136 ++++++++++++++++ cfb-mode/src/decrypt.rs | 307 ++++++++++++++---------------------- cfb-mode/src/encrypt.rs | 273 ++++++++++++-------------------- cfb-mode/src/lib.rs | 11 +- 5 files changed, 502 insertions(+), 360 deletions(-) create mode 100644 cfb-mode/src/buf_decrypt.rs create mode 100644 cfb-mode/src/buf_encrypt.rs diff --git a/cfb-mode/src/buf_decrypt.rs b/cfb-mode/src/buf_decrypt.rs new file mode 100644 index 0000000..9164b60 --- /dev/null +++ b/cfb-mode/src/buf_decrypt.rs @@ -0,0 +1,135 @@ +use cipher::{ + crypto_common::{InnerUser, IvSizeUser}, + AlgorithmName, Block, BlockCipher, BlockEncryptMut, InnerIvInit, Iv, Unsigned, +}; +use core::fmt; + +#[cfg(feature = "zeroize")] +use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; + +/// CFB mode buffered decryptor. +#[derive(Clone)] +pub struct BufDecryptor +where + C: BlockEncryptMut + BlockCipher, +{ + cipher: C, + iv: Block, + pos: usize, +} + +impl BufDecryptor +where + C: BlockEncryptMut + BlockCipher, +{ + /// Decrypt a buffer in multiple parts. + pub fn decrypt(&mut self, mut data: &mut [u8]) { + let bs = C::BlockSize::to_usize(); + let n = data.len(); + + if n < bs - self.pos { + xor_set2(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_set2(left, &mut iv[self.pos..]); + self.cipher.encrypt_block_mut(&mut iv); + + let mut chunks = data.chunks_exact_mut(bs); + for chunk in &mut chunks { + xor_set2(chunk, iv.as_mut_slice()); + self.cipher.encrypt_block_mut(&mut iv); + } + + let rem = chunks.into_remainder(); + xor_set2(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 BufDecryptor +where + C: BlockEncryptMut + BlockCipher, +{ + type Inner = C; +} + +impl IvSizeUser for BufDecryptor +where + C: BlockEncryptMut + BlockCipher, +{ + type IvSize = C::BlockSize; +} + +impl InnerIvInit for BufDecryptor +where + C: BlockEncryptMut + BlockCipher, +{ + #[inline] + fn inner_iv_init(mut cipher: C, iv: &Iv) -> Self { + let mut iv = iv.clone(); + cipher.encrypt_block_mut(&mut iv); + Self { cipher, iv, pos: 0 } + } +} + +impl AlgorithmName for BufDecryptor +where + C: BlockEncryptMut + 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 BufDecryptor +where + C: BlockEncryptMut + 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 BufDecryptor { + fn drop(&mut self) { + self.iv.zeroize(); + } +} + +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl ZeroizeOnDrop for BufDecryptor {} + +#[inline(always)] +fn xor_set2(buf1: &mut [u8], buf2: &mut [u8]) { + for (a, b) in buf1.iter_mut().zip(buf2) { + let t = *a; + *a ^= *b; + *b = t; + } +} diff --git a/cfb-mode/src/buf_encrypt.rs b/cfb-mode/src/buf_encrypt.rs new file mode 100644 index 0000000..0992376 --- /dev/null +++ b/cfb-mode/src/buf_encrypt.rs @@ -0,0 +1,136 @@ +use cipher::{ + crypto_common::{InnerUser, IvSizeUser}, + AlgorithmName, Block, BlockCipher, BlockEncryptMut, InnerIvInit, Iv, Unsigned, +}; +use core::fmt; + +#[cfg(feature = "zeroize")] +use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; + +/// CFB mode buffered encryptor. +#[derive(Clone)] +pub struct BufEncryptor +where + C: BlockEncryptMut + BlockCipher, +{ + cipher: C, + iv: Block, + pos: usize, +} + +impl BufEncryptor +where + C: BlockEncryptMut + 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; + } + + 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(&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(&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: BlockEncryptMut + BlockCipher, +{ + type Inner = C; +} + +impl IvSizeUser for BufEncryptor +where + C: BlockEncryptMut + BlockCipher, +{ + type IvSize = C::BlockSize; +} + +impl InnerIvInit for BufEncryptor +where + C: BlockEncryptMut + BlockCipher, +{ + #[inline] + fn inner_iv_init(mut cipher: C, iv: &Iv) -> Self { + let mut iv = iv.clone(); + cipher.encrypt_block_mut(&mut iv); + Self { cipher, iv, pos: 0 } + } +} + +impl AlgorithmName for BufEncryptor +where + C: BlockEncryptMut + 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 fmt::Debug for BufEncryptor +where + C: BlockEncryptMut + 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 BufEncryptor { + fn drop(&mut self) { + self.iv.zeroize(); + } +} + +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl ZeroizeOnDrop for BufEncryptor {} + +#[inline(always)] +fn xor_set1(buf1: &mut [u8], buf2: &mut [u8]) { + for (a, b) in buf1.iter_mut().zip(buf2) { + let t = *a ^ *b; + *a = t; + *b = t; + } +} diff --git a/cfb-mode/src/decrypt.rs b/cfb-mode/src/decrypt.rs index 7e7c1d6..916372b 100644 --- a/cfb-mode/src/decrypt.rs +++ b/cfb-mode/src/decrypt.rs @@ -1,158 +1,95 @@ use cipher::{ + consts::U1, crypto_common::{InnerUser, IvSizeUser}, generic_array::{ArrayLength, GenericArray}, inout::InOut, AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt, - BlockDecryptMut, BlockEncryptMut, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocks, - ParBlocksSizeUser, Unsigned, + BlockDecryptMut, BlockEncryptMut, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, }; -use core::fmt; +use core::{fmt, marker::PhantomData}; #[cfg(feature = "zeroize")] use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; /// CFB mode decryptor. #[derive(Clone)] -pub struct Decryptor +pub struct Decryptor::BlockSize> where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { cipher: C, iv: Block, + _pd: PhantomData, } -/// CFB mode buffered decryptor. -#[derive(Clone)] -pub struct BufDecryptor +impl BlockSizeUser for Decryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { - cipher: C, - iv: Block, - pos: usize, -} - -impl BufDecryptor -where - C: BlockEncryptMut + BlockCipher, -{ - /// Decrypt a buffer in multiple parts. - pub fn decrypt(&mut self, mut data: &mut [u8]) { - let bs = C::BlockSize::to_usize(); - let n = data.len(); - - if n < bs - self.pos { - xor_set2(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_set2(left, &mut iv[self.pos..]); - self.cipher.encrypt_block_mut(&mut iv); - - let mut chunks = data.chunks_exact_mut(bs); - for chunk in &mut chunks { - xor_set2(chunk, iv.as_mut_slice()); - self.cipher.encrypt_block_mut(&mut iv); - } - - let rem = chunks.into_remainder(); - xor_set2(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, - } - } + type BlockSize = MBS; } -impl BlockSizeUser for Decryptor -where - C: BlockEncryptMut + BlockCipher, -{ - type BlockSize = C::BlockSize; -} - -impl BlockDecryptMut for Decryptor +impl BlockDecryptMut for Decryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { fn decrypt_with_backend_mut(&mut self, f: impl BlockClosure) { - let Self { cipher, iv } = self; - cipher.encrypt_with_backend_mut(Closure { iv, f }) + let Self { cipher, iv, _pd } = self; + cipher.encrypt_with_backend_mut(Closure { + iv, + f, + _pd: _pd.clone(), + }) } } -impl AsyncStreamCipher for Decryptor where C: BlockEncryptMut + BlockCipher {} - -impl InnerUser for Decryptor +impl AsyncStreamCipher for Decryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { - type Inner = C; } -impl InnerUser for BufDecryptor +impl InnerUser for Decryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { type Inner = C; } -impl IvSizeUser for Decryptor +impl IvSizeUser for Decryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { type IvSize = C::BlockSize; } -impl IvSizeUser for BufDecryptor -where - C: BlockEncryptMut + BlockCipher, -{ - type IvSize = C::BlockSize; -} - -impl InnerIvInit for Decryptor -where - C: BlockEncryptMut + BlockCipher, -{ - #[inline] - fn inner_iv_init(mut cipher: C, iv: &Iv) -> Self { - let mut iv = iv.clone(); - cipher.encrypt_block_mut(&mut iv); - Self { cipher, iv } - } -} - -impl InnerIvInit for BufDecryptor +impl InnerIvInit for Decryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { #[inline] fn inner_iv_init(mut cipher: C, iv: &Iv) -> Self { let mut iv = iv.clone(); cipher.encrypt_block_mut(&mut iv); - Self { cipher, iv, pos: 0 } + Self { + cipher, + iv, + _pd: PhantomData, + } } } -impl IvState for Decryptor +impl IvState for Decryptor where C: BlockEncryptMut + BlockDecrypt + BlockCipher, + MBS: ArrayLength, { #[inline] fn iv_state(&self) -> Iv { @@ -162,9 +99,10 @@ where } } -impl AlgorithmName for Decryptor +impl AlgorithmName for Decryptor where C: BlockEncryptMut + BlockCipher + AlgorithmName, + MBS: ArrayLength, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb::Decryptor<")?; @@ -173,20 +111,10 @@ where } } -impl AlgorithmName for BufDecryptor -where - C: BlockEncryptMut + 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 +impl fmt::Debug for Decryptor where C: BlockEncryptMut + BlockCipher + AlgorithmName, + MBS: ArrayLength, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb::Decryptor<")?; @@ -195,20 +123,13 @@ where } } -impl fmt::Debug for BufDecryptor -where - C: BlockEncryptMut + 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 { +impl Drop for Decryptor +where + C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, +{ fn drop(&mut self) { self.iv.zeroize(); } @@ -216,107 +137,123 @@ impl Drop for Decryptor { #[cfg(feature = "zeroize")] #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for BufDecryptor { - fn drop(&mut self) { - self.iv.zeroize(); - } +impl ZeroizeOnDrop for Decryptor +where + C: BlockEncryptMut + BlockCipher + ZeroizeOnDrop, + MBS: ArrayLength, +{ } -#[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> +struct Closure<'a, CBS, MBS, BC> where - BS: ArrayLength, - BC: BlockClosure, + CBS: ArrayLength, + MBS: ArrayLength, + BC: BlockClosure, { - iv: &'a mut GenericArray, + iv: &'a mut GenericArray, f: BC, + _pd: PhantomData, } -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> +impl<'a, CBS, MBS, BC> BlockSizeUser for Closure<'a, CBS, MBS, BC> where - BS: ArrayLength, - BC: BlockClosure, + CBS: ArrayLength, + MBS: ArrayLength, + BC: BlockClosure, { - type BlockSize = BS; + type BlockSize = CBS; } -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> +impl<'a, CBS, MBS, BC> BlockClosure for Closure<'a, CBS, MBS, BC> where - BS: ArrayLength, - BC: BlockClosure, + CBS: ArrayLength, + MBS: ArrayLength, + BC: BlockClosure, { #[inline(always)] fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); + let Self { iv, f, _pd } = self; + f.call(&mut Backend { iv, backend, _pd }); } } -struct Backend<'a, BS, BK> +struct Backend<'a, CBS, MBS, BK> where - BS: ArrayLength, - BK: BlockBackend, + CBS: ArrayLength, + MBS: ArrayLength, + BK: BlockBackend, { - iv: &'a mut GenericArray, + iv: &'a mut GenericArray, backend: &'a mut BK, + _pd: PhantomData, } -impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> +impl<'a, CBS, MBS, BK> BlockSizeUser for Backend<'a, CBS, MBS, BK> where - BS: ArrayLength, - BK: BlockBackend, + CBS: ArrayLength, + MBS: ArrayLength, + BK: BlockBackend, { - type BlockSize = BS; + type BlockSize = MBS; } -impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> +impl<'a, CBS, MBS, BK> ParBlocksSizeUser for Backend<'a, CBS, MBS, BK> where - BS: ArrayLength, - BK: BlockBackend, + CBS: ArrayLength, + MBS: ArrayLength, + BK: BlockBackend, { - type ParBlocksSize = BK::ParBlocksSize; + // It's possible to implement parallel decryption, but currently + // `ParBlocksSize` is tied to block size. Since cipher block size + // and method block size in general can be different, we can not + // write `type ParBlocksSize = BK::ParBlocksSize`. + type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, CBS, MBS, BK> BlockBackend for Backend<'a, CBS, MBS, BK> where - BS: ArrayLength, - BK: BlockBackend, + CBS: ArrayLength, + MBS: ArrayLength, + BK: BlockBackend, { #[inline(always)] fn proc_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.iv = t; - } - - #[inline(always)] - fn proc_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); - - let n = t.len(); - blocks.get(0).xor_in2out(self.iv); - for i in 1..n { - blocks.get(i).xor_in2out(&t[i - 1]) + let cbs = CBS::USIZE; + let mbs = MBS::USIZE; + if mbs == cbs { + let mut t = block.clone_in(); + block.xor_in2out(GenericArray::from_slice(&self.iv)); + let block = GenericArray::from_mut_slice(&mut t); + self.backend.proc_block(block.into()); + *self.iv = block.clone(); + } else { + let mut t = self.iv.clone(); + self.backend.proc_block((&mut t).into()); + let ct = block.clone_in(); + block.xor_in2out(GenericArray::from_slice(&t[..mbs])); + + let mid = cbs - mbs; + for i in 0..mid { + self.iv[i] = self.iv[i + 1]; + } + self.iv[mid..].copy_from_slice(&ct); } - *self.iv = t[n - 1].clone(); } -} -#[inline(always)] -fn xor_set2(buf1: &mut [u8], buf2: &mut [u8]) { - for (a, b) in buf1.iter_mut().zip(buf2) { - let t = *a; - *a ^= *b; - *b = t; - } + // See comment in `ParBlocksSizeUser` impl + /* + #[inline(always)] + fn proc_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); + + // let n = t.len(); + // blocks.get(0).xor_in2out(self.iv); + // for i in 1..n { + // blocks.get(i).xor_in2out(&t[i - 1]) + // } + // *self.iv = t[n - 1].clone(); + } + */ } diff --git a/cfb-mode/src/encrypt.rs b/cfb-mode/src/encrypt.rs index cde30b8..8e52ac9 100644 --- a/cfb-mode/src/encrypt.rs +++ b/cfb-mode/src/encrypt.rs @@ -4,156 +4,92 @@ use cipher::{ generic_array::{ArrayLength, GenericArray}, inout::InOut, AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt, - BlockEncryptMut, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, Unsigned, + BlockEncryptMut, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, }; -use core::fmt; +use core::{fmt, marker::PhantomData}; #[cfg(feature = "zeroize")] use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; /// CFB mode encryptor. #[derive(Clone)] -pub struct Encryptor +pub struct Encryptor::BlockSize> where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { cipher: C, iv: Block, + _pd: PhantomData, } -/// CFB mode buffered encryptor. -#[derive(Clone)] -pub struct BufEncryptor -where - C: BlockEncryptMut + BlockCipher, -{ - cipher: C, - iv: Block, - pos: usize, -} - -impl BufEncryptor -where - C: BlockEncryptMut + 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; - } - - 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(&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(&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 BlockSizeUser for Encryptor +impl BlockSizeUser for Encryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { - type BlockSize = C::BlockSize; + type BlockSize = MBS; } -impl BlockEncryptMut for Encryptor +impl BlockEncryptMut for Encryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { fn encrypt_with_backend_mut(&mut self, f: impl BlockClosure) { - let Self { cipher, iv } = self; - cipher.encrypt_with_backend_mut(Closure { iv, f }) + let Self { cipher, iv, _pd } = self; + cipher.encrypt_with_backend_mut(Closure { + iv, + f, + _pd: _pd.clone(), + }) } } -impl AsyncStreamCipher for Encryptor where C: BlockEncryptMut + BlockCipher {} - -impl InnerUser for Encryptor +impl AsyncStreamCipher for Encryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { - type Inner = C; } -impl InnerUser for BufEncryptor +impl InnerUser for Encryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { type Inner = C; } -impl IvSizeUser for Encryptor +impl IvSizeUser for Encryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { type IvSize = C::BlockSize; } -impl IvSizeUser for BufEncryptor -where - C: BlockEncryptMut + BlockCipher, -{ - type IvSize = C::BlockSize; -} - -impl InnerIvInit for Encryptor -where - C: BlockEncryptMut + BlockCipher, -{ - #[inline] - fn inner_iv_init(mut cipher: C, iv: &Iv) -> Self { - let mut iv = iv.clone(); - cipher.encrypt_block_mut(&mut iv); - Self { cipher, iv } - } -} - -impl InnerIvInit for BufEncryptor +impl InnerIvInit for Encryptor where C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, { #[inline] fn inner_iv_init(mut cipher: C, iv: &Iv) -> Self { let mut iv = iv.clone(); cipher.encrypt_block_mut(&mut iv); - Self { cipher, iv, pos: 0 } + Self { + cipher, + iv, + _pd: PhantomData, + } } } -impl IvState for Encryptor +impl IvState for Encryptor where C: BlockEncryptMut + BlockDecrypt + BlockCipher, + MBS: ArrayLength, { #[inline] fn iv_state(&self) -> Iv { @@ -163,20 +99,10 @@ where } } -impl AlgorithmName for BufEncryptor -where - C: BlockEncryptMut + 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 +impl AlgorithmName for Encryptor where C: BlockEncryptMut + BlockCipher + AlgorithmName, + MBS: ArrayLength, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb::Encryptor<")?; @@ -185,9 +111,10 @@ where } } -impl fmt::Debug for Encryptor +impl fmt::Debug for Encryptor where C: BlockEncryptMut + BlockCipher + AlgorithmName, + MBS: ArrayLength, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("cfb::Encryptor<")?; @@ -196,20 +123,13 @@ where } } -impl fmt::Debug for BufEncryptor -where - C: BlockEncryptMut + 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 { +impl Drop for Encryptor +where + C: BlockEncryptMut + BlockCipher, + MBS: ArrayLength, +{ fn drop(&mut self) { self.iv.zeroize(); } @@ -217,93 +137,102 @@ impl Drop for Encryptor { #[cfg(feature = "zeroize")] #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl Drop for BufEncryptor { - fn drop(&mut self) { - self.iv.zeroize(); - } +impl ZeroizeOnDrop for Encryptor +where + C: BlockEncryptMut + BlockCipher + ZeroizeOnDrop, + MBS: ArrayLength, +{ } -#[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> +struct Closure<'a, CBS, MBS, BC> where - BS: ArrayLength, - BC: BlockClosure, + CBS: ArrayLength, + MBS: ArrayLength, + BC: BlockClosure, { - iv: &'a mut GenericArray, + iv: &'a mut GenericArray, f: BC, + _pd: PhantomData, } -impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC> +impl<'a, CBS, MBS, BC> BlockSizeUser for Closure<'a, CBS, MBS, BC> where - BS: ArrayLength, - BC: BlockClosure, + CBS: ArrayLength, + MBS: ArrayLength, + BC: BlockClosure, { - type BlockSize = BS; + type BlockSize = CBS; } -impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC> +impl<'a, CBS, MBS, BC> BlockClosure for Closure<'a, CBS, MBS, BC> where - BS: ArrayLength, - BC: BlockClosure, + CBS: ArrayLength, + MBS: ArrayLength, + BC: BlockClosure, { #[inline(always)] fn call>(self, backend: &mut B) { - let Self { iv, f } = self; - f.call(&mut Backend { iv, backend }); + let Self { iv, f, _pd } = self; + f.call(&mut Backend { iv, backend, _pd }); } } -struct Backend<'a, BS, BK> +struct Backend<'a, CBS, MBS, BK> where - BS: ArrayLength, - BK: BlockBackend, + CBS: ArrayLength, + MBS: ArrayLength, + BK: BlockBackend, { - iv: &'a mut GenericArray, + iv: &'a mut GenericArray, backend: &'a mut BK, + _pd: PhantomData, } -impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK> +impl<'a, CBS, MBS, BK> BlockSizeUser for Backend<'a, CBS, MBS, BK> where - BS: ArrayLength, - BK: BlockBackend, + CBS: ArrayLength, + MBS: ArrayLength, + BK: BlockBackend, { - type BlockSize = BS; + type BlockSize = MBS; } -impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK> +impl<'a, CBS, MBS, BK> ParBlocksSizeUser for Backend<'a, CBS, MBS, BK> where - BS: ArrayLength, - BK: BlockBackend, + CBS: ArrayLength, + MBS: ArrayLength, + BK: BlockBackend, { type ParBlocksSize = U1; } -impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK> +impl<'a, CBS, MBS, BK> BlockBackend for Backend<'a, CBS, MBS, BK> where - BS: ArrayLength, - BK: BlockBackend, + CBS: ArrayLength, + MBS: ArrayLength, + BK: BlockBackend, { #[inline(always)] fn proc_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.iv = t; - } -} - -#[inline(always)] -fn xor_set1(buf1: &mut [u8], buf2: &mut [u8]) { - for (a, b) in buf1.iter_mut().zip(buf2) { - let t = *a ^ *b; - *a = t; - *b = t; + let cbs = CBS::USIZE; + let mbs = MBS::USIZE; + if mbs == cbs { + block.xor_in2out(GenericArray::from_slice(self.iv)); + let mut t = block.get_out().clone(); + let block = GenericArray::from_mut_slice(&mut t); + self.backend.proc_block(block.into()); + self.iv.copy_from_slice(&t); + } else { + let mut t = self.iv.clone(); + self.backend.proc_block((&mut t).into()); + block.xor_in2out(GenericArray::from_slice(&t[..mbs])); + + let ct = block.get_out(); + let mid = cbs - mbs; + for i in 0..mid { + self.iv[i] = self.iv[i + mbs]; + } + self.iv[mid..].copy_from_slice(&ct); + } } } diff --git a/cfb-mode/src/lib.rs b/cfb-mode/src/lib.rs index 5291081..b5f938c 100644 --- a/cfb-mode/src/lib.rs +++ b/cfb-mode/src/lib.rs @@ -59,9 +59,14 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![warn(missing_docs, rust_2018_idioms)] +pub use cipher; + +mod buf_decrypt; +mod buf_encrypt; mod decrypt; mod encrypt; -pub use cipher; -pub use decrypt::{BufDecryptor, Decryptor}; -pub use encrypt::{BufEncryptor, Encryptor}; +pub use buf_decrypt::BufDecryptor; +pub use buf_encrypt::BufEncryptor; +pub use decrypt::Decryptor; +pub use encrypt::Encryptor; From 84676628ca0efe1fd85f031da009b77f034e4e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 6 Jan 2023 23:18:15 +0300 Subject: [PATCH 2/4] clippy --- cfb-mode/src/decrypt.rs | 8 ++------ cfb-mode/src/encrypt.rs | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/cfb-mode/src/decrypt.rs b/cfb-mode/src/decrypt.rs index 916372b..3bf8b76 100644 --- a/cfb-mode/src/decrypt.rs +++ b/cfb-mode/src/decrypt.rs @@ -38,11 +38,7 @@ where { fn decrypt_with_backend_mut(&mut self, f: impl BlockClosure) { let Self { cipher, iv, _pd } = self; - cipher.encrypt_with_backend_mut(Closure { - iv, - f, - _pd: _pd.clone(), - }) + cipher.encrypt_with_backend_mut(Closure { iv, f, _pd: *_pd }) } } @@ -222,7 +218,7 @@ where let mbs = MBS::USIZE; if mbs == cbs { let mut t = block.clone_in(); - block.xor_in2out(GenericArray::from_slice(&self.iv)); + block.xor_in2out(GenericArray::from_slice(self.iv)); let block = GenericArray::from_mut_slice(&mut t); self.backend.proc_block(block.into()); *self.iv = block.clone(); diff --git a/cfb-mode/src/encrypt.rs b/cfb-mode/src/encrypt.rs index 8e52ac9..6b8758b 100644 --- a/cfb-mode/src/encrypt.rs +++ b/cfb-mode/src/encrypt.rs @@ -38,11 +38,7 @@ where { fn encrypt_with_backend_mut(&mut self, f: impl BlockClosure) { let Self { cipher, iv, _pd } = self; - cipher.encrypt_with_backend_mut(Closure { - iv, - f, - _pd: _pd.clone(), - }) + cipher.encrypt_with_backend_mut(Closure { iv, f, _pd: *_pd }) } } @@ -232,7 +228,7 @@ where for i in 0..mid { self.iv[i] = self.iv[i + mbs]; } - self.iv[mid..].copy_from_slice(&ct); + self.iv[mid..].copy_from_slice(ct); } } } From 7703ca10f033cc210c55e0450d00b3926a6f45b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sat, 7 Jan 2023 15:04:49 +0300 Subject: [PATCH 3/4] rework impl. add tests and benches --- cfb-mode/benches/aes128.rs | 14 +++- cfb-mode/src/decrypt.rs | 41 ++++----- cfb-mode/src/encrypt.rs | 40 +++------ cfb-mode/src/lib.rs | 2 +- cfb-mode/tests/aes.rs | 78 +++++++++++++++--- cfb-mode/tests/data/cfb8_aes128.blb | Bin 0 -> 941 bytes cfb-mode/tests/data/cfb8_aes192.blb | Bin 0 -> 1101 bytes cfb-mode/tests/data/cfb8_aes256.blb | Bin 0 -> 1261 bytes .../tests/data/{aes128.blb => cfb_aes128.blb} | Bin .../tests/data/{aes192.blb => cfb_aes192.blb} | Bin .../tests/data/{aes256.blb => cfb_aes256.blb} | Bin 11 files changed, 106 insertions(+), 69 deletions(-) create mode 100644 cfb-mode/tests/data/cfb8_aes128.blb create mode 100644 cfb-mode/tests/data/cfb8_aes192.blb create mode 100644 cfb-mode/tests/data/cfb8_aes256.blb rename cfb-mode/tests/data/{aes128.blb => cfb_aes128.blb} (100%) rename cfb-mode/tests/data/{aes192.blb => cfb_aes192.blb} (100%) rename cfb-mode/tests/data/{aes256.blb => cfb_aes256.blb} (100%) diff --git a/cfb-mode/benches/aes128.rs b/cfb-mode/benches/aes128.rs index 1d5c9df..f53923a 100644 --- a/cfb-mode/benches/aes128.rs +++ b/cfb-mode/benches/aes128.rs @@ -1,7 +1,7 @@ #![feature(test)] extern crate test; -use aes::Aes128; +use aes::{cipher::consts::U1, Aes128}; cipher::block_encryptor_bench!( KeyIv: cfb_mode::Encryptor, @@ -14,3 +14,15 @@ cipher::block_decryptor_bench!( cfb_aes128_decrypt_block, cfb_aes128_decrypt_blocks, ); + +cipher::block_encryptor_bench!( + KeyIv: cfb_mode::Encryptor, + cfb8_aes128_encrypt_block, + cfb8_aes128_encrypt_blocks, +); + +cipher::block_decryptor_bench!( + KeyIv: cfb_mode::Decryptor, + cfb8_aes128_decrypt_block, + cfb8_aes128_decrypt_blocks, +); diff --git a/cfb-mode/src/decrypt.rs b/cfb-mode/src/decrypt.rs index 3bf8b76..1076c94 100644 --- a/cfb-mode/src/decrypt.rs +++ b/cfb-mode/src/decrypt.rs @@ -3,7 +3,7 @@ use cipher::{ crypto_common::{InnerUser, IvSizeUser}, generic_array::{ArrayLength, GenericArray}, inout::InOut, - AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt, + AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockClosure, BlockDecryptMut, BlockEncryptMut, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, }; use core::{fmt, marker::PhantomData}; @@ -71,12 +71,10 @@ where MBS: ArrayLength, { #[inline] - fn inner_iv_init(mut cipher: C, iv: &Iv) -> Self { - let mut iv = iv.clone(); - cipher.encrypt_block_mut(&mut iv); + fn inner_iv_init(cipher: C, iv: &Iv) -> Self { Self { cipher, - iv, + iv: iv.clone(), _pd: PhantomData, } } @@ -84,14 +82,12 @@ where impl IvState for Decryptor where - C: BlockEncryptMut + BlockDecrypt + BlockCipher, + C: BlockEncryptMut + BlockCipher, MBS: ArrayLength, { #[inline] fn iv_state(&self) -> Iv { - let mut res = self.iv.clone(); - self.cipher.decrypt_block(&mut res); - res + self.iv.clone() } } @@ -216,24 +212,15 @@ where fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { let cbs = CBS::USIZE; let mbs = MBS::USIZE; - if mbs == cbs { - let mut t = block.clone_in(); - block.xor_in2out(GenericArray::from_slice(self.iv)); - let block = GenericArray::from_mut_slice(&mut t); - self.backend.proc_block(block.into()); - *self.iv = block.clone(); - } else { - let mut t = self.iv.clone(); - self.backend.proc_block((&mut t).into()); - let ct = block.clone_in(); - block.xor_in2out(GenericArray::from_slice(&t[..mbs])); - - let mid = cbs - mbs; - for i in 0..mid { - self.iv[i] = self.iv[i + 1]; - } - self.iv[mid..].copy_from_slice(&ct); - } + + let mut iv_cpy = self.iv.clone(); + + let mid = cbs - mbs; + self.iv[..mid].copy_from_slice(&iv_cpy[mbs..]); + self.iv[mid..].copy_from_slice(block.get_in()); + + self.backend.proc_block((&mut iv_cpy).into()); + block.xor_in2out(GenericArray::from_slice(&iv_cpy[..mbs])); } // See comment in `ParBlocksSizeUser` impl diff --git a/cfb-mode/src/encrypt.rs b/cfb-mode/src/encrypt.rs index 6b8758b..8c04e5b 100644 --- a/cfb-mode/src/encrypt.rs +++ b/cfb-mode/src/encrypt.rs @@ -3,7 +3,7 @@ use cipher::{ crypto_common::{InnerUser, IvSizeUser}, generic_array::{ArrayLength, GenericArray}, inout::InOut, - AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt, + AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockClosure, BlockEncryptMut, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocksSizeUser, }; use core::{fmt, marker::PhantomData}; @@ -71,12 +71,10 @@ where MBS: ArrayLength, { #[inline] - fn inner_iv_init(mut cipher: C, iv: &Iv) -> Self { - let mut iv = iv.clone(); - cipher.encrypt_block_mut(&mut iv); + fn inner_iv_init(cipher: C, iv: &Iv) -> Self { Self { cipher, - iv, + iv: iv.clone(), _pd: PhantomData, } } @@ -84,14 +82,12 @@ where impl IvState for Encryptor where - C: BlockEncryptMut + BlockDecrypt + BlockCipher, + C: BlockEncryptMut + BlockCipher, MBS: ArrayLength, { #[inline] fn iv_state(&self) -> Iv { - let mut res = self.iv.clone(); - self.cipher.decrypt_block(&mut res); - res + self.iv.clone() } } @@ -212,23 +208,13 @@ where fn proc_block(&mut self, mut block: InOut<'_, '_, Block>) { let cbs = CBS::USIZE; let mbs = MBS::USIZE; - if mbs == cbs { - block.xor_in2out(GenericArray::from_slice(self.iv)); - let mut t = block.get_out().clone(); - let block = GenericArray::from_mut_slice(&mut t); - self.backend.proc_block(block.into()); - self.iv.copy_from_slice(&t); - } else { - let mut t = self.iv.clone(); - self.backend.proc_block((&mut t).into()); - block.xor_in2out(GenericArray::from_slice(&t[..mbs])); - - let ct = block.get_out(); - let mid = cbs - mbs; - for i in 0..mid { - self.iv[i] = self.iv[i + mbs]; - } - self.iv[mid..].copy_from_slice(ct); - } + + let iv_cpy = self.iv.clone(); + self.backend.proc_block((&mut *self.iv).into()); + block.xor_in2out(GenericArray::from_slice(&self.iv[..mbs])); + + let mid = cbs - mbs; + self.iv[..mid].copy_from_slice(&iv_cpy[mbs..]); + self.iv[mid..].copy_from_slice(block.get_out()); } } diff --git a/cfb-mode/src/lib.rs b/cfb-mode/src/lib.rs index b5f938c..27b526a 100644 --- a/cfb-mode/src/lib.rs +++ b/cfb-mode/src/lib.rs @@ -50,7 +50,7 @@ //! //! [1]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_(CFB) -#![no_std] +// #![no_std] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" diff --git a/cfb-mode/tests/aes.rs b/cfb-mode/tests/aes.rs index 188ea47..7a1d675 100644 --- a/cfb-mode/tests/aes.rs +++ b/cfb-mode/tests/aes.rs @@ -1,6 +1,6 @@ use aes::*; use cfb_mode::{BufDecryptor, BufEncryptor, Decryptor, Encryptor}; -use cipher::{block_mode_dec_test, block_mode_enc_test, iv_state_test, KeyInit}; +use cipher::{block_mode_dec_test, block_mode_enc_test, consts::U1, iv_state_test, KeyInit}; iv_state_test!(aes128_cfb_enc_iv_state, Encryptor, encrypt); iv_state_test!(aes128_cfb_dec_iv_state, Decryptor, decrypt); @@ -9,20 +9,40 @@ iv_state_test!(aes192_cfb_dec_iv_state, Decryptor, decrypt); iv_state_test!(aes256_cfb_enc_iv_state, Encryptor, encrypt); iv_state_test!(aes256_cfb_dec_iv_state, Decryptor, decrypt); +iv_state_test!(aes128_cfb8_enc_iv_state, Encryptor, encrypt); +iv_state_test!(aes128_cfb8_dec_iv_state, Decryptor, decrypt); +iv_state_test!(aes192_cfb8_enc_iv_state, Encryptor, encrypt); +iv_state_test!(aes192_cfb8_dec_iv_state, Decryptor, decrypt); +iv_state_test!(aes256_cfb8_enc_iv_state, Encryptor, encrypt); +iv_state_test!(aes256_cfb8_dec_iv_state, Decryptor, decrypt); + // Test vectors from CVAP "AES Multiblock Message Test (MMT) Sample Vectors": // -block_mode_enc_test!(aes128_cfb_enc_test, "aes128", Encryptor); -block_mode_dec_test!(aes128_cfb_dec_test, "aes128", Decryptor); -block_mode_enc_test!(aes128enc_cfb_enc_test, "aes128", Encryptor); -block_mode_dec_test!(aes128enc_cfb_dec_test, "aes128", Decryptor); -block_mode_enc_test!(aes192_cfb_enc_test, "aes192", Encryptor); -block_mode_dec_test!(aes192_cfb_dec_test, "aes192", Decryptor); -block_mode_enc_test!(aes192enc_cfb_enc_test, "aes192", Encryptor); -block_mode_dec_test!(aes192dec_cfb_dec_test, "aes192", Decryptor); -block_mode_enc_test!(aes256_cfb_enc_test, "aes256", Encryptor); -block_mode_dec_test!(aes256_cfb_dec_test, "aes256", Decryptor); -block_mode_enc_test!(aes256enc_cfb_enc_test, "aes256", Encryptor); -block_mode_dec_test!(aes256dec_cfb_dec_test, "aes256", Decryptor); +block_mode_enc_test!(aes128_cfb_enc_test, "cfb_aes128", Encryptor); +block_mode_dec_test!(aes128_cfb_dec_test, "cfb_aes128", Decryptor); +block_mode_enc_test!(aes128enc_cfb_enc_test, "cfb_aes128", Encryptor); +block_mode_dec_test!(aes128enc_cfb_dec_test, "cfb_aes128", Decryptor); +block_mode_enc_test!(aes192_cfb_enc_test, "cfb_aes192", Encryptor); +block_mode_dec_test!(aes192_cfb_dec_test, "cfb_aes192", Decryptor); +block_mode_enc_test!(aes192enc_cfb_enc_test, "cfb_aes192", Encryptor); +block_mode_dec_test!(aes192dec_cfb_dec_test, "cfb_aes192", Decryptor); +block_mode_enc_test!(aes256_cfb_enc_test, "cfb_aes256", Encryptor); +block_mode_dec_test!(aes256_cfb_dec_test, "cfb_aes256", Decryptor); +block_mode_enc_test!(aes256enc_cfb_enc_test, "cfb_aes256", Encryptor); +block_mode_dec_test!(aes256dec_cfb_dec_test, "cfb_aes256", Decryptor); + +block_mode_enc_test!(aes128_cfb8_enc_test, "cfb8_aes128", Encryptor); +block_mode_dec_test!(aes128_cfb8_dec_test, "cfb8_aes128", Decryptor); +block_mode_enc_test!(aes128enc_cfb8_enc_test, "cfb8_aes128", Encryptor); +block_mode_dec_test!(aes128enc_cfb8_dec_test, "cfb8_aes128", Decryptor); +block_mode_enc_test!(aes192_cfb8_enc_test, "cfb8_aes192", Encryptor); +block_mode_dec_test!(aes192_cfb8_dec_test, "cfb8_aes192", Decryptor); +block_mode_enc_test!(aes192enc_cfb8_enc_test, "cfb8_aes192", Encryptor); +block_mode_dec_test!(aes192dec_cfb8_dec_test, "cfb8_aes192", Decryptor); +block_mode_enc_test!(aes256_cfb8_enc_test, "cfb8_aes256", Encryptor); +block_mode_dec_test!(aes256_cfb8_dec_test, "cfb8_aes256", Decryptor); +block_mode_enc_test!(aes256enc_cfb8_enc_test, "cfb8_aes256", Encryptor); +block_mode_dec_test!(aes256dec_cfb8_dec_test, "cfb8_aes256", Decryptor); /// Test methods from the `AsyncStreamCipher` trait. #[test] @@ -54,6 +74,38 @@ fn aes128_cfb_async_test() { } } +/* +/// Test methods from the `AsyncStreamCipher` trait. +#[test] +fn aes128_cfb8_async_test() { + use cipher::{AsyncStreamCipher, KeyIvInit}; + + type Enc = Encryptor; + type Dec = Decryptor; + + let key = [42; 16]; + let iv = [24; 16]; + let mut pt = [0u8; 101]; + for (i, b) in pt.iter_mut().enumerate() { + *b = (i % 11) as u8; + } + let enc = Enc::new_from_slices(&key, &iv).unwrap(); + let mut ct = pt.clone(); + enc.encrypt(&mut ct); + for i in 1..100 { + let enc = Enc::new_from_slices(&key, &iv).unwrap(); + let mut t = pt.clone(); + let t = &mut t[..i]; + enc.encrypt(t); + assert_eq!(t, &ct[..i]); + + let dec = Dec::new_from_slices(&key, &iv).unwrap(); + dec.decrypt(t); + assert_eq!(t, &pt[..i]); + } +} +*/ + #[test] fn aes128_cfb_buffered_test() { use cipher::{AsyncStreamCipher, KeyIvInit}; diff --git a/cfb-mode/tests/data/cfb8_aes128.blb b/cfb-mode/tests/data/cfb8_aes128.blb new file mode 100644 index 0000000000000000000000000000000000000000..81b6cafb9722ddead4ab6ecf0158d50b7e33da9b GIT binary patch literal 941 zcmV;e15*3|AjN%Yor&Lk`|okUfTpnu!yx>!yi5RVhe$bid1@-+#4ZA10wf>}k3GZf z?qJ(xi@ATVM*E{6H3=}0aa_OB6 z&%#IJIy)d{2bg>{ND0fR7-OBy7*R(cRV)x13w#WrL$4)-Q^l%LKoy6K+=9OlhcZwV zFUF<2AkZDDT`VeL+6L-)&$?O6Fd+G(ldX_}Pp>8}I$Ir=SuPS+!J`gH7HyV566vVJ zw|4E*o;@HsZ;@FhKc>#|pmoan&R7>955hKLx7+tPC-BGKG906B6o>EYja8o0Hg_l# zj+{_JRut7h&JiF3?fwWQP`z5n-S$sHpj3Y#Qmok8wk(((ppH?KoWPB%0to^kAUMx= zXHXU{++)MF+v5?dpCFj~y(oxs#19!Jv2M!j6=4MHBm_u!Ajt(hhr{J-#pNs0A7w@P zks!GFWDN-;+7te6xO)Nc&!7g82}uU7w$dQ!XL0rN3W@HA5@FKOjvhuJZiYZUGdX5e zkb2;5@scJl2s?it90-HTvhyI4trP6F3*H;EvrOQ4XJ;!Q`C33=xcCk~gPlw~qdl#Z z3KzM#;cW^@_daDSAnRAS-3M-ayED|k#MkVyejrg3S(l(^+|u9{#c?#n`ce$an4hHR z7!0uL%ks)bAaJY1i?O~*0fX@VJ@sLg{~+Q~@p%_Zaqb>SinHAy1cMG#1=hu;no67mDQ)B?6y8QKy7 znJSoKdBbR4AY+-q+y;xIP?$wxkE!h%mLL&V!gg$iw^ZLqTj||cQQs8)|4uF>SgqeG PR20d=gz2ll=KB%;LFu|1 literal 0 HcmV?d00001 diff --git a/cfb-mode/tests/data/cfb8_aes192.blb b/cfb-mode/tests/data/cfb8_aes192.blb new file mode 100644 index 0000000000000000000000000000000000000000..f7eb86dd623273a6adc53e6b133155f3c8702d2a GIT binary patch literal 1101 zcmV-T1hV@8FfyUA(;t2K^CT2E@P?Feh<^ zq@+NGnIQEe#MOBGTkX?2?u{`O45RWdGZNn79$cGS27ajg`2u2wexm|^uGD|yes|2HK~?e&sMYhmNy4sFifL&EN5 z4t$ArSSTVOFm8Cv?B~(4qri;t-gArYGt0a8jhpn6EFeq16|w0`dzU2&AvV~6PDT*U z+Coxzargod*)RBzMX`~8FcZm!WprVe^ZM zCcYmnWyKO33S-waWUD-i5>$nReqB5+EW|KVetY&|{Xit3Bw;@lu{MzR(8x!@;fZA+ zI)VAw)4^4+%B@{eD*LobbX>Fy}-phG-Lf}ZN3@NL03~zarqq} zchjY>^)nbtx_OfwCD7PlR~3J_Xk$Z`q^*%Z$UFkQ@>jfzEXnHSBCRM+M*CEZWc@MZlg!17L9Yr*nEycDTPD2+l6A+#gLpeA?{%o%E_@d04y`@{r{J2 z!XR3~#2 zr<86nU>^2oogm^5Iokjw>m*4V&|ngXaR>^n9a9nN3K`6oreZ+sbEjY@EQ9$MakHy? z7>5IH=IAhQtu6z18{Uvvg&t}enSN7yC3noWE1l_t*!#Bt>6{8@D{XL+cOCuZq$I;!|i9FmndyX1KvyTp&)xYK~MN zT>g8CxktaG{Rj{paHXg#t@Y{<9wNTJzO2|CKx7kMXTZuD&hs`6lM4LTCdIHwVWylL zYDm4|+VT%OA0ShAp;XoRNEn}*rF%wf7P1nfY^CZrDl#tb5-|k%XUK{sn&Gc(5Yk(W{VG4?*X`aaSJe&)%aB)Y}LNT z*5Umluf;>S_zgda0+<4CK(@66=(h$_bLuh8RGw1pr^}Z89kEW`th_=1g{w%nM<9m| z%|)>!7z5p}i>(!)CD#Nsas(IDKx)$vUKRUWbSw1!9=Pd@Y#;unQxJTF_Ove1BPt8L zAs`o1Oo_zm<=&?1H9g*Y79$4vK^g|BgdRY3k3XogvWfAZ)t++}zCgJI@Avg(%B)3j z`EoW64X1}7vJ*9~mM7v2uFx`atMU8UL`<)E`?6FnNSIJ*1*-mKspQq%AFov zNxL`s1RsdeS;O(w&L+p0^`6yAlklMC03e#KIJ$!_O9?wrL_l;=eIN{i2kzphs|<8O z49ybSK<))bAt?T*UXh<~Lu|2_@*;$NX^JR6S7+a7Ei=>3cOcTORpc0l2T_D$Q4*pr zz>^NI^QufF<5Ld*1D=V8dqhA8tG&!VxxsOLvHGKp%?OjP)!}X>mUMdckBwpL?fK0h zxh2TlnwwRmH!h~reIdc?5Vtn~P$-M`01)AJx|!-=FWEp=)C8!L`#V2bN~;)?k}$BA zWNJ63fnuM%l5q2h8eHli<&bMO^4WfGEwP(ydOYJ9668shyRiTC5AG7hTAGo1fSPzq zKKF;OW3q27O;fcXShzFbtswjQT2hW6hA Date: Sat, 7 Jan 2023 15:09:54 +0300 Subject: [PATCH 4/4] uncomment no_std --- cfb-mode/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfb-mode/src/lib.rs b/cfb-mode/src/lib.rs index 27b526a..b5f938c 100644 --- a/cfb-mode/src/lib.rs +++ b/cfb-mode/src/lib.rs @@ -50,7 +50,7 @@ //! //! [1]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_feedback_(CFB) -// #![no_std] +#![no_std] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"