From 6e2eab7df12263e9def61d37e2ab7d11dd2e378e 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: Wed, 31 Jul 2024 22:49:47 +0300 Subject: [PATCH 01/12] cipher: rework backend traits --- cipher/src/block.rs | 230 +++++------------------------------ cipher/src/block/backends.rs | 206 +++++++++++++++++++++++++++++++ cipher/src/block/ctx.rs | 120 ++++++++++++++++++ cipher/src/block/macros.rs | 79 ++++++++++++ 4 files changed, 434 insertions(+), 201 deletions(-) create mode 100644 cipher/src/block/backends.rs create mode 100644 cipher/src/block/ctx.rs create mode 100644 cipher/src/block/macros.rs diff --git a/cipher/src/block.rs b/cipher/src/block.rs index fd69bf570..4ff68f08b 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -10,10 +10,8 @@ //! [2]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation //! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm -use crate::{ParBlocks, ParBlocksSizeUser}; #[cfg(all(feature = "block-padding", feature = "alloc"))] use alloc::{vec, vec::Vec}; -use crypto_common::BlockSizes; #[cfg(feature = "block-padding")] use inout::{ block_padding::{Padding, UnpadError}, @@ -23,64 +21,20 @@ use inout::{InOut, InOutBuf, NotEqualError}; pub use crypto_common::{array::ArraySize, typenum::Unsigned, Block, BlockSizeUser}; -/// Marker trait for block ciphers. -pub trait BlockCipher: BlockSizeUser {} - -/// Trait implemented by block cipher encryption and decryption backends. -pub trait BlockBackend: ParBlocksSizeUser { - /// Process single inout block. - fn proc_block(&mut self, block: InOut<'_, '_, Block>); +mod backends; +mod ctx; +mod macros; - /// Process inout blocks in parallel. - #[inline(always)] - fn proc_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { - for i in 0..Self::ParBlocksSize::USIZE { - self.proc_block(blocks.get(i)); - } - } +pub use backends::*; +use ctx::{BlockCtx, BlocksCtx}; - /// Process buffer of inout blocks. Length of the buffer MUST be smaller - /// than `Self::ParBlocksSize`. - #[inline(always)] - fn proc_tail_blocks(&mut self, blocks: InOutBuf<'_, '_, Block>) { - assert!(blocks.len() < Self::ParBlocksSize::USIZE); - for block in blocks { - self.proc_block(block); - } - } - - /// Process single block in-place. - #[inline(always)] - fn proc_block_inplace(&mut self, block: &mut Block) { - self.proc_block(block.into()); - } - - /// Process blocks in parallel in-place. - #[inline(always)] - fn proc_par_blocks_inplace(&mut self, blocks: &mut ParBlocks) { - self.proc_par_blocks(blocks.into()); - } - - /// Process buffer of blocks in-place. Length of the buffer MUST be smaller - /// than `Self::ParBlocksSize`. - #[inline(always)] - fn proc_tail_blocks_inplace(&mut self, blocks: &mut [Block]) { - self.proc_tail_blocks(blocks.into()); - } -} - -/// Trait for [`BlockBackend`] users. -/// -/// This trait is used to define rank-2 closures. -pub trait BlockClosure: BlockSizeUser { - /// Execute closure with the provided block cipher backend. - fn call>(self, backend: &mut B); -} +/// Marker trait for block ciphers. +pub trait BlockCipher: BlockSizeUser {} /// Encrypt-only functionality for block ciphers. pub trait BlockCipherEncrypt: BlockSizeUser + Sized { /// Encrypt data using backend provided to the rank-2 closure. - fn encrypt_with_backend(&self, f: impl BlockClosure); + fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure); /// Encrypt single `inout` block. #[inline] @@ -178,7 +132,8 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized { #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] fn encrypt_padded_vec>(&self, msg: &[u8]) -> Vec { - let mut out = allocate_out_vec::(msg.len()); + let bs = Self::BlockSize::USIZE; + let mut out = vec![0; bs * (msg.len() / bs + 1)]; let len = self .encrypt_padded_b2b::

