From 7bff7d65873402bf59f1cd09f0d0e23449db8ed9 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?= Date: Sat, 10 Apr 2021 13:17:31 +0300 Subject: [PATCH 1/6] cipher: experimental design --- cipher/Cargo.toml | 4 +- cipher/src/block.rs | 327 ++++++++++++++--------------- cipher/src/dev/block.rs | 17 +- cipher/src/errors.rs | 17 -- cipher/src/inout.rs | 374 ++++++++++++++++++++++++++++++++++ cipher/src/lib.rs | 115 +---------- cipher/src/mode.rs | 42 ---- cipher/src/stream.rs | 37 ++++ crypto-common/src/core_api.rs | 10 +- crypto-common/src/init.rs | 192 +++++++++++++++++ crypto-common/src/lib.rs | 18 +- 11 files changed, 795 insertions(+), 358 deletions(-) create mode 100644 cipher/src/inout.rs delete mode 100644 cipher/src/mode.rs create mode 100644 crypto-common/src/init.rs diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index d01e925b3..2feabf3bc 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -20,9 +20,9 @@ blobby = { version = "0.3", optional = true } rand_core = { version = "0.6", optional = true } [features] -default = ["mode_wrapper"] +#default = ["mode_wrapper"] std = ["crypto-common/std"] -mode_wrapper = ["block-buffer"] +wrappers = ["block-buffer"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 1769c782e..233150b89 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -9,229 +9,198 @@ //! [1]: https://en.wikipedia.org/wiki/Block_cipher //! [2]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation //! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm +pub use crypto_common::{BlockProcessing, Block, InnerIvInit}; +use crate::inout::{InOutVal, InOutBuf, InResOutBuf}; +use generic_array::{GenericArray, typenum::U1}; -use crate::errors::InvalidLength; -use crate::{FromKey, FromKeyNonce}; -use core::convert::TryInto; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; - -/// Key for an algorithm that implements [`FromKey`]. -pub type BlockCipherKey = GenericArray::KeySize>; - -/// Block on which a [`BlockCipher`] operates. -pub type Block = GenericArray::BlockSize>; - -/// Block on which a [`BlockCipher`] operates in parallel. -pub type ParBlocks = GenericArray, ::ParBlocks>; - -/// Trait which marks a type as being a block cipher. -pub trait BlockCipher { - /// Size of the block in bytes - type BlockSize: ArrayLength; - - /// Number of blocks which can be processed in parallel by - /// cipher implementation - type ParBlocks: ArrayLength>; -} - -/// Encrypt-only functionality for block ciphers. -pub trait BlockEncrypt: BlockCipher { - /// Encrypt block in-place - fn encrypt_block(&self, block: &mut Block); - - /// Encrypt several blocks in parallel using instruction level parallelism - /// if possible. +/// Marker trait for types which represent block ciphers. +/// +/// Even if a type is marked by this trait implements only `BlockEncryptMut` and/or +/// `BlockDecryptMut`, it is assumed that its inner state is not changed by calling +/// its methods, i.e. mutable-only implementations are used only for hardware +/// encryption engines which require `&mut self` access to an underlying hardware +/// peripheral. +pub trait BlockCipher {} + +/// Marker trait for types which represent asynchronous stream ciphers. +pub trait AsyncStreamCipher {} + +/// Encrypt-only functionality of block ciphers. +pub trait BlockEncrypt: BlockProcessing { + /// Encrypt the provided block. /// - /// If `ParBlocks` equals to 1 it's equivalent to `encrypt_block`. - #[inline] - fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) { - for block in blocks.iter_mut() { - self.encrypt_block(block); - } + /// Usually `block` is either `&mut Block`, or `(&Block, &mut Block)`. + fn encrypt_block(&self, block: impl InOutVal>); + + /// Encrypt provided blocks in parallel. + fn encrypt_blocks( + &self, + mut blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) { + blocks.chunks::( + &self, + |state, inc, res| state.encrypt_block((&inc[0], &mut res[0])), + |state, inc, res| state.encrypt_block((&inc[0], &mut res[0])), + proc, + ); } +} - /// Encrypt a slice of blocks, leveraging parallelism when available. - #[inline] - fn encrypt_blocks(&self, mut blocks: &mut [Block]) { - let pb = Self::ParBlocks::to_usize(); - - if pb > 1 { - let mut iter = blocks.chunks_exact_mut(pb); - - for chunk in &mut iter { - self.encrypt_par_blocks(chunk.try_into().unwrap()) - } - - blocks = iter.into_remainder(); - } - - for block in blocks { - self.encrypt_block(block); - } +/// Decrypt-only functionality of block ciphers. +pub trait BlockDecrypt: BlockProcessing { + /// Decrypt the provided block. + /// + /// Usually `block` is either `&mut Block`, or `(&Block, &mut Block)`. + fn decrypt_block(&self, block: impl InOutVal>,); + + /// Decrypt provided blocks in parallel. + fn decrypt_blocks( + &self, + mut blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) { + blocks.chunks::( + &self, + |state, inc, res| state.decrypt_block((&inc[0], &mut res[0])), + |state, inc, res| state.decrypt_block((&inc[0], &mut res[0])), + proc, + ); } } -/// Decrypt-only functionality for block ciphers. -pub trait BlockDecrypt: BlockCipher { - /// Decrypt block in-place - fn decrypt_block(&self, block: &mut Block); - - /// Decrypt several blocks in parallel using instruction level parallelism - /// if possible. +/// Encrypt-only functionality of block ciphers and block cipher modes of operation. +pub trait BlockEncryptMut: BlockProcessing { + /// Encrypt the provided block. /// - /// If `ParBlocks` equals to 1 it's equivalent to `decrypt_block`. - #[inline] - fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) { - for block in blocks.iter_mut() { - self.decrypt_block(block); - } + /// Usually `block` is either `&mut Block`, or `(&Block, &mut Block)`. + fn encrypt_block(&mut self, block: impl InOutVal>); + + /// Encrypt provided blocks in parallel. + fn encrypt_blocks( + &mut self, + mut blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) { + blocks.chunks::( + self, + |state, inc, res| state.encrypt_block((&inc[0], &mut res[0])), + |state, inc, res| state.encrypt_block((&inc[0], &mut res[0])), + proc, + ); } +} - /// Decrypt a slice of blocks, leveraging parallelism when available. - #[inline] - fn decrypt_blocks(&self, mut blocks: &mut [Block]) { - let pb = Self::ParBlocks::to_usize(); - - if pb > 1 { - let mut iter = blocks.chunks_exact_mut(pb); - - for chunk in &mut iter { - self.decrypt_par_blocks(chunk.try_into().unwrap()) - } - - blocks = iter.into_remainder(); - } - - for block in blocks { - self.decrypt_block(block); - } +/// Decrypt-only functionality of block ciphers and block cipher modes of operation. +pub trait BlockDecryptMut: BlockProcessing { + /// Decrypt the provided block. + /// + /// Usually `block` is either `&mut Block`, or `(&Block, &mut Block)`. + fn decrypt_block(&mut self, block: impl InOutVal>); + + /// Decrypt provided blocks in parallel. + fn decrypt_blocks( + &mut self, + mut blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) { + blocks.chunks::( + self, + |state, inc, res| state.decrypt_block((&inc[0], &mut res[0])), + |state, inc, res| state.decrypt_block((&inc[0], &mut res[0])), + proc, + ); } } -/// Encrypt-only functionality for block ciphers with mutable access to `self`. +/// Trait for block cipher modes of operation, used to obtain the current state +/// in the form of an IV that can re-initialize mode later and resume the original +/// operation. /// -/// The main use case for this trait is hardware encryption engines which -/// require `&mut self` access to an underlying hardware peripheral. -pub trait BlockEncryptMut: BlockCipher { - /// Encrypt block in-place - fn encrypt_block_mut(&mut self, block: &mut Block); -} - -/// Decrypt-only functionality for block ciphers with mutable access to `self`. +/// The IV value SHOULD be used for resuming operations only and MUST NOT be +/// exposed to attackers. Failing to comply with this requirement breaks +/// unpredictability and opens attack venues (see e.g. [1], sec. 3.6.2). /// -/// The main use case for this trait is hardware encryption engines which -/// require `&mut self` access to an underlying hardware peripheral. -pub trait BlockDecryptMut: BlockCipher { - /// Decrypt block in-place - fn decrypt_block_mut(&mut self, block: &mut Block); +/// [1]: https://www.cs.umd.edu/~jkatz/imc.html +pub trait IvState: InnerIvInit { + /// Returns the IV needed to process the following block. This value MUST + /// NOT be exposed to attackers. + fn iv_state(&self) -> GenericArray; } -impl BlockEncryptMut for Alg { - fn encrypt_block_mut(&mut self, block: &mut Block) { - self.encrypt_block(block); - } -} -impl BlockDecryptMut for Alg { - fn decrypt_block_mut(&mut self, block: &mut Block) { - self.decrypt_block(block); - } -} +// =========================== BLANKET IMPLS =========================== -// Impls of block cipher traits for reference types -impl BlockCipher for &Alg { - type BlockSize = Alg::BlockSize; - type ParBlocks = Alg::ParBlocks; -} +impl BlockCipher for &T {} + +impl BlockCipher for &mut T {} impl BlockEncrypt for &Alg { #[inline] - fn encrypt_block(&self, block: &mut Block) { + fn encrypt_block(&self, block: impl InOutVal>) { Alg::encrypt_block(self, block); } #[inline] - fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) { - Alg::encrypt_par_blocks(self, blocks); - } - - #[inline] - fn encrypt_blocks(&self, blocks: &mut [Block]) { - Alg::encrypt_blocks(self, blocks); + fn encrypt_blocks( + &self, + blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) { + Alg::encrypt_blocks(self, blocks, proc); } } impl BlockDecrypt for &Alg { #[inline] - fn decrypt_block(&self, block: &mut Block) { - Alg::decrypt_block(self, block); + fn decrypt_block(&self, block: impl InOutVal>) { + Alg::decrypt_block(self, block) } #[inline] - fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) { - Alg::decrypt_par_blocks(self, blocks); + fn decrypt_blocks( + &self, + blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) { + Alg::decrypt_blocks(self, blocks, proc); } +} +impl BlockEncryptMut for Alg { #[inline] - fn decrypt_blocks(&self, blocks: &mut [Block]) { - Alg::decrypt_blocks(self, blocks); + fn encrypt_block(&mut self, block: impl InOutVal>) { + Alg::encrypt_block(self, block) } -} - -/// Trait for types which can be initialized from a block cipher. -pub trait FromBlockCipher { - /// Block cipher used for initialization. - type BlockCipher: BlockCipher; - - /// Initialize instance from block cipher. - fn from_block_cipher(cipher: Self::BlockCipher) -> Self; -} -/// Trait for types which can be initialized from a block cipher and nonce. -pub trait FromBlockCipherNonce { - /// Block cipher used for initialization. - type BlockCipher: BlockCipher; - /// Nonce size in bytes. - type NonceSize: ArrayLength; - - /// Initialize instance from block cipher and nonce. - fn from_block_cipher_nonce( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self; -} - -impl FromKeyNonce for T -where - T: FromBlockCipherNonce, - T::BlockCipher: FromKey, -{ - type KeySize = ::KeySize; - type NonceSize = T::NonceSize; - - fn new( - key: &GenericArray, - nonce: &GenericArray, - ) -> Self { - Self::from_block_cipher_nonce(T::BlockCipher::new(key), nonce) + #[inline] + fn encrypt_blocks( + &mut self, + blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) { + Alg::encrypt_blocks(self, blocks, proc); } } -impl FromKey for T -where - T: FromBlockCipher, - T::BlockCipher: FromKey, -{ - type KeySize = ::KeySize; - - fn new(key: &GenericArray) -> Self { - Self::from_block_cipher(T::BlockCipher::new(key)) +impl BlockDecryptMut for Alg { + #[inline] + fn decrypt_block(&mut self, block: impl InOutVal>) { + Alg::decrypt_block(self, block); } - fn new_from_slice(key: &[u8]) -> Result { - T::BlockCipher::new_from_slice(key) - .map_err(|_| InvalidLength) - .map(Self::from_block_cipher) + #[inline] + fn decrypt_blocks( + &mut self, + blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) { + Alg::decrypt_blocks(self, blocks, proc); } } + +// note: unfortunately we can't write a blanket implementation of +// `BlockEncryptMut`/`BlockDecryptMut` for implementors of `StreamCipherCore` +// since such impl will conflict with blanket impls for +// `BlockEncrypt`/`BlockDecrypt` diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index fc53b9435..f4d53980b 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -11,11 +11,11 @@ macro_rules! block_cipher_test { fn $name() { use cipher::generic_array::{typenum::Unsigned, GenericArray}; use cipher::{ - blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher, + blobby::Blob3Iterator, BlockDecrypt, BlockEncrypt, KeyInit, }; - fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { - let state = <$cipher as NewBlockCipher>::new_from_slice(key).unwrap(); + fn run_single_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { + let state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); let mut block = GenericArray::clone_from_slice(pt); state.encrypt_block(&mut block); @@ -31,6 +31,7 @@ macro_rules! block_cipher_test { true } + /* fn run_par_test(key: &[u8], pt: &[u8]) -> bool { type ParBlocks = <$cipher as BlockCipher>::ParBlocks; type BlockSize = <$cipher as BlockCipher>::BlockSize; @@ -69,15 +70,15 @@ macro_rules! block_cipher_test { true } + */ - let pb = <$cipher as BlockCipher>::ParBlocks::to_usize(); let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { let [key, pt, ct] = row.unwrap(); - if !run_test(key, pt, ct) { + if !run_single_test(key, pt, ct) { panic!( "\n\ - Failed test №{}\n\ + Failed single block test №{}\n\ key:\t{:?}\n\ plaintext:\t{:?}\n\ ciphertext:\t{:?}\n", @@ -85,6 +86,7 @@ macro_rules! block_cipher_test { ); } + /* // test parallel blocks encryption/decryption if pb != 1 { if !run_par_test(key, pt) { @@ -98,10 +100,11 @@ macro_rules! block_cipher_test { ); } } + */ } // test if cipher can be cloned let key = Default::default(); - let _ = <$cipher as NewBlockCipher>::new(&key).clone(); + let _ = <$cipher as KeyInit>::new(&key).clone(); } }; } diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index 644495e80..f6ede6ee9 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -35,23 +35,6 @@ impl From for LoopError { #[cfg(feature = "std")] impl std::error::Error for OverflowError {} -/// The error type returned when key and/or nonce used in the [`FromKey`] -/// and [`FromKeyNonce`] slice-based methods had an invalid length. -/// -/// [`FromKey`]: crate::FromKey -/// [`FromKeyNonce`]: crate::FromKeyNonce -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub struct InvalidLength; - -impl fmt::Display for InvalidLength { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("Invalid Length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidLength {} - /// The error type returned by the [`BlockModeEncryptWrapper`] and /// [`BlockModeDecryptWrapper`] types. /// diff --git a/cipher/src/inout.rs b/cipher/src/inout.rs new file mode 100644 index 000000000..8f5e78cae --- /dev/null +++ b/cipher/src/inout.rs @@ -0,0 +1,374 @@ +use generic_array::{GenericArray, ArrayLength}; +use core::marker::PhantomData; +use core::slice; + +// TODO: rename to InOutRef +pub trait InOutVal { + fn get_in(&self) -> &T; + + fn get_out(&mut self) -> &mut T; +} + +impl InOutVal for &mut T { + fn get_in(&self) -> &T { + self + } + fn get_out(&mut self) -> &mut T { + self + } +} + +impl InOutVal for (&T, &mut T) { + fn get_in(&self) -> &T { + self.0 + } + fn get_out(&mut self) -> &mut T { + self.1 + } +} + +// note: it would be nice to have: +// impl> InOutVal for &mut C { .. } +// but unfortunately it conflicts with the `&mut T` impl + +/// Fat pointer type which references one immutable (input) slice and one mutable +/// (output) slice of equal length. +pub struct InOutBuf<'in_buf, 'out_buf, T> { + in_ptr: *const T, + out_ptr: *mut T, + len: usize, + _pd: PhantomData<(&'in_buf T, &'out_buf mut T)>, +} + +impl<'a, T> From<&'a mut [T]> for InOutBuf<'a, 'a, T> { + fn from(buf: &'a mut [T]) -> Self { + Self { + in_ptr: buf.as_ptr(), + out_ptr: buf.as_mut_ptr(), + len: buf.len(), + _pd: PhantomData, + } + } +} + +impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { + /// Divides one buffer into two at an index. + /// + /// The first will contain all indices from `[0, mid)` (excluding + /// the index `mid` itself) and the second will contain all + /// indices from `[mid, len)` (excluding the index `len` itself). + /// + /// # Panics + /// + /// Panics if `mid > len`. + #[inline] + pub fn split_at(self, mid: usize) -> ( + InOutBuf<'in_buf, 'out_buf, T>, + InOutBuf<'in_buf, 'out_buf, T>, + ) { + assert!(mid <= self.len); + let (tail_in_ptr, tail_out_ptr) = unsafe { + (self.in_ptr.add(mid), self.out_ptr.add(mid)) + }; + ( + InOutBuf { + in_ptr: self.in_ptr, + out_ptr: self.out_ptr, + len: mid, + _pd: PhantomData, + }, + InOutBuf { + in_ptr: tail_in_ptr, + out_ptr: tail_out_ptr, + len: self.len() - mid, + _pd: PhantomData, + } + ) + } + + /// Partitions buffer into 2 parts: body of arrays and tail. + #[inline] + pub fn to_blocks>(self) -> ( + InOutBuf<'in_buf, 'out_buf, GenericArray>, + InOutBuf<'in_buf, 'out_buf, T>, + ) { + let nb = self.len() / N::USIZE; + let body_len = nb * N::USIZE; + let (tail_in_ptr, tail_out_ptr) = unsafe { + (self.in_ptr.add(body_len), self.out_ptr.add(body_len)) + }; + ( + InOutBuf { + in_ptr: self.in_ptr as *const GenericArray, + out_ptr: self.out_ptr as *mut GenericArray, + len: nb, + _pd: PhantomData, + }, + InOutBuf { + in_ptr: tail_in_ptr, + out_ptr: tail_out_ptr, + len: self.len() - body_len, + _pd: PhantomData, + } + ) + } + + /// Copy data from input buffer to output. Does nothing if input and + /// output buffers point to the same memory. + #[inline] + pub fn copy_in2out(&mut self) { + if self.in_ptr != self.out_ptr { + // SAFETY: if pointers are not equal, then memory regions do not overlap + unsafe { + core::ptr::copy_nonoverlapping(self.in_ptr, self.out_ptr, self.len); + } + } + } +} + +impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { + /// Create a new value from simple references. + #[inline] + pub fn from_refs(in_val: &'in_buf T, out_val: &'out_buf mut T) -> Self { + Self { + in_ptr: in_val as *const T, + out_ptr: out_val as *mut T, + len: 1, + _pd: PhantomData, + } + + } + + /// Create a new value from slices. + /// + /// Returns an error if length of slices is not equal to each other. + // TODO: add error type + #[inline] + pub fn new(in_buf: &'in_buf [T], out_buf: &'out_buf mut [T]) -> Result { + if in_buf.len() != out_buf.len() { + Err(()) + } else { + Ok(Self { + in_ptr: in_buf.as_ptr(), + out_ptr: out_buf.as_mut_ptr(), + len: in_buf.len(), + _pd: Default::default(), + }) + } + + } + + pub fn chunks( + &mut self, + state: S, + mut proc_chunk: PC, + mut proc_tail: PT, + proc_res: PR, + ) + where + T: Clone + Default, + N: ArrayLength + 'static, + PC: FnMut(&mut S, &GenericArray, &mut GenericArray), + PT: FnMut(&mut S, &[T], &mut GenericArray), + PR: FnMut(InResOutBuf<'_, '_, 'out_buf, T>), + { + self.try_chunks::( + state, + |state, inb, out| { + proc_chunk(state, inb, out); + Ok(()) + }, + |state, inb, out| { + proc_tail(state, inb, out); + Ok(()) + }, + proc_res, + ).expect("closures always return Ok"); + } + + pub fn try_chunks( + &mut self, + mut state: S, + mut proc_chunk: PC, + mut proc_tail: PT, + mut proc_res: PR, + ) -> Result<(), E> + where + T: Clone + Default, + N: ArrayLength + 'static, + PC: FnMut(&mut S, &GenericArray, &mut GenericArray) -> Result<(), E>, + PT: FnMut(&mut S, &[T], &mut GenericArray) -> Result<(), E>, + PR: FnMut(InResOutBuf<'_, '_, 'out_buf, T>), + { + let mut pos = 0; + let len = self.len; + while len - pos >= N::USIZE { + let mut res_chunk = GenericArray::::default(); + unsafe { + let in_chunk = &*(self.in_ptr.add(pos) as *const GenericArray); + proc_chunk(&mut state, in_chunk, &mut res_chunk)?; + proc_res(InResOutBuf::from_raw( + in_chunk.as_ptr(), + res_chunk.as_mut_ptr(), + self.out_ptr.add(pos), + N::USIZE, + )); + } + pos += N::USIZE + } + let rem = len - pos; + if rem != 0 { + let mut res_chunk = GenericArray::::default(); + unsafe { + let in_tail = slice::from_raw_parts(self.in_ptr.add(pos), rem); + proc_tail(&mut state, in_tail, &mut res_chunk)?; + proc_res(InResOutBuf::from_raw( + in_tail.as_ptr(), + res_chunk.as_mut_ptr(), + self.out_ptr.add(pos), + rem, + )); + } + } + Ok(()) + } + + /// Process elements in the inner buffers using the `f` callback. + /// + /// The first immutable reference passed to the callback is from the input + /// buffer, while the second mutable one is from output buffer. + pub fn process_pairs(&self, mut f: impl FnMut(&'in_buf T, &'out_buf mut T)) { + for i in 0..self.len { + // SAFETY: constructors guarantee that `in_ptr` and `out_ptr` + // point to slices of length `len` + unsafe { + f(& *(self.in_ptr.add(i)), &mut *(self.out_ptr.add(i))); + } + } + } + + /// Get lenght of the inner buffers. + #[inline] + pub fn len(&self) -> usize { + self.len + } + + pub fn get_in(&self) -> &'in_buf [T] { + unsafe { + slice::from_raw_parts(self.in_ptr, self.len) + } + } + + pub fn get_out(&mut self) -> &mut [T] { + unsafe { + slice::from_raw_parts_mut(self.out_ptr, self.len) + } + } +} + +pub struct InResOutBuf<'in_buf, 'res_buf, 'out_buf, T> { + in_ptr: *const T, + res_ptr: *mut T, + out_ptr: *mut T, + len: usize, + _pd: PhantomData<(&'in_buf T, &'res_buf T, &'out_buf mut T)>, +} + +impl<'in_buf, 'res_buf, 'out_buf, T: Clone> InResOutBuf<'in_buf, 'res_buf, 'out_buf, T> { + #[inline] + pub unsafe fn from_raw( + in_ptr: *const T, + res_ptr: *mut T, + out_ptr: *mut T, + len: usize, + ) -> Self { + Self { in_ptr, res_ptr, out_ptr, len, _pd: PhantomData } + } + + #[inline] + pub fn from_slices( + in_buf: &'in_buf [T], + res_buf: &'res_buf mut [T], + out_buf: &'out_buf mut [T] + ) -> Result { + let len = in_buf.len(); + if len != res_buf.len() || len != out_buf.len() { + Err(()) + } else { + Ok(Self { + in_ptr: in_buf.as_ptr(), + res_ptr: res_buf.as_mut_ptr(), + out_ptr: out_buf.as_mut_ptr(), + len, + _pd: PhantomData, + }) + } + + } + + #[inline] + pub fn from_arrays>( + in_buf: &'in_buf GenericArray, + res_buf: &'res_buf mut GenericArray, + out_buf: &'out_buf mut GenericArray, + ) -> Self { + Self { + in_ptr: in_buf.as_ptr(), + res_ptr: res_buf.as_mut_ptr(), + out_ptr: out_buf.as_mut_ptr(), + len: N::USIZE, + _pd: PhantomData, + } + } + + #[inline] + pub fn get_in_res(&mut self) -> (&'in_buf [T], &'res_buf mut [T]) { + let n = self.len; + unsafe { + ( + slice::from_raw_parts(self.in_ptr, n), + slice::from_raw_parts_mut(self.res_ptr, n), + ) + } + } + + #[inline] + pub fn get_res_out(&mut self) -> (&'res_buf mut [T], &'out_buf mut [T]) { + let n = self.len; + unsafe { + ( + slice::from_raw_parts_mut(self.res_ptr, n), + slice::from_raw_parts_mut(self.out_ptr, n), + ) + } + } + + /// Get lenght of the inner buffers. + #[inline] + pub fn len(&self) -> usize { + self.len + } +} + + +#[inline(always)] +pub fn copy_res2out(mut buf: InResOutBuf<'_, '_, '_, T>) { + let (res, out) = buf.get_res_out(); + out.copy_from_slice(res); +} + +#[inline(always)] +pub fn xor_inres2out>( + buf: InResOutBuf<'_, '_, '_, GenericArray>, +) { + // length of bufers in bytes + let n = N::USIZE * buf.len(); + let in_ptr = buf.in_ptr as *const u8; + let res_ptr = buf.res_ptr as *const u8; + let out_ptr = buf.out_ptr as *mut u8; + for i in 0..n { + unsafe { + *(out_ptr.add(i)) = *(in_ptr.add(i)) ^ *(res_ptr.add(i)); + } + } +} diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index da2951d87..853652b75 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -10,8 +10,8 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -#![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] +// #![forbid(unsafe_code)] +// #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "std")] extern crate std; @@ -23,113 +23,20 @@ mod block; #[cfg(feature = "dev")] mod dev; pub mod errors; -mod mode; mod stream; +mod inout; #[cfg(feature = "mode_wrapper")] mod mode_wrapper; -pub use crate::{block::*, mode::*, stream::*}; +pub use block::{ + AsyncStreamCipher, BlockCipher, BlockEncrypt, BlockDecrypt, + BlockEncryptMut, BlockDecryptMut, IvState, +}; +pub use inout::{InOutVal, InOutBuf, InResOutBuf}; +//StreamCipherCore, +pub use crate::{stream::*, inout::*}; +pub use crypto_common::{InnerIvInit, InnerInit, KeyInit, KeyIvInit, BlockProcessing, Block}; pub use generic_array::{self, typenum::consts}; #[cfg(feature = "mode_wrapper")] pub use mode_wrapper::{BlockModeDecryptWrapper, BlockModeEncryptWrapper}; - -use crate::errors::InvalidLength; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; - -// note: ideally the following traits would be defined in the `crypto-common` crate, -// but it would make impossible the generic impls over `T: FromBlockCipher(Nonce)` -// in the `block` module, see the following link for proposal to change it: -// https://internals.rust-lang.org/t/14125 - -/// Trait for types which can be created from key and nonce. -pub trait FromKeyNonce: Sized { - /// Key size in bytes. - type KeySize: ArrayLength; - - /// Nonce size in bytes. - type NonceSize: ArrayLength; - - /// Create new value from fixed length key and nonce. - fn new( - key: &GenericArray, - nonce: &GenericArray, - ) -> Self; - - /// Create new value from variable length key and nonce. - #[inline] - fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { - let kl = Self::KeySize::to_usize(); - let nl = Self::NonceSize::to_usize(); - if key.len() != kl || nonce.len() != nl { - Err(InvalidLength) - } else { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); - Ok(Self::new(key, nonce)) - } - } - - /// Generate a random key using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut key = GenericArray::::default(); - rng.fill_bytes(&mut key); - key - } - - /// Generate a random nonce using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_nonce(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut nonce = GenericArray::::default(); - rng.fill_bytes(&mut nonce); - nonce - } - - /// Generate random key and nonce using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key_nonce( - mut rng: impl CryptoRng + RngCore, - ) -> ( - GenericArray, - GenericArray, - ) { - (Self::generate_key(&mut rng), Self::generate_nonce(&mut rng)) - } -} - -/// Trait for types which can be created from key. -pub trait FromKey: Sized { - /// Key size in bytes. - type KeySize: ArrayLength; - - /// Create new value from fixed size key. - fn new(key: &GenericArray) -> Self; - - /// Create new value from variable size key. - fn new_from_slice(key: &[u8]) -> Result { - if key.len() != Self::KeySize::to_usize() { - Err(InvalidLength) - } else { - Ok(Self::new(GenericArray::from_slice(key))) - } - } - - /// Generate a random key using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut key = GenericArray::::default(); - rng.fill_bytes(&mut key); - key - } -} diff --git a/cipher/src/mode.rs b/cipher/src/mode.rs deleted file mode 100644 index 336f50cfa..000000000 --- a/cipher/src/mode.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::{BlockCipher, FromKeyNonce}; -use generic_array::{ArrayLength, GenericArray}; - -/// Trait for types which implement a block cipher [mode of operation][1]. -/// -/// [1]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation -pub trait BlockMode { - /// Size of the block in bytes - type BlockSize: ArrayLength; -} - -/// Trait for a block cipher mode of operation block-level encryptor. -/// -/// This trait operates only on blocks, for convinient slice-based methods with padding -/// see the [`BlockModeEncryptWrapper`][crate::BlockModeEncryptWrapper] type. -pub trait BlockModeEncrypt: BlockMode { - /// Encrypt blocks of data. - fn encrypt_blocks(&mut self, blocks: &mut [GenericArray]); -} - -/// Trait for a block cipher mode of operation block-level decryptor. -/// -/// This trait operates only on blocks, for convinient slice-based methods with padding -/// see the [`BlockModeDecryptWrapper`][crate::BlockModeDecryptWrapper] type. -pub trait BlockModeDecrypt: BlockMode { - /// Decrypt blocks of data. - fn decrypt_blocks(&mut self, blocks: &mut [GenericArray]); -} - -/// Trait for a block mode, used to obtain the current state in the form of an IV -/// that can initialize a BlockMode later and resume the original operation. -/// -/// The IV value SHOULD be used for resuming operations only and MUST NOT be -/// exposed to attackers. Failing to comply with this requirement breaks -/// unpredictability and opens attack venues (see e.g. [1], sec. 3.6.2). -/// -/// [1]: https://www.cs.umd.edu/~jkatz/imc.html -pub trait BlockModeIvState: FromKeyNonce { - /// Returns the IV needed to process the following block. This value MUST - /// NOT be exposed to attackers. - fn iv_state(&self) -> GenericArray; -} diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 3bea72828..6b8c9fe62 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -5,6 +5,43 @@ use crate::errors::{LoopError, OverflowError}; use core::convert::{TryFrom, TryInto}; +use generic_array::typenum::U1; +use crate::inout::{InOutBuf, InResOutBuf}; +use crypto_common::{BlockProcessing, Block}; + +/// Synchronous stream ciphers. +pub trait StreamCipherCore: BlockProcessing { + /// Generate next keystream block. + fn gen_keystream_block(&mut self) -> Result, LoopError>; + + /// Generate keystream blocks in parallel for provided data blocks. + fn gen_keystream_blocks( + &mut self, + mut blocks: InOutBuf<'_, '_, Block>, + proc: impl FnMut(InResOutBuf<'_, '_, '_, Block>), + ) -> Result<(), LoopError> { + blocks.try_chunks::( + self, + |state, _, res| state.gen_keystream_block().map(|b| res[0] = b), + |state, _, res| state.gen_keystream_block().map(|b| res[0] = b), + proc, + ) + } +} + +/// Counter-based synchronous stream ciphers. +/// +/// Such ciphers allow random access to an underlying keystream and can return +/// current position in it. +pub trait CounterStreamCipherCore: StreamCipherCore { + type Counter; + + /// Get current block position. + fn get_block_pos(&self) -> Self::Counter; + + /// Set current block position. + fn set_block_pos(&mut self, pos: Self::Counter); +} /// Synchronous stream cipher core trait. pub trait StreamCipher { diff --git a/crypto-common/src/core_api.rs b/crypto-common/src/core_api.rs index 7def7a076..f0485418e 100644 --- a/crypto-common/src/core_api.rs +++ b/crypto-common/src/core_api.rs @@ -1,20 +1,18 @@ //! Low-level core API traits. -use super::{FixedOutput, FixedOutputReset, Reset, Update}; +use super::{FixedOutput, FixedOutputReset, Reset, Update, BlockProcessing, Block}; use block_buffer::DigestBuffer; use core::fmt; use generic_array::{ArrayLength, GenericArray}; -/// Trait for types which consume data in blocks. +/// Types which consume data in blocks. #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] -pub trait UpdateCore { - /// Block size in bytes. - type BlockSize: ArrayLength; +pub trait UpdateCore: BlockProcessing { /// Block buffer type over which value operates. type Buffer: DigestBuffer; /// Update state using the provided data blocks. - fn update_blocks(&mut self, blocks: &[GenericArray]); + fn update_blocks(&mut self, blocks: &[Block]); } /// Core trait for hash functions with fixed output size. diff --git a/crypto-common/src/init.rs b/crypto-common/src/init.rs new file mode 100644 index 000000000..c84e544e7 --- /dev/null +++ b/crypto-common/src/init.rs @@ -0,0 +1,192 @@ +//! Traits related to types initialization. + +use core::fmt; +use generic_array::{ArrayLength, GenericArray, typenum::Unsigned}; + +/// Types which can be initialized from a key. +pub trait KeyInit: Sized { + /// Key size in bytes. + type KeySize: ArrayLength; + + /// Create new value from fixed size key. + fn new(key: &GenericArray) -> Self; + + /// Create new value from variable size key. + fn new_from_slice(key: &[u8]) -> Result { + if key.len() != Self::KeySize::to_usize() { + Err(InvalidLength) + } else { + Ok(Self::new(GenericArray::from_slice(key))) + } + } + + /// Generate a random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut key = GenericArray::::default(); + rng.fill_bytes(&mut key); + key + } +} + + +/// Types which can be initialized from key and initialization vector/nonce. +pub trait KeyIvInit: Sized { + /// Key size in bytes. + type KeySize: ArrayLength; + + /// Initialization vector size in bytes. + type IvSize: ArrayLength; + + /// Create new value from fixed length key and nonce. + fn new( + key: &GenericArray, + iv: &GenericArray, + ) -> Self; + + /// Create new value from variable length key and nonce. + #[inline] + fn new_from_slices(key: &[u8], iv: &[u8]) -> Result { + let kl = Self::KeySize::to_usize(); + let nl = Self::IvSize::to_usize(); + if key.len() != kl || iv.len() != nl { + Err(InvalidLength) + } else { + let key = GenericArray::from_slice(key); + let iv = GenericArray::from_slice(iv); + Ok(Self::new(key, iv)) + } + } + + /// Generate a random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut key = GenericArray::::default(); + rng.fill_bytes(&mut key); + key + } + + /// Generate a random IV using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_iv(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut iv = GenericArray::::default(); + rng.fill_bytes(&mut iv); + iv + } + + /// Generate random key and nonce using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key_iv( + mut rng: impl CryptoRng + RngCore, + ) -> ( + GenericArray, + GenericArray, + ) { + (Self::generate_key(&mut rng), Self::generate_iv(&mut rng)) + } +} + +/// Types which can be initialized from another type (usually block ciphers). +/// +/// Usually used for initializing types from block ciphers. +pub trait InnerInit: Sized { + /// Type used for initialization. + type Inner; + + /// Initialize value from the `inner`. + fn inner_init(inner: Self::Inner) -> Self; +} + +/// Types which can be initialized from another type and additional initialization +/// vector/nonce. +/// +/// Usually used for initializing types from block ciphers. +pub trait InnerIvInit: Sized { + /// Block cipher used for initialization. + type Inner; + /// Initialization vector size in bytes. + type IvSize: ArrayLength; + + /// Initialize value using `inner` and `iv` array. + fn inner_iv_init( + inner: Self::Inner, + iv: &GenericArray, + ) -> Self; + + /// Initialize value using `inner` and `iv` slice. + fn inner_iv_slice_init( + inner: Self::Inner, + iv: &[u8], + ) -> Result { + if iv.len() != Self::IvSize::to_usize() { + Err(InvalidLength) + } else { + Ok(Self::inner_iv_init(inner, GenericArray::from_slice(iv))) + } + } +} + +impl KeyIvInit for T +where + T: InnerIvInit, + T::Inner: KeyInit, +{ + type KeySize = ::KeySize; + type IvSize = T::IvSize; + + #[inline] + fn new( + key: &GenericArray, + iv: &GenericArray, + ) -> Self { + Self::inner_iv_init(T::Inner::new(key), iv) + } + + #[inline] + fn new_from_slices(key: &[u8], iv: &[u8]) -> Result { + T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv)) + } +} + +impl KeyInit for T +where + T: InnerInit, + T::Inner: KeyInit, +{ + type KeySize = ::KeySize; + + #[inline] + fn new(key: &GenericArray) -> Self { + Self::inner_init(T::Inner::new(key)) + } + + #[inline] + fn new_from_slice(key: &[u8]) -> Result { + T::Inner::new_from_slice(key) + .map_err(|_| InvalidLength) + .map(Self::inner_init) + } +} + +/// The error type returned when key and/or IV used in the [`FromKey`] +/// and [`FromKeyIv`] slice-based methods had an invalid length. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct InvalidLength; + +impl fmt::Display for InvalidLength { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Invalid Length") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for InvalidLength {} + diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 5869bc677..b080307ee 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -18,11 +18,27 @@ use generic_array::{ArrayLength, GenericArray}; #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub use block_buffer; +mod init; +pub use init::{KeyIvInit, KeyInit, InnerInit, InnerIvInit}; + #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub mod core_api; -/// Trait for types which consume data. +/// Types which process data in blocks. +pub trait BlockProcessing { + /// Size of the block in bytes. + type BlockSize: ArrayLength + 'static; +} + +/// Block on which a [`BlockProcessing`] operates. +pub type Block = GenericArray::BlockSize>; + +impl BlockProcessing for &Alg { + type BlockSize = Alg::BlockSize; +} + +/// Types which consume data. pub trait Update { /// Update state using the provided data. fn update(&mut self, data: &[u8]); From 27f27ad2370a5379fa4d228269a43b11a802e5f9 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?= Date: Mon, 12 Apr 2021 16:37:09 +0300 Subject: [PATCH 2/6] clippy and fmt --- cipher/src/block.rs | 10 ++--- cipher/src/dev/block.rs | 4 +- cipher/src/errors.rs | 13 ++++++ cipher/src/inout.rs | 82 +++++++++++++++++++---------------- cipher/src/lib.rs | 12 ++--- cipher/src/stream.rs | 10 ++--- crypto-common/src/core_api.rs | 2 +- crypto-common/src/init.rs | 24 +++------- crypto-common/src/lib.rs | 2 +- 9 files changed, 81 insertions(+), 78 deletions(-) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 233150b89..5bf086b02 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -9,9 +9,9 @@ //! [1]: https://en.wikipedia.org/wiki/Block_cipher //! [2]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation //! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm -pub use crypto_common::{BlockProcessing, Block, InnerIvInit}; -use crate::inout::{InOutVal, InOutBuf, InResOutBuf}; -use generic_array::{GenericArray, typenum::U1}; +use crate::inout::{InOutBuf, InOutVal, InResOutBuf}; +pub use crypto_common::{Block, BlockProcessing, InnerIvInit}; +use generic_array::{typenum::U1, GenericArray}; /// Marker trait for types which represent block ciphers. /// @@ -52,7 +52,7 @@ pub trait BlockDecrypt: BlockProcessing { /// Decrypt the provided block. /// /// Usually `block` is either `&mut Block`, or `(&Block, &mut Block)`. - fn decrypt_block(&self, block: impl InOutVal>,); + fn decrypt_block(&self, block: impl InOutVal>); /// Decrypt provided blocks in parallel. fn decrypt_blocks( @@ -128,10 +128,8 @@ pub trait IvState: InnerIvInit { fn iv_state(&self) -> GenericArray; } - // =========================== BLANKET IMPLS =========================== - impl BlockCipher for &T {} impl BlockCipher for &mut T {} diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index f4d53980b..16f39e2a5 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -10,9 +10,7 @@ macro_rules! block_cipher_test { #[test] fn $name() { use cipher::generic_array::{typenum::Unsigned, GenericArray}; - use cipher::{ - blobby::Blob3Iterator, BlockDecrypt, BlockEncrypt, KeyInit, - }; + use cipher::{blobby::Blob3Iterator, BlockDecrypt, BlockEncrypt, KeyInit}; fn run_single_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { let state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index f6ede6ee9..b21ce5f82 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -51,3 +51,16 @@ impl fmt::Display for BlockModeError { #[cfg(feature = "std")] impl std::error::Error for BlockModeError {} + +/// The error type for methods which require slices of equal length. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct NotEqualError; + +impl fmt::Display for NotEqualError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Length of slices is not equal") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for NotEqualError {} diff --git a/cipher/src/inout.rs b/cipher/src/inout.rs index 8f5e78cae..f10a18c88 100644 --- a/cipher/src/inout.rs +++ b/cipher/src/inout.rs @@ -1,6 +1,7 @@ -use generic_array::{GenericArray, ArrayLength}; +use crate::errors::NotEqualError; use core::marker::PhantomData; use core::slice; +use generic_array::{ArrayLength, GenericArray}; // TODO: rename to InOutRef pub trait InOutVal { @@ -62,14 +63,15 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { /// /// Panics if `mid > len`. #[inline] - pub fn split_at(self, mid: usize) -> ( + pub fn split_at( + self, + mid: usize, + ) -> ( InOutBuf<'in_buf, 'out_buf, T>, InOutBuf<'in_buf, 'out_buf, T>, ) { assert!(mid <= self.len); - let (tail_in_ptr, tail_out_ptr) = unsafe { - (self.in_ptr.add(mid), self.out_ptr.add(mid)) - }; + let (tail_in_ptr, tail_out_ptr) = unsafe { (self.in_ptr.add(mid), self.out_ptr.add(mid)) }; ( InOutBuf { in_ptr: self.in_ptr, @@ -82,21 +84,22 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { out_ptr: tail_out_ptr, len: self.len() - mid, _pd: PhantomData, - } + }, ) } /// Partitions buffer into 2 parts: body of arrays and tail. #[inline] - pub fn to_blocks>(self) -> ( + pub fn into_blocks>( + self, + ) -> ( InOutBuf<'in_buf, 'out_buf, GenericArray>, InOutBuf<'in_buf, 'out_buf, T>, ) { let nb = self.len() / N::USIZE; let body_len = nb * N::USIZE; - let (tail_in_ptr, tail_out_ptr) = unsafe { - (self.in_ptr.add(body_len), self.out_ptr.add(body_len)) - }; + let (tail_in_ptr, tail_out_ptr) = + unsafe { (self.in_ptr.add(body_len), self.out_ptr.add(body_len)) }; ( InOutBuf { in_ptr: self.in_ptr as *const GenericArray, @@ -109,7 +112,7 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { out_ptr: tail_out_ptr, len: self.len() - body_len, _pd: PhantomData, - } + }, ) } @@ -136,7 +139,6 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { len: 1, _pd: PhantomData, } - } /// Create a new value from slices. @@ -144,9 +146,9 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { /// Returns an error if length of slices is not equal to each other. // TODO: add error type #[inline] - pub fn new(in_buf: &'in_buf [T], out_buf: &'out_buf mut [T]) -> Result { + pub fn new(in_buf: &'in_buf [T], out_buf: &'out_buf mut [T]) -> Result { if in_buf.len() != out_buf.len() { - Err(()) + Err(NotEqualError) } else { Ok(Self { in_ptr: in_buf.as_ptr(), @@ -155,7 +157,6 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { _pd: Default::default(), }) } - } pub fn chunks( @@ -164,8 +165,7 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { mut proc_chunk: PC, mut proc_tail: PT, proc_res: PR, - ) - where + ) where T: Clone + Default, N: ArrayLength + 'static, PC: FnMut(&mut S, &GenericArray, &mut GenericArray), @@ -183,7 +183,8 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { Ok(()) }, proc_res, - ).expect("closures always return Ok"); + ) + .expect("closures always return Ok"); } pub fn try_chunks( @@ -242,7 +243,7 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { // SAFETY: constructors guarantee that `in_ptr` and `out_ptr` // point to slices of length `len` unsafe { - f(& *(self.in_ptr.add(i)), &mut *(self.out_ptr.add(i))); + f(&*(self.in_ptr.add(i)), &mut *(self.out_ptr.add(i))); } } } @@ -253,16 +254,18 @@ impl<'in_buf, 'out_buf, T> InOutBuf<'in_buf, 'out_buf, T> { self.len } + /// Returns `true` if `self` has a length of zero elements. + #[inline] + pub fn is_empty(&self) -> bool { + self.len == 0 + } + pub fn get_in(&self) -> &'in_buf [T] { - unsafe { - slice::from_raw_parts(self.in_ptr, self.len) - } + unsafe { slice::from_raw_parts(self.in_ptr, self.len) } } pub fn get_out(&mut self) -> &mut [T] { - unsafe { - slice::from_raw_parts_mut(self.out_ptr, self.len) - } + unsafe { slice::from_raw_parts_mut(self.out_ptr, self.len) } } } @@ -276,24 +279,25 @@ pub struct InResOutBuf<'in_buf, 'res_buf, 'out_buf, T> { impl<'in_buf, 'res_buf, 'out_buf, T: Clone> InResOutBuf<'in_buf, 'res_buf, 'out_buf, T> { #[inline] - pub unsafe fn from_raw( - in_ptr: *const T, - res_ptr: *mut T, - out_ptr: *mut T, - len: usize, - ) -> Self { - Self { in_ptr, res_ptr, out_ptr, len, _pd: PhantomData } + unsafe fn from_raw(in_ptr: *const T, res_ptr: *mut T, out_ptr: *mut T, len: usize) -> Self { + Self { + in_ptr, + res_ptr, + out_ptr, + len, + _pd: PhantomData, + } } #[inline] pub fn from_slices( in_buf: &'in_buf [T], res_buf: &'res_buf mut [T], - out_buf: &'out_buf mut [T] - ) -> Result { + out_buf: &'out_buf mut [T], + ) -> Result { let len = in_buf.len(); if len != res_buf.len() || len != out_buf.len() { - Err(()) + Err(NotEqualError) } else { Ok(Self { in_ptr: in_buf.as_ptr(), @@ -303,7 +307,6 @@ impl<'in_buf, 'res_buf, 'out_buf, T: Clone> InResOutBuf<'in_buf, 'res_buf, 'out_ _pd: PhantomData, }) } - } #[inline] @@ -348,8 +351,13 @@ impl<'in_buf, 'res_buf, 'out_buf, T: Clone> InResOutBuf<'in_buf, 'res_buf, 'out_ pub fn len(&self) -> usize { self.len } -} + /// Returns `true` if `self` has a length of zero elements. + #[inline] + pub fn is_empty(&self) -> bool { + self.len == 0 + } +} #[inline(always)] pub fn copy_res2out(mut buf: InResOutBuf<'_, '_, '_, T>) { diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 853652b75..ca35ef1fe 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -23,20 +23,20 @@ mod block; #[cfg(feature = "dev")] mod dev; pub mod errors; -mod stream; mod inout; +mod stream; #[cfg(feature = "mode_wrapper")] mod mode_wrapper; pub use block::{ - AsyncStreamCipher, BlockCipher, BlockEncrypt, BlockDecrypt, - BlockEncryptMut, BlockDecryptMut, IvState, + AsyncStreamCipher, BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, + IvState, }; -pub use inout::{InOutVal, InOutBuf, InResOutBuf}; +pub use inout::{InOutBuf, InOutVal, InResOutBuf}; //StreamCipherCore, -pub use crate::{stream::*, inout::*}; -pub use crypto_common::{InnerIvInit, InnerInit, KeyInit, KeyIvInit, BlockProcessing, Block}; +pub use crate::{inout::*, stream::*}; +pub use crypto_common::{Block, BlockProcessing, InnerInit, InnerIvInit, KeyInit, KeyIvInit}; pub use generic_array::{self, typenum::consts}; #[cfg(feature = "mode_wrapper")] pub use mode_wrapper::{BlockModeDecryptWrapper, BlockModeEncryptWrapper}; diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 6b8c9fe62..7ad5cf489 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -4,10 +4,10 @@ //! for ciphers implementation. use crate::errors::{LoopError, OverflowError}; +use crate::inout::{InOutBuf, InResOutBuf}; use core::convert::{TryFrom, TryInto}; +use crypto_common::{Block, BlockProcessing}; use generic_array::typenum::U1; -use crate::inout::{InOutBuf, InResOutBuf}; -use crypto_common::{BlockProcessing, Block}; /// Synchronous stream ciphers. pub trait StreamCipherCore: BlockProcessing { @@ -33,7 +33,7 @@ pub trait StreamCipherCore: BlockProcessing { /// /// Such ciphers allow random access to an underlying keystream and can return /// current position in it. -pub trait CounterStreamCipherCore: StreamCipherCore { +pub trait CtrBasedStreamCipherCore: StreamCipherCore { type Counter; /// Get current block position. @@ -142,7 +142,7 @@ pub trait SeekNum: 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 to_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; + fn to_block_byte(&self, bs: u8) -> Result<(T, u8), OverflowError>; } macro_rules! impl_seek_num { @@ -156,7 +156,7 @@ macro_rules! impl_seek_num { Ok(pos) } - fn to_block_byte>(self, bs: u8) -> Result<(T, u8), OverflowError> { + fn to_block_byte>(&self, bs: u8) -> Result<(T, u8), OverflowError> { let bs = bs as Self; let byte = self % bs; let block = T::try_from(self/bs).map_err(|_| OverflowError)?; diff --git a/crypto-common/src/core_api.rs b/crypto-common/src/core_api.rs index f0485418e..167c59cf0 100644 --- a/crypto-common/src/core_api.rs +++ b/crypto-common/src/core_api.rs @@ -1,5 +1,5 @@ //! Low-level core API traits. -use super::{FixedOutput, FixedOutputReset, Reset, Update, BlockProcessing, Block}; +use super::{Block, BlockProcessing, FixedOutput, FixedOutputReset, Reset, Update}; use block_buffer::DigestBuffer; use core::fmt; use generic_array::{ArrayLength, GenericArray}; diff --git a/crypto-common/src/init.rs b/crypto-common/src/init.rs index c84e544e7..26d429b78 100644 --- a/crypto-common/src/init.rs +++ b/crypto-common/src/init.rs @@ -1,7 +1,7 @@ //! Traits related to types initialization. use core::fmt; -use generic_array::{ArrayLength, GenericArray, typenum::Unsigned}; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Types which can be initialized from a key. pub trait KeyInit: Sized { @@ -31,7 +31,6 @@ pub trait KeyInit: Sized { } } - /// Types which can be initialized from key and initialization vector/nonce. pub trait KeyIvInit: Sized { /// Key size in bytes. @@ -41,10 +40,7 @@ pub trait KeyIvInit: Sized { type IvSize: ArrayLength; /// Create new value from fixed length key and nonce. - fn new( - key: &GenericArray, - iv: &GenericArray, - ) -> Self; + fn new(key: &GenericArray, iv: &GenericArray) -> Self; /// Create new value from variable length key and nonce. #[inline] @@ -116,16 +112,10 @@ pub trait InnerIvInit: Sized { type IvSize: ArrayLength; /// Initialize value using `inner` and `iv` array. - fn inner_iv_init( - inner: Self::Inner, - iv: &GenericArray, - ) -> Self; + fn inner_iv_init(inner: Self::Inner, iv: &GenericArray) -> Self; /// Initialize value using `inner` and `iv` slice. - fn inner_iv_slice_init( - inner: Self::Inner, - iv: &[u8], - ) -> Result { + fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result { if iv.len() != Self::IvSize::to_usize() { Err(InvalidLength) } else { @@ -143,10 +133,7 @@ where type IvSize = T::IvSize; #[inline] - fn new( - key: &GenericArray, - iv: &GenericArray, - ) -> Self { + fn new(key: &GenericArray, iv: &GenericArray) -> Self { Self::inner_iv_init(T::Inner::new(key), iv) } @@ -189,4 +176,3 @@ impl fmt::Display for InvalidLength { #[cfg(feature = "std")] impl std::error::Error for InvalidLength {} - diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index b080307ee..7b06d0aab 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -19,7 +19,7 @@ use generic_array::{ArrayLength, GenericArray}; pub use block_buffer; mod init; -pub use init::{KeyIvInit, KeyInit, InnerInit, InnerIvInit}; +pub use init::{InnerInit, InnerIvInit, KeyInit, KeyIvInit}; #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] From 11f63beed5e223ceb3d2f4f40a6673386de2364d 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?= Date: Mon, 12 Apr 2021 16:45:12 +0300 Subject: [PATCH 3/6] update crypto-mac --- Cargo.lock | 1 - crypto-common/src/errors.rs | 15 +++++++++++++++ crypto-common/src/init.rs | 16 +--------------- crypto-common/src/lib.rs | 2 ++ crypto-mac/Cargo.toml | 1 - crypto-mac/src/lib.rs | 9 ++++----- 6 files changed, 22 insertions(+), 22 deletions(-) create mode 100644 crypto-common/src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index a60ffc880..df81926ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,6 @@ name = "crypto-mac" version = "0.11.0-pre" dependencies = [ "blobby", - "cipher", "crypto-common", "generic-array 0.14.4", "rand_core", diff --git a/crypto-common/src/errors.rs b/crypto-common/src/errors.rs new file mode 100644 index 000000000..379acdef7 --- /dev/null +++ b/crypto-common/src/errors.rs @@ -0,0 +1,15 @@ +use core::fmt; + +/// The error type returned when key and/or IV used in the [`FromKey`] +/// and [`FromKeyIv`] slice-based methods had an invalid length. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct InvalidLength; + +impl fmt::Display for InvalidLength { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Invalid Length") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for InvalidLength {} diff --git a/crypto-common/src/init.rs b/crypto-common/src/init.rs index 26d429b78..71fb58c32 100644 --- a/crypto-common/src/init.rs +++ b/crypto-common/src/init.rs @@ -1,7 +1,7 @@ //! Traits related to types initialization. -use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use crate::InvalidLength; /// Types which can be initialized from a key. pub trait KeyInit: Sized { @@ -162,17 +162,3 @@ where .map(Self::inner_init) } } - -/// The error type returned when key and/or IV used in the [`FromKey`] -/// and [`FromKeyIv`] slice-based methods had an invalid length. -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub struct InvalidLength; - -impl fmt::Display for InvalidLength { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("Invalid Length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidLength {} diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 7b06d0aab..5c74945cf 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -20,6 +20,8 @@ pub use block_buffer; mod init; pub use init::{InnerInit, InnerIvInit, KeyInit, KeyIvInit}; +mod errors; +pub use errors::InvalidLength; #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 4c367b963..8168c2bdc 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -14,7 +14,6 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" crypto-common = { version = "0.1", path = "../crypto-common/" } -cipher = { version = "0.3.0-pre.4", path = "../cipher/" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 5020bc7a9..6c84cc35b 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -25,8 +25,7 @@ pub mod dev; #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub mod core_api; -pub use cipher::{errors::InvalidLength, FromKey}; -pub use crypto_common::{FixedOutput, FixedOutputReset, Reset, Update}; +pub use crypto_common::{InvalidLength, KeyInit, FixedOutput, FixedOutputReset, Reset, Update}; pub use generic_array::{self, typenum::consts}; use core::fmt; @@ -34,10 +33,10 @@ use generic_array::GenericArray; use subtle::{Choice, ConstantTimeEq}; /// Key for an algorithm that implements [`FromKey`]. -pub type Key = GenericArray::KeySize>; +pub type Key = GenericArray::KeySize>; /// Convinience super-trait covering functionality of Message Authentication algorithms. -pub trait Mac: FromKey + Update + FixedOutput { +pub trait Mac: KeyInit + Update + FixedOutput { /// Obtain the result of a [`Mac`] computation as a [`Output`] and consume /// [`Mac`] instance. fn finalize(self) -> Output { @@ -65,7 +64,7 @@ pub trait Mac: FromKey + Update + FixedOutput { } } -impl Mac for T {} +impl Mac for T {} /// [`Output`] is a thin wrapper around bytes array which provides a safe `Eq` /// implementation that runs in a fixed time. From 4f40e64d60670fff32d7a19fff0685cd393d22b3 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?= Date: Mon, 12 Apr 2021 16:53:58 +0300 Subject: [PATCH 4/6] update digest --- digest/src/core_api.rs | 10 ++++------ digest/src/core_api/ct_variable.rs | 14 +++++++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index 63e573d33..951912830 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -5,8 +5,9 @@ //! higher-level traits. use crate::InvalidOutputSize; use crate::{ExtendableOutput, Reset}; -use generic_array::{ArrayLength, GenericArray}; +use generic_array::ArrayLength; +pub use crypto_common::{BlockProcessing, Block}; pub use crypto_common::core_api::{AlgorithmName, CoreWrapper, FixedOutputCore, UpdateCore}; mod ct_variable; @@ -28,12 +29,9 @@ pub trait ExtendableOutputCore: UpdateCore { } /// Core reader trait for extendable-output function (XOF) result. -pub trait XofReaderCore { - /// Block size in bytes. - type BlockSize: ArrayLength; - +pub trait XofReaderCore: BlockProcessing { /// Read next XOF block. - fn read_block(&mut self) -> GenericArray; + fn read_block(&mut self) -> Block; } /// Core trait for hash functions with variable output size. diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 11474326f..b68fe7d35 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -1,4 +1,4 @@ -use super::{AlgorithmName, FixedOutputCore, Reset, UpdateCore, VariableOutputCore}; +use super::{AlgorithmName, FixedOutputCore, Reset, UpdateCore, VariableOutputCore, BlockProcessing, Block}; use core::{fmt, marker::PhantomData}; use generic_array::{ typenum::{IsLessOrEqual, LeEq, NonZero}, @@ -18,17 +18,25 @@ where _out: PhantomData, } -impl UpdateCore for CtVariableCoreWrapper +impl BlockProcessing for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, { type BlockSize = T::BlockSize; +} + +impl UpdateCore for CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, +{ type Buffer = T::Buffer; #[inline] - fn update_blocks(&mut self, blocks: &[GenericArray]) { + fn update_blocks(&mut self, blocks: &[Block]) { self.inner.update_blocks(blocks); } } From 414accc41d9a55015cbba1f8354cacad23239a4c 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?= Date: Mon, 12 Apr 2021 17:04:52 +0300 Subject: [PATCH 5/6] fmt --- crypto-common/src/init.rs | 2 +- crypto-mac/src/lib.rs | 2 +- digest/src/core_api.rs | 2 +- digest/src/core_api/ct_variable.rs | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/crypto-common/src/init.rs b/crypto-common/src/init.rs index 71fb58c32..b65683c50 100644 --- a/crypto-common/src/init.rs +++ b/crypto-common/src/init.rs @@ -1,7 +1,7 @@ //! Traits related to types initialization. -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; use crate::InvalidLength; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Types which can be initialized from a key. pub trait KeyInit: Sized { diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 6c84cc35b..c2b7f8974 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -25,7 +25,7 @@ pub mod dev; #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub mod core_api; -pub use crypto_common::{InvalidLength, KeyInit, FixedOutput, FixedOutputReset, Reset, Update}; +pub use crypto_common::{FixedOutput, FixedOutputReset, InvalidLength, KeyInit, Reset, Update}; pub use generic_array::{self, typenum::consts}; use core::fmt; diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index 951912830..84b429c4d 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -7,8 +7,8 @@ use crate::InvalidOutputSize; use crate::{ExtendableOutput, Reset}; use generic_array::ArrayLength; -pub use crypto_common::{BlockProcessing, Block}; pub use crypto_common::core_api::{AlgorithmName, CoreWrapper, FixedOutputCore, UpdateCore}; +pub use crypto_common::{Block, BlockProcessing}; mod ct_variable; mod rt_variable; diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index b68fe7d35..22c2b5059 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -1,4 +1,6 @@ -use super::{AlgorithmName, FixedOutputCore, Reset, UpdateCore, VariableOutputCore, BlockProcessing, Block}; +use super::{ + AlgorithmName, Block, BlockProcessing, FixedOutputCore, Reset, UpdateCore, VariableOutputCore, +}; use core::{fmt, marker::PhantomData}; use generic_array::{ typenum::{IsLessOrEqual, LeEq, NonZero}, From 225f4eead718214ea35a3dd95860c62bcb47fb9a 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?= Date: Mon, 12 Apr 2021 17:07:34 +0300 Subject: [PATCH 6/6] aead fmt --- aead/src/stream.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/aead/src/stream.rs b/aead/src/stream.rs index c61b76fb1..170904559 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -226,7 +226,7 @@ macro_rules! impl_stream_object { pub fn new(key: &Key, nonce: &Nonce) -> Self where A: NewAead, - S: NewStream + S: NewStream, { Self::from_stream_primitive(S::new(key, nonce)) } @@ -237,7 +237,7 @@ macro_rules! impl_stream_object { pub fn from_aead(aead: A, nonce: &Nonce) -> Self where A: NewAead, - S: NewStream + S: NewStream, { Self::from_stream_primitive(S::from_aead(aead, nonce)) } @@ -291,7 +291,8 @@ macro_rules! impl_stream_object { return Err(Error); } - self.stream.$in_place_op(self.position, false, associated_data, buffer)?; + self.stream + .$in_place_op(self.position, false, associated_data, buffer)?; // Note: overflow checked above self.position += S::COUNTER_INCR; @@ -322,12 +323,13 @@ macro_rules! impl_stream_object { pub fn $last_in_place_method( self, associated_data: &[u8], - buffer: &mut dyn Buffer + buffer: &mut dyn Buffer, ) -> Result<(), Error> { - self.stream.$in_place_op(self.position, true, associated_data, buffer) + self.stream + .$in_place_op(self.position, true, associated_data, buffer) } } - } + }; } impl_stream_object!(