diff --git a/cipher/src/async_stream.rs b/cipher/src/async_stream.rs new file mode 100644 index 000000000..aeada2184 --- /dev/null +++ b/cipher/src/async_stream.rs @@ -0,0 +1,57 @@ +//! Traits which define functionality of asynchronous (a.k.a. self-synchronizing) stream ciphers. + +use crate::block::{BlockModeDecrypt, BlockModeEncrypt}; +use crypto_common::Block; +use inout::{InOutBuf, NotEqualError}; + +/// Asynchronous stream cipher encryptor. +pub trait AsyncStreamCipherCoreEncrypt: BlockModeEncrypt { + /// Encrypt data using `InOutBuf`. + fn encrypt_inout(mut self, data: InOutBuf<'_, '_, u8>) { + let (blocks, mut tail) = data.into_chunks(); + self.encrypt_blocks_inout(blocks); + let n = tail.len(); + if n != 0 { + let mut block = Block::::default(); + block[..n].copy_from_slice(tail.get_in()); + self.encrypt_block(&mut block); + tail.get_out().copy_from_slice(&block[..n]); + } + } + + /// Encrypt data in place. + fn encrypt(self, buf: &mut [u8]) { + self.encrypt_inout(buf.into()); + } + + /// Encrypt data from buffer to buffer. + fn encrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> { + InOutBuf::new(in_buf, out_buf).map(|b| self.encrypt_inout(b)) + } +} + +/// Asynchronous stream cipher decryptor. +pub trait AsyncStreamCipherCoreDecrypt: BlockModeDecrypt { + /// Decrypt data using `InOutBuf`. + fn decrypt_inout(mut self, data: InOutBuf<'_, '_, u8>) { + let (blocks, mut tail) = data.into_chunks(); + self.decrypt_blocks_inout(blocks); + let n = tail.len(); + if n != 0 { + let mut block = Block::::default(); + block[..n].copy_from_slice(tail.get_in()); + self.decrypt_block(&mut block); + tail.get_out().copy_from_slice(&block[..n]); + } + } + + /// Decrypt data in place. + fn decrypt(self, buf: &mut [u8]) { + self.decrypt_inout(buf.into()); + } + + /// Decrypt data from buffer to buffer. + fn decrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> { + InOutBuf::new(in_buf, out_buf).map(|b| self.decrypt_inout(b)) + } +} diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 3f76b6e02..c408fe0a8 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -33,6 +33,7 @@ pub use inout::block_padding; #[cfg(feature = "zeroize")] pub use zeroize; +pub mod async_stream; pub mod block; #[cfg(feature = "dev")] pub mod dev; diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index baa8facbc..f388694de 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -3,8 +3,6 @@ //! See the [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) repository //! for ciphers implementation. -use crate::block::{BlockModeDecrypt, BlockModeEncrypt}; -use crypto_common::Block; use inout::{InOutBuf, NotEqualError}; mod core_api; @@ -20,72 +18,6 @@ pub use errors::{OverflowError, StreamCipherError}; #[cfg(feature = "stream-wrapper")] pub use wrapper::StreamCipherCoreWrapper; -/// Asynchronous stream cipher trait. -pub trait AsyncStreamCipher: Sized { - /// Encrypt data using `InOutBuf`. - fn encrypt_inout(mut self, data: InOutBuf<'_, '_, u8>) - where - Self: BlockModeEncrypt, - { - let (blocks, mut tail) = data.into_chunks(); - self.encrypt_blocks_inout(blocks); - let n = tail.len(); - if n != 0 { - let mut block = Block::::default(); - block[..n].copy_from_slice(tail.get_in()); - self.encrypt_block(&mut block); - tail.get_out().copy_from_slice(&block[..n]); - } - } - - /// Decrypt data using `InOutBuf`. - fn decrypt_inout(mut self, data: InOutBuf<'_, '_, u8>) - where - Self: BlockModeDecrypt, - { - let (blocks, mut tail) = data.into_chunks(); - self.decrypt_blocks_inout(blocks); - let n = tail.len(); - if n != 0 { - let mut block = Block::::default(); - block[..n].copy_from_slice(tail.get_in()); - self.decrypt_block(&mut block); - tail.get_out().copy_from_slice(&block[..n]); - } - } - /// Encrypt data in place. - fn encrypt(self, buf: &mut [u8]) - where - Self: BlockModeEncrypt, - { - self.encrypt_inout(buf.into()); - } - - /// Decrypt data in place. - fn decrypt(self, buf: &mut [u8]) - where - Self: BlockModeDecrypt, - { - self.decrypt_inout(buf.into()); - } - - /// Encrypt data from buffer to buffer. - fn encrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> - where - Self: BlockModeEncrypt, - { - InOutBuf::new(in_buf, out_buf).map(|b| self.encrypt_inout(b)) - } - - /// Decrypt data from buffer to buffer. - fn decrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> - where - Self: BlockModeDecrypt, - { - InOutBuf::new(in_buf, out_buf).map(|b| self.decrypt_inout(b)) - } -} - /// Stream cipher trait. /// /// This trait applies only to synchronous stream ciphers, which generate a keystream and