(msg, &mut out) .expect("enough space for encrypting is allocated") @@ -191,7 +146,7 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized { /// Decrypt-only functionality for block ciphers. pub trait BlockCipherDecrypt: BlockSizeUser { /// Decrypt data using backend provided to the rank-2 closure. - fn decrypt_with_backend(&self, f: impl BlockClosure); + fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure); /// Decrypt single `inout` block. #[inline] @@ -310,6 +265,20 @@ pub trait BlockCipherDecrypt: BlockSizeUser { } } +impl BlockCipher for &Alg {} + +impl BlockCipherEncrypt for &Alg { + fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure) { + Alg::encrypt_with_backend(self, f); + } +} + +impl BlockCipherDecrypt for &Alg { + fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure) { + Alg::decrypt_with_backend(self, f); + } +} + /// Encrypt-only functionality for block ciphers and modes with mutable access to `self`. /// /// The main use case for this trait is blocks modes, but it also can be used @@ -317,7 +286,7 @@ pub trait BlockCipherDecrypt: BlockSizeUser { /// underlying hardware peripheral. pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// Encrypt data using backend provided to the rank-2 closure. - fn encrypt_with_backend(&mut self, f: impl BlockClosure); + fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure); /// Encrypt single `inout` block. #[inline] @@ -415,7 +384,8 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] fn encrypt_padded_vec>(self, msg: &[u8]) -> Vec { - let mut out = allocate_out_vec::(msg.len()); + let bs = Self::BlockSize::USIZE; + let mut out = vec![0; bs * (msg.len() / bs + 1)]; let len = self .encrypt_padded_b2b::

(msg, &mut out) .expect("enough space for encrypting is allocated") @@ -432,7 +402,7 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// underlying hardware peripheral. pub trait BlockModeDecrypt: BlockSizeUser + Sized { /// Decrypt data using backend provided to the rank-2 closure. - fn decrypt_with_backend(&mut self, f: impl BlockClosure); + fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure); /// Decrypt single `inout` block. #[inline] @@ -550,145 +520,3 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { Ok(out) } } - -impl BlockCipher for &Alg {} - -impl BlockCipherEncrypt for &Alg { - fn encrypt_with_backend(&self, f: impl BlockClosure) { - Alg::encrypt_with_backend(self, f); - } -} - -impl BlockCipherDecrypt for &Alg { - fn decrypt_with_backend(&self, f: impl BlockClosure) { - Alg::decrypt_with_backend(self, f); - } -} - -/// Closure used in methods which operate over separate blocks. -struct BlockCtx<'inp, 'out, BS: BlockSizes> { - block: InOut<'inp, 'out, Block>, -} - -impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlockCtx<'inp, 'out, BS> { - type BlockSize = BS; -} - -impl<'inp, 'out, BS: BlockSizes> BlockClosure for BlockCtx<'inp, 'out, BS> { - #[inline(always)] - fn call>(self, backend: &mut B) { - backend.proc_block(self.block); - } -} - -/// Closure used in methods which operate over slice of blocks. -struct BlocksCtx<'inp, 'out, BS: BlockSizes> { - blocks: InOutBuf<'inp, 'out, Block>, -} - -impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlocksCtx<'inp, 'out, BS> { - type BlockSize = BS; -} - -impl<'inp, 'out, BS: BlockSizes> BlockClosure for BlocksCtx<'inp, 'out, BS> { - #[inline(always)] - fn call>(self, backend: &mut B) { - if B::ParBlocksSize::USIZE > 1 { - let (chunks, tail) = self.blocks.into_chunks(); - for chunk in chunks { - backend.proc_par_blocks(chunk); - } - backend.proc_tail_blocks(tail); - } else { - for block in self.blocks { - backend.proc_block(block); - } - } - } -} - -#[cfg(all(feature = "block-padding", feature = "alloc"))] -fn allocate_out_vec(len: usize) -> Vec { - let bs = BS::BlockSize::USIZE; - vec![0; bs * (len / bs + 1)] -} - -/// Implement simple block backend -#[macro_export] -macro_rules! impl_simple_block_encdec { - ( - <$($N:ident$(:$b0:ident$(+$b:ident)*)?),*> - $cipher:ident, $block_size:ty, $state:ident, $block:ident, - encrypt: $enc_block:block - decrypt: $dec_block:block - ) => { - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockSizeUser for $cipher<$($N),*> { - type BlockSize = $block_size; - } - - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherEncrypt for $cipher<$($N),*> { - fn encrypt_with_backend(&self, f: impl $crate::BlockClosure) { - struct EncBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for EncBack<'a, $($N),*> { - type BlockSize = $block_size; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for EncBack<'a, $($N),*> { - type ParBlocksSize = $crate::consts::U1; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockBackend for EncBack<'a, $($N),*> { - #[inline(always)] - fn proc_block( - &mut self, - mut $block: $crate::inout::InOut<'_, '_, $crate::Block> - ) { - let $state: &$cipher<$($N),*> = self.0; - $enc_block - } - } - - f.call(&mut EncBack(self)) - } - } - - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherDecrypt for $cipher<$($N),*> { - fn decrypt_with_backend(&self, f: impl $crate::BlockClosure) { - struct DecBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for DecBack<'a, $($N),*> { - type BlockSize = $block_size; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for DecBack<'a, $($N),*> { - type ParBlocksSize = $crate::consts::U1; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockBackend for DecBack<'a, $($N),*> { - #[inline(always)] - fn proc_block( - &mut self, - mut $block: $crate::inout::InOut<'_, '_, $crate::Block> - ) { - let $state: &$cipher<$($N),*> = self.0; - $dec_block - } - } - - f.call(&mut DecBack(self)) - } - } - }; - ( - $cipher:ident, $block_size:ty, $state:ident, $block:ident, - encrypt: $enc_block:block - decrypt: $dec_block:block - ) => { - $crate::impl_simple_block_encdec!( - <> $cipher, $block_size, $state, $block, - encrypt: $enc_block - decrypt: $dec_block - ); - }; -} diff --git a/cipher/src/block/backends.rs b/cipher/src/block/backends.rs new file mode 100644 index 000000000..e035b3993 --- /dev/null +++ b/cipher/src/block/backends.rs @@ -0,0 +1,206 @@ +use crypto_common::{typenum::Unsigned, Block, BlockSizeUser, ParBlocks, ParBlocksSizeUser}; +use inout::{InOut, InOutBuf}; + +/// Trait implemented by block cipher mode encryption backends. +pub trait BlockCipherEncBackend: ParBlocksSizeUser { + /// Encrypt single inout block. + fn encrypt_block(&self, block: InOut<'_, '_, Block>); + + /// Encrypt inout blocks in parallel. + #[inline(always)] + fn encrypt_par_blocks(&self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.encrypt_block(blocks.get(i)); + } + } + + /// Encrypt buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn encrypt_tail_blocks(&self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.encrypt_block(block); + } + } + + /// Encrypt single block in-place. + #[inline(always)] + fn encrypt_block_inplace(&self, block: &mut Block) { + self.encrypt_block(block.into()); + } + + /// Encrypt blocks in parallel in-place. + #[inline(always)] + fn encrypt_par_blocks_inplace(&self, blocks: &mut ParBlocks) { + self.encrypt_par_blocks(blocks.into()); + } + + /// Encrypt buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn encrypt_tail_blocks_inplace(&self, blocks: &mut [Block]) { + self.encrypt_tail_blocks(blocks.into()); + } +} + +/// Trait for [`BlockCipherEncBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockCipherEncClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &B); +} + +/// Trait implemented by block cipher decryption backends. +pub trait BlockCipherDecBackend: ParBlocksSizeUser { + /// Decrypt single inout block. + fn decrypt_block(&self, block: InOut<'_, '_, Block>); + + /// Decrypt inout blocks in parallel. + #[inline(always)] + fn decrypt_par_blocks(&self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.decrypt_block(blocks.get(i)); + } + } + + /// Decrypt buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn decrypt_tail_blocks(&self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.decrypt_block(block); + } + } + + /// Decrypt single block in-place. + #[inline(always)] + fn decrypt_block_inplace(&self, block: &mut Block) { + self.decrypt_block(block.into()); + } + + /// Decrypt blocks in parallel in-place. + #[inline(always)] + fn decrypt_par_blocks_inplace(&self, blocks: &mut ParBlocks) { + self.decrypt_par_blocks(blocks.into()); + } + + /// Decrypt buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn decrypt_tail_blocks_inplace(&self, blocks: &mut [Block]) { + self.decrypt_tail_blocks(blocks.into()); + } +} + +/// Trait for [`BlockCipherDecBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockCipherDecClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &B); +} + +/// Trait implemented by block cipher mode encryption backends. +pub trait BlockModeEncBackend: ParBlocksSizeUser { + /// Encrypt single inout block. + fn encrypt_block(&mut self, block: InOut<'_, '_, Block>); + + /// Encrypt inout blocks in parallel. + #[inline(always)] + fn encrypt_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.encrypt_block(blocks.get(i)); + } + } + + /// Encrypt buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn encrypt_tail_blocks(&mut self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.encrypt_block(block); + } + } + + /// Encrypt single block in-place. + #[inline(always)] + fn encrypt_block_inplace(&mut self, block: &mut Block) { + self.encrypt_block(block.into()); + } + + /// Encrypt blocks in parallel in-place. + #[inline(always)] + fn encrypt_par_blocks_inplace(&mut self, blocks: &mut ParBlocks) { + self.encrypt_par_blocks(blocks.into()); + } + + /// Encrypt buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn encrypt_tail_blocks_inplace(&mut self, blocks: &mut [Block]) { + self.encrypt_tail_blocks(blocks.into()); + } +} + +/// Trait for [`BlockModeEncBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockModeEncClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &mut B); +} + +/// Trait implemented by block cipher mode decryption backends. +pub trait BlockModeDecBackend: ParBlocksSizeUser { + /// Decrypt single inout block. + fn decrypt_block(&mut self, block: InOut<'_, '_, Block>); + + /// Decrypt inout blocks in parallel. + #[inline(always)] + fn decrypt_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.decrypt_block(blocks.get(i)); + } + } + + /// Decrypt buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn decrypt_tail_blocks(&mut self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.decrypt_block(block); + } + } + + /// Decrypt single block in-place. + #[inline(always)] + fn decrypt_block_inplace(&mut self, block: &mut Block) { + self.decrypt_block(block.into()); + } + + /// Decrypt blocks in parallel in-place. + #[inline(always)] + fn decrypt_par_blocks_inplace(&mut self, blocks: &mut ParBlocks) { + self.decrypt_par_blocks(blocks.into()); + } + + /// Decrypt buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn decrypt_tail_blocks_inplace(&mut self, blocks: &mut [Block]) { + self.decrypt_tail_blocks(blocks.into()); + } +} + +/// Trait for [`BlockModeDecBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockModeDecClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &mut B); +} diff --git a/cipher/src/block/ctx.rs b/cipher/src/block/ctx.rs new file mode 100644 index 000000000..7b0f04632 --- /dev/null +++ b/cipher/src/block/ctx.rs @@ -0,0 +1,120 @@ +use crypto_common::{typenum::Unsigned, Block, BlockSizeUser, BlockSizes}; +use inout::{InOut, InOutBuf}; + +use super::{ + BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherEncBackend, BlockCipherEncClosure, + BlockModeDecBackend, BlockModeDecClosure, BlockModeEncBackend, BlockModeEncClosure, +}; + +/// Closure used in methods which operate over separate blocks. +pub(super) struct BlockCtx<'inp, 'out, BS: BlockSizes> { + pub block: InOut<'inp, 'out, Block>, +} + +impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlockCtx<'inp, 'out, BS> { + type BlockSize = BS; +} + +impl<'inp, 'out, BS: BlockSizes> BlockCipherEncClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &B) { + backend.encrypt_block(self.block); + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockCipherDecClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &B) { + backend.decrypt_block(self.block); + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockModeEncClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + backend.encrypt_block(self.block); + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockModeDecClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + backend.decrypt_block(self.block); + } +} +/// Closure used in methods which operate over slice of blocks. +pub(super) struct BlocksCtx<'inp, 'out, BS: BlockSizes> { + pub blocks: InOutBuf<'inp, 'out, Block>, +} + +impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlocksCtx<'inp, 'out, BS> { + type BlockSize = BS; +} + +impl<'inp, 'out, BS: BlockSizes> BlockCipherEncClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.encrypt_par_blocks(chunk); + } + backend.encrypt_tail_blocks(tail); + } else { + for block in self.blocks { + backend.encrypt_block(block); + } + } + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockCipherDecClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.decrypt_par_blocks(chunk); + } + backend.decrypt_tail_blocks(tail); + } else { + for block in self.blocks { + backend.decrypt_block(block); + } + } + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockModeEncClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.encrypt_par_blocks(chunk); + } + backend.encrypt_tail_blocks(tail); + } else { + for block in self.blocks { + backend.encrypt_block(block); + } + } + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockModeDecClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.decrypt_par_blocks(chunk); + } + backend.decrypt_tail_blocks(tail); + } else { + for block in self.blocks { + backend.decrypt_block(block); + } + } + } +} diff --git a/cipher/src/block/macros.rs b/cipher/src/block/macros.rs new file mode 100644 index 000000000..17d6e0d4c --- /dev/null +++ b/cipher/src/block/macros.rs @@ -0,0 +1,79 @@ +/// Implement simple block backend +#[macro_export] +macro_rules! impl_simple_block_encdec { + ( + <$($N:ident$(:$b0:ident$(+$b:ident)*)?),*> + $cipher:ident, $block_size:ty, $state:ident, $block:ident, + encrypt: $enc_block:block + decrypt: $dec_block:block + ) => { + impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockSizeUser for $cipher<$($N),*> { + type BlockSize = $block_size; + } + + impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherEncrypt for $cipher<$($N),*> { + fn encrypt_with_backend(&self, f: impl $crate::BlockCipherEncClosure) { + struct EncBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for EncBack<'a, $($N),*> { + type BlockSize = $block_size; + } + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for EncBack<'a, $($N),*> { + type ParBlocksSize = $crate::consts::U1; + } + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockCipherEncBackend for EncBack<'a, $($N),*> { + #[inline(always)] + fn proc_block( + &mut self, + mut $block: $crate::inout::InOut<'_, '_, $crate::Block> + ) { + let $state: &$cipher<$($N),*> = self.0; + $enc_block + } + } + + f.call(&mut EncBack(self)) + } + } + + impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherDecrypt for $cipher<$($N),*> { + fn decrypt_with_backend(&self, f: impl $crate::BlockCipherDecClosure) { + struct DecBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for DecBack<'a, $($N),*> { + type BlockSize = $block_size; + } + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for DecBack<'a, $($N),*> { + type ParBlocksSize = $crate::consts::U1; + } + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockCipherDecBackend for DecBack<'a, $($N),*> { + #[inline(always)] + fn proc_block( + &mut self, + mut $block: $crate::inout::InOut<'_, '_, $crate::Block> + ) { + let $state: &$cipher<$($N),*> = self.0; + $dec_block + } + } + + f.call(&mut DecBack(self)) + } + } + }; + ( + $cipher:ident, $block_size:ty, $state:ident, $block:ident, + encrypt: $enc_block:block + decrypt: $dec_block:block + ) => { + $crate::impl_simple_block_encdec!( + <> $cipher, $block_size, $state, $block, + encrypt: $enc_block + decrypt: $dec_block + ); + }; +} From 1d286e2894d4832ac86ca49d0c8543040c02ed29 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, 2 Aug 2024 17:01:44 +0300 Subject: [PATCH 02/12] Expose block and stream modules --- cipher/Cargo.toml | 3 +- cipher/src/block.rs | 15 ++-- cipher/src/block/macros.rs | 79 ------------------- cipher/src/dev/block.rs | 15 ++-- cipher/src/lib.rs | 26 +++--- cipher/src/stream.rs | 12 ++- .../{stream_core.rs => stream/core_api.rs} | 5 +- cipher/src/{ => stream}/errors.rs | 0 .../{stream_wrapper.rs => stream/wrapper.rs} | 2 +- 9 files changed, 40 insertions(+), 117 deletions(-) delete mode 100644 cipher/src/block/macros.rs rename cipher/src/{stream_core.rs => stream/core_api.rs} (98%) rename cipher/src/{ => stream}/errors.rs (100%) rename cipher/src/{stream_wrapper.rs => stream/wrapper.rs} (99%) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 044e84b4c..fb2536eb0 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -24,7 +24,8 @@ zeroize = { version = "1.7", optional = true, default-features = false } alloc = [] std = ["alloc", "crypto-common/std", "inout/std"] block-padding = ["inout/block-padding"] -rand_core = ["crypto-common/rand_core"] # Enable random key and IV generation methods +# Enable random key and IV generation methods +rand_core = ["crypto-common/rand_core"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 4ff68f08b..3699ebfdb 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -12,6 +12,7 @@ #[cfg(all(feature = "block-padding", feature = "alloc"))] use alloc::{vec, vec::Vec}; +use crypto_common::{Block, BlockSizeUser}; #[cfg(feature = "block-padding")] use inout::{ block_padding::{Padding, UnpadError}, @@ -19,17 +20,15 @@ use inout::{ }; use inout::{InOut, InOutBuf, NotEqualError}; -pub use crypto_common::{array::ArraySize, typenum::Unsigned, Block, BlockSizeUser}; - mod backends; mod ctx; -mod macros; -pub use backends::*; use ctx::{BlockCtx, BlocksCtx}; -/// Marker trait for block ciphers. -pub trait BlockCipher: BlockSizeUser {} +pub use backends::{ + BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherEncBackend, BlockCipherEncClosure, + BlockModeDecBackend, BlockModeDecClosure, BlockModeEncBackend, BlockModeEncClosure, +}; /// Encrypt-only functionality for block ciphers. pub trait BlockCipherEncrypt: BlockSizeUser + Sized { @@ -132,6 +131,7 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized { #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] fn encrypt_padded_vec>(&self, msg: &[u8]) -> Vec { + use crypto_common::typenum::Unsigned; let bs = Self::BlockSize::USIZE; let mut out = vec![0; bs * (msg.len() / bs + 1)]; let len = self @@ -265,8 +265,6 @@ pub trait BlockCipherDecrypt: BlockSizeUser { } } -impl BlockCipher for &Alg {} - impl BlockCipherEncrypt for &Alg { fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure) { Alg::encrypt_with_backend(self, f); @@ -384,6 +382,7 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] fn encrypt_padded_vec>(self, msg: &[u8]) -> Vec { + use crypto_common::typenum::Unsigned; let bs = Self::BlockSize::USIZE; let mut out = vec![0; bs * (msg.len() / bs + 1)]; let len = self diff --git a/cipher/src/block/macros.rs b/cipher/src/block/macros.rs deleted file mode 100644 index 17d6e0d4c..000000000 --- a/cipher/src/block/macros.rs +++ /dev/null @@ -1,79 +0,0 @@ -/// Implement simple block backend -#[macro_export] -macro_rules! impl_simple_block_encdec { - ( - <$($N:ident$(:$b0:ident$(+$b:ident)*)?),*> - $cipher:ident, $block_size:ty, $state:ident, $block:ident, - encrypt: $enc_block:block - decrypt: $dec_block:block - ) => { - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockSizeUser for $cipher<$($N),*> { - type BlockSize = $block_size; - } - - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherEncrypt for $cipher<$($N),*> { - fn encrypt_with_backend(&self, f: impl $crate::BlockCipherEncClosure) { - struct EncBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for EncBack<'a, $($N),*> { - type BlockSize = $block_size; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for EncBack<'a, $($N),*> { - type ParBlocksSize = $crate::consts::U1; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockCipherEncBackend for EncBack<'a, $($N),*> { - #[inline(always)] - fn proc_block( - &mut self, - mut $block: $crate::inout::InOut<'_, '_, $crate::Block> - ) { - let $state: &$cipher<$($N),*> = self.0; - $enc_block - } - } - - f.call(&mut EncBack(self)) - } - } - - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherDecrypt for $cipher<$($N),*> { - fn decrypt_with_backend(&self, f: impl $crate::BlockCipherDecClosure) { - struct DecBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for DecBack<'a, $($N),*> { - type BlockSize = $block_size; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for DecBack<'a, $($N),*> { - type ParBlocksSize = $crate::consts::U1; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockCipherDecBackend for DecBack<'a, $($N),*> { - #[inline(always)] - fn proc_block( - &mut self, - mut $block: $crate::inout::InOut<'_, '_, $crate::Block> - ) { - let $state: &$cipher<$($N),*> = self.0; - $dec_block - } - } - - f.call(&mut DecBack(self)) - } - } - }; - ( - $cipher:ident, $block_size:ty, $state:ident, $block:ident, - encrypt: $enc_block:block - decrypt: $dec_block:block - ) => { - $crate::impl_simple_block_encdec!( - <> $cipher, $block_size, $state, $block, - encrypt: $enc_block - decrypt: $dec_block - ); - }; -} diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 80ea55273..053c55c24 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -7,8 +7,11 @@ macro_rules! block_cipher_test { #[test] fn $name() { use cipher::{ - array::Array, blobby::Blob3Iterator, typenum::Unsigned, BlockCipherDecrypt, - BlockCipherEncrypt, BlockSizeUser, KeyInit, + array::Array, + blobby::Blob3Iterator, + block::{BlockCipherDecrypt, BlockCipherEncrypt}, + typenum::Unsigned, + BlockSizeUser, KeyInit, }; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -290,7 +293,7 @@ macro_rules! block_encryptor_bench { #[bench] pub fn $block_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::{BlockCipherEncrypt, BlockModeEncrypt}; + use cipher::block::{BlockCipherEncrypt, BlockModeEncrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -307,7 +310,7 @@ macro_rules! block_encryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::{BlockCipherEncrypt, BlockModeEncrypt}; + use cipher::block::{BlockCipherEncrypt, BlockModeEncrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -353,7 +356,7 @@ macro_rules! block_decryptor_bench { #[bench] pub fn $block_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::{BlockCipherDecrypt, BlockModeDecrypt}; + use cipher::block::{BlockCipherDecrypt, BlockModeDecrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -370,7 +373,7 @@ macro_rules! block_decryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::{BlockCipherDecrypt, BlockModeDecrypt}; + use cipher::block::{BlockCipherDecrypt, BlockModeDecrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index ba485aa5a..032e05daa 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -18,42 +18,34 @@ missing_debug_implementations )] -pub use crypto_common; -pub use inout; - #[cfg(all(feature = "block-padding", feature = "alloc"))] extern crate alloc; - #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "dev")] +pub use blobby; +pub use crypto_common; #[cfg(feature = "rand_core")] pub use crypto_common::rand_core; - +pub use inout; #[cfg(feature = "block-padding")] pub use inout::block_padding; - #[cfg(feature = "zeroize")] pub use zeroize; -#[cfg(feature = "dev")] -pub use blobby; - -mod block; +pub mod block; #[cfg(feature = "dev")] mod dev; -mod errors; -mod stream; -mod stream_core; -mod stream_wrapper; +pub mod stream; -pub use crate::{block::*, errors::*, stream::*, stream_core::*, stream_wrapper::*}; pub use crypto_common::{ array, typenum::{self, consts}, - AlgorithmName, Block, InnerIvInit, InvalidLength, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, - KeySizeUser, ParBlocks, ParBlocksSizeUser, + AlgorithmName, Block, BlockSizeUser, InnerIvInit, InvalidLength, Iv, IvSizeUser, Key, KeyInit, + KeyIvInit, KeySizeUser, ParBlocks, ParBlocksSizeUser, }; +pub use inout::{InOut, InOutBuf}; /// Trait for loading current IV state. pub trait IvState: IvSizeUser { diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index ac7a2fe5d..20da93058 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -3,11 +3,17 @@ //! See [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) //! for ciphers implementation. -use crate::errors::{OverflowError, StreamCipherError}; -use crate::stream_core::Counter; -use crate::{Block, BlockModeDecrypt, BlockModeEncrypt}; +use crate::block::{BlockModeDecrypt, BlockModeEncrypt}; +use crypto_common::Block; use inout::{InOutBuf, NotEqualError}; +mod core_api; +mod errors; +mod wrapper; + +pub use core_api::{Counter, StreamBackend, StreamCipherCore, StreamCipherSeekCore, StreamClosure}; +pub use errors::{OverflowError, StreamCipherError}; + /// Marker trait for block-level asynchronous stream ciphers pub trait AsyncStreamCipher: Sized { /// Encrypt data using `InOutBuf`. diff --git a/cipher/src/stream_core.rs b/cipher/src/stream/core_api.rs similarity index 98% rename from cipher/src/stream_core.rs rename to cipher/src/stream/core_api.rs index c121ca46a..cc16788d4 100644 --- a/cipher/src/stream_core.rs +++ b/cipher/src/stream/core_api.rs @@ -1,5 +1,6 @@ -use crate::{ParBlocks, ParBlocksSizeUser, StreamCipherError}; -use crypto_common::{array::Array, typenum::Unsigned, Block, BlockSizeUser, BlockSizes}; +use super::StreamCipherError; +use crate::{array::Array, typenum::Unsigned}; +use crypto_common::{Block, BlockSizeUser, BlockSizes, ParBlocks, ParBlocksSizeUser}; use inout::{InOut, InOutBuf}; /// Trait implemented by stream cipher backends. diff --git a/cipher/src/errors.rs b/cipher/src/stream/errors.rs similarity index 100% rename from cipher/src/errors.rs rename to cipher/src/stream/errors.rs diff --git a/cipher/src/stream_wrapper.rs b/cipher/src/stream/wrapper.rs similarity index 99% rename from cipher/src/stream_wrapper.rs rename to cipher/src/stream/wrapper.rs index 626b4e3d0..abf4a9b04 100644 --- a/cipher/src/stream_wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -1,4 +1,4 @@ -use crate::{ +use super::{ errors::StreamCipherError, Block, OverflowError, SeekNum, StreamCipher, StreamCipherCore, StreamCipherSeek, StreamCipherSeekCore, }; From dda304c8c1db3e0f43cbcdab59b1e67ea1d24ed4 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, 2 Aug 2024 17:04:40 +0300 Subject: [PATCH 03/12] re-export StreamCipherCoreWrapper --- cipher/src/stream.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 20da93058..aeb316df2 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -13,6 +13,7 @@ mod wrapper; pub use core_api::{Counter, StreamBackend, StreamCipherCore, StreamCipherSeekCore, StreamClosure}; pub use errors::{OverflowError, StreamCipherError}; +pub use wrapper::StreamCipherCoreWrapper; /// Marker trait for block-level asynchronous stream ciphers pub trait AsyncStreamCipher: Sized { From 129582d63285cf423e853dea75c7645c2fd1ae1e 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, 2 Aug 2024 18:56:11 +0300 Subject: [PATCH 04/12] Move `IvState` to `crypto-common` --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- cipher/src/lib.rs | 10 ++-------- crypto-common/src/lib.rs | 6 ++++++ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac9536a6a..8768221ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,7 +220,7 @@ name = "cipher" version = "0.5.0-pre.6" dependencies = [ "blobby", - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "inout 0.2.0-rc.0", "zeroize", ] diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index fb2536eb0..d677c9511 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.2.0-rc.0" +crypto-common = { path = "../crypto-common/", version = "0.2.0-rc.0" } inout = "0.2.0-rc.0" # optional dependencies diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 032e05daa..d9d4fa1e2 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -42,13 +42,7 @@ pub mod stream; pub use crypto_common::{ array, typenum::{self, consts}, - AlgorithmName, Block, BlockSizeUser, InnerIvInit, InvalidLength, Iv, IvSizeUser, Key, KeyInit, - KeyIvInit, KeySizeUser, ParBlocks, ParBlocksSizeUser, + AlgorithmName, Block, BlockSizeUser, InnerIvInit, InvalidLength, Iv, IvSizeUser, IvState, Key, + KeyInit, KeyIvInit, KeySizeUser, ParBlocks, ParBlocksSizeUser, }; pub use inout::{InOut, InOutBuf}; - -/// Trait for loading current IV state. -pub trait IvState: IvSizeUser { - /// Returns current IV state. - fn iv_state(&self) -> Iv; -} diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 712fcf49b..bd62fade1 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -305,6 +305,12 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { } } +/// Trait for loading current IV state. +pub trait IvState: IvSizeUser { + /// Returns current IV state. + fn iv_state(&self) -> Iv; +} + impl KeySizeUser for T where T: InnerUser, From 534b0aad5239b5f009f457c42c5737a056d873b8 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, 2 Aug 2024 19:01:47 +0300 Subject: [PATCH 05/12] Update Cargo.lock --- Cargo.lock | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8768221ea..4d0c99a2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,15 +160,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cc" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", @@ -926,9 +926,12 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +dependencies = [ + "zerocopy", +] [[package]] name = "pqcrypto" @@ -1115,9 +1118,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ "itoa", "memchr", @@ -1356,6 +1359,27 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "zerocopy" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zeroize" version = "1.8.1" From b34c1d6a01c507fbe0186ac40307aa35ced4e41e 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, 2 Aug 2024 22:32:09 +0300 Subject: [PATCH 06/12] Bump min version of `zeroize` to 1.8 --- cipher/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index d677c9511..32411bb81 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -18,7 +18,7 @@ inout = "0.2.0-rc.0" # optional dependencies blobby = { version = "0.3", optional = true } -zeroize = { version = "1.7", optional = true, default-features = false } +zeroize = { version = "1.8", optional = true, default-features = false } [features] alloc = [] From 197ef4eff104c605c0e05330b97a0c8df33c9803 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, 9 Aug 2024 16:11:28 +0300 Subject: [PATCH 07/12] Re-export items from stream and block modules --- cipher/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index d9d4fa1e2..1c7ae89ee 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -39,8 +39,11 @@ pub mod block; mod dev; pub mod stream; +pub use block::*; +pub use stream::*; + pub use crypto_common::{ - array, + array::{self, Array}, typenum::{self, consts}, AlgorithmName, Block, BlockSizeUser, InnerIvInit, InvalidLength, Iv, IvSizeUser, IvState, Key, KeyInit, KeyIvInit, KeySizeUser, ParBlocks, ParBlocksSizeUser, From c00ddc9915e7a5dfcb7d4c14cab08c64836e06a5 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: Mon, 12 Aug 2024 14:27:12 +0300 Subject: [PATCH 08/12] Bump cipher and crypto-common versions --- Cargo.lock | 18 +++++++++--------- cipher/Cargo.toml | 4 ++-- crypto-common/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d0c99a2e..355a26033 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "heapless", ] @@ -130,7 +130,7 @@ version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17092d478f4fadfb35a7e082f62e49f0907fdf048801d9d706277e34f9df8a78" dependencies = [ - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "zeroize", ] @@ -217,10 +217,10 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre.6" +version = "0.5.0-pre.7" dependencies = [ "blobby", - "crypto-common 0.2.0-rc.0", + "crypto-common 0.2.0-rc.1", "inout 0.2.0-rc.0", "zeroize", ] @@ -317,6 +317,8 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.2.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b" dependencies = [ "getrandom", "hybrid-array", @@ -325,9 +327,7 @@ 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" dependencies = [ "getrandom", "hybrid-array", @@ -435,7 +435,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-rc.0", "const-oid 0.10.0-rc.0", - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "subtle", "zeroize", ] @@ -1306,7 +1306,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-rc.0" dependencies = [ - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "subtle", ] diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 32411bb81..1125a68b4 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre.6" +version = "0.5.0-pre.7" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { path = "../crypto-common/", version = "0.2.0-rc.0" } +crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common/" } inout = "0.2.0-rc.0" # optional dependencies diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 8ccd7ea05..52be3f26b 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-rc.0" +version = "0.2.0-rc.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 021f308e2a6271262564dc2a4a77eec7526019e0 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: Mon, 12 Aug 2024 14:37:43 +0300 Subject: [PATCH 09/12] tweak dev::block --- cipher/src/dev/block.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 053c55c24..42558c561 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -293,7 +293,7 @@ macro_rules! block_encryptor_bench { #[bench] pub fn $block_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::block::{BlockCipherEncrypt, BlockModeEncrypt}; + use $crate::{BlockCipherEncrypt, BlockModeEncrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -310,7 +310,7 @@ macro_rules! block_encryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::block::{BlockCipherEncrypt, BlockModeEncrypt}; + use $crate::{BlockCipherEncrypt, BlockModeEncrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -356,7 +356,7 @@ macro_rules! block_decryptor_bench { #[bench] pub fn $block_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::block::{BlockCipherDecrypt, BlockModeDecrypt}; + use $crate::{BlockCipherDecrypt, BlockModeDecrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -373,7 +373,7 @@ macro_rules! block_decryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::block::{BlockCipherDecrypt, BlockModeDecrypt}; + use $crate::{BlockCipherDecrypt, BlockModeDecrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; From 19e6b3f01614cbb5232e99dbf60883f846e31626 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: Mon, 12 Aug 2024 14:56:50 +0300 Subject: [PATCH 10/12] Update serde_json and bytes --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 355a26033..33d01836f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1118,9 +1118,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.122" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" dependencies = [ "itoa", "memchr", From 3612b3c1b5b2c8aa08ec7dde1121144e56db40db 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: Mon, 12 Aug 2024 17:35:46 +0300 Subject: [PATCH 11/12] rename stream cipher traits --- cipher/src/stream.rs | 17 ++++++++++++----- cipher/src/stream/core_api.rs | 30 +++++++++++++++--------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index aeb316df2..520837db5 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -11,7 +11,10 @@ mod core_api; mod errors; mod wrapper; -pub use core_api::{Counter, StreamBackend, StreamCipherCore, StreamCipherSeekCore, StreamClosure}; +pub use core_api::{ + StreamCipherBackend, StreamCipherClosure, StreamCipherCore, StreamCipherCounter, + StreamCipherSeekCore, +}; pub use errors::{OverflowError, StreamCipherError}; pub use wrapper::StreamCipherCoreWrapper; @@ -199,17 +202,21 @@ impl StreamCipher for &mut C { pub trait SeekNum: Sized { /// Try to get position for block number `block`, byte position inside /// block `byte`, and block size `bs`. - fn from_block_byte(block: T, byte: u8, bs: u8) -> Result; + fn from_block_byte( + block: T, + byte: u8, + bs: u8, + ) -> Result; /// Try to get block number and bytes position for given block size `bs`. - fn into_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; + fn into_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; } macro_rules! impl_seek_num { {$($t:ty )*} => { $( impl SeekNum for $t { - fn from_block_byte(block: T, byte: u8, block_size: u8) -> Result { + fn from_block_byte(block: T, byte: u8, block_size: u8) -> Result { debug_assert!(byte != 0); let rem = block_size.checked_sub(byte).ok_or(OverflowError)?; let block: Self = block.try_into().map_err(|_| OverflowError)?; @@ -219,7 +226,7 @@ macro_rules! impl_seek_num { .ok_or(OverflowError) } - fn into_block_byte(self, block_size: u8) -> Result<(T, u8), OverflowError> { + fn into_block_byte(self, block_size: u8) -> Result<(T, u8), OverflowError> { let bs: Self = block_size.into(); let byte = (self % bs) as u8; let block = T::try_from(self / bs).map_err(|_| OverflowError)?; diff --git a/cipher/src/stream/core_api.rs b/cipher/src/stream/core_api.rs index cc16788d4..088898792 100644 --- a/cipher/src/stream/core_api.rs +++ b/cipher/src/stream/core_api.rs @@ -4,7 +4,7 @@ use crypto_common::{Block, BlockSizeUser, BlockSizes, ParBlocks, ParBlocksSizeUs use inout::{InOut, InOutBuf}; /// Trait implemented by stream cipher backends. -pub trait StreamBackend: ParBlocksSizeUser { +pub trait StreamCipherBackend: ParBlocksSizeUser { /// Generate keystream block. fn gen_ks_block(&mut self, block: &mut Block); @@ -30,9 +30,9 @@ pub trait StreamBackend: ParBlocksSizeUser { /// Trait for [`StreamBackend`] users. /// /// This trait is used to define rank-2 closures. -pub trait StreamClosure: BlockSizeUser { +pub trait StreamCipherClosure: BlockSizeUser { /// Execute closure with the provided stream cipher backend. - fn call>(self, backend: &mut B); + fn call>(self, backend: &mut B); } /// Block-level synchronous stream ciphers. @@ -45,7 +45,7 @@ pub trait StreamCipherCore: BlockSizeUser + Sized { fn remaining_blocks(&self) -> Option; /// Process data using backend provided to the rank-2 closure. - fn process_with_backend(&mut self, f: impl StreamClosure); + fn process_with_backend(&mut self, f: impl StreamCipherClosure); /// Write keystream block. /// @@ -153,7 +153,7 @@ pub trait StreamCipherCore: BlockSizeUser + Sized { /// This trait is implemented for `i32`, `u32`, `u64`, `u128`, and `usize`. /// It's not intended to be implemented in third-party crates, but doing so /// is not forbidden. -pub trait Counter: +pub trait StreamCipherCounter: TryFrom + TryFrom + TryFrom @@ -170,7 +170,7 @@ pub trait Counter: /// Block-level seeking trait for stream ciphers. pub trait StreamCipherSeekCore: StreamCipherCore { /// Counter type used inside stream cipher. - type Counter: Counter; + type Counter: StreamCipherCounter; /// Get current block position. fn get_block_pos(&self) -> Self::Counter; @@ -181,7 +181,7 @@ pub trait StreamCipherSeekCore: StreamCipherCore { macro_rules! impl_counter { {$($t:ty )*} => { - $( impl Counter for $t { } )* + $( impl StreamCipherCounter for $t { } )* }; } @@ -193,9 +193,9 @@ struct WriteBlockCtx<'a, BS: BlockSizes> { impl<'a, BS: BlockSizes> BlockSizeUser for WriteBlockCtx<'a, BS> { type BlockSize = BS; } -impl<'a, BS: BlockSizes> StreamClosure for WriteBlockCtx<'a, BS> { +impl<'a, BS: BlockSizes> StreamCipherClosure for WriteBlockCtx<'a, BS> { #[inline(always)] - fn call>(self, backend: &mut B) { + fn call>(self, backend: &mut B) { backend.gen_ks_block(self.block); } } @@ -206,9 +206,9 @@ struct WriteBlocksCtx<'a, BS: BlockSizes> { impl<'a, BS: BlockSizes> BlockSizeUser for WriteBlocksCtx<'a, BS> { type BlockSize = BS; } -impl<'a, BS: BlockSizes> StreamClosure for WriteBlocksCtx<'a, BS> { +impl<'a, BS: BlockSizes> StreamCipherClosure for WriteBlocksCtx<'a, BS> { #[inline(always)] - fn call>(self, backend: &mut B) { + fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { let (chunks, tail) = Array::slice_as_chunks_mut(self.blocks); for chunk in chunks { @@ -231,9 +231,9 @@ impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for ApplyBlockCtx<'inp, 'out, BS> type BlockSize = BS; } -impl<'inp, 'out, BS: BlockSizes> StreamClosure for ApplyBlockCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> StreamCipherClosure for ApplyBlockCtx<'inp, 'out, BS> { #[inline(always)] - fn call>(mut self, backend: &mut B) { + fn call>(mut self, backend: &mut B) { let mut t = Default::default(); backend.gen_ks_block(&mut t); self.block.xor_in2out(&t); @@ -248,10 +248,10 @@ impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for ApplyBlocksCtx<'inp, 'out, BS type BlockSize = BS; } -impl<'inp, 'out, BS: BlockSizes> StreamClosure for ApplyBlocksCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> StreamCipherClosure for ApplyBlocksCtx<'inp, 'out, BS> { #[inline(always)] #[allow(clippy::needless_range_loop)] - fn call>(self, backend: &mut B) { + fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { let (chunks, mut tail) = self.blocks.into_chunks::(); for mut chunk in chunks { From 546fa2bc04f8f9d13c39d09a0e8de3d3aa89d989 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: Wed, 14 Aug 2024 16:25:57 +0300 Subject: [PATCH 12/12] Fix doc link --- cipher/src/stream/core_api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/src/stream/core_api.rs b/cipher/src/stream/core_api.rs index 088898792..aab1c32b5 100644 --- a/cipher/src/stream/core_api.rs +++ b/cipher/src/stream/core_api.rs @@ -27,7 +27,7 @@ pub trait StreamCipherBackend: ParBlocksSizeUser { } } -/// Trait for [`StreamBackend`] users. +/// Trait for [`StreamCipherBackend`] users. /// /// This trait is used to define rank-2 closures. pub trait StreamCipherClosure: BlockSizeUser {