From 8181ac7b55ffddc536ec03aae59fe8882352e064 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 4 Feb 2026 10:31:32 -0700 Subject: [PATCH] cipher: use workspace level `clippy` config Enables the workspace-level config added in #2270 and fixes violations --- cipher/Cargo.toml | 4 ++- cipher/src/block.rs | 22 ++++++++---- cipher/src/dev/block_cipher.rs | 4 +++ cipher/src/dev/block_mode.rs | 2 ++ cipher/src/dev/stream.rs | 3 ++ cipher/src/lib.rs | 6 ---- cipher/src/stream.rs | 65 +++++++++++++++++++++++++++------- cipher/src/stream/core_api.rs | 6 ++-- cipher/src/stream/wrapper.rs | 5 +-- cipher/src/tweak/zero.rs | 4 +-- cipher/tests/stream.rs | 4 +++ 11 files changed, 93 insertions(+), 32 deletions(-) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index b5013ff86..cd73127af 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -28,11 +28,13 @@ hex-literal = "1" alloc = [] block-padding = ["inout/block-padding"] stream-wrapper = ["block-buffer"] -# Enable random key and IV generation methods getrandom = ["common/getrandom"] rand_core = ["common/rand_core"] dev = ["blobby"] zeroize = ["dep:zeroize", "common/zeroize", "block-buffer?/zeroize"] +[lints] +workspace = true + [package.metadata.docs.rs] all-features = true diff --git a/cipher/src/block.rs b/cipher/src/block.rs index b44bd9b3f..9f0008d12 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -70,6 +70,7 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized { /// Encrypt blocks buffer-to-buffer. /// + /// # Errors /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` /// have different lengths. #[inline] @@ -123,6 +124,7 @@ pub trait BlockCipherDecrypt: BlockSizeUser { /// Decrypt blocks buffer-to-buffer. /// + /// # Errors /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` /// have different lengths. #[inline] @@ -192,6 +194,7 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// Encrypt blocks buffer-to-buffer. /// + /// # Errors /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` /// have different lengths. #[inline] @@ -206,6 +209,7 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// Pad input and encrypt. Returns resulting ciphertext slice. /// + /// # Errors /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] #[inline] @@ -223,6 +227,7 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// Pad input and encrypt in-place. Returns resulting ciphertext slice. /// + /// # Errors /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] #[inline] @@ -233,6 +238,7 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// Pad input and encrypt buffer-to-buffer. Returns resulting ciphertext slice. /// + /// # Errors /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] #[inline] @@ -262,12 +268,11 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { let pad_type_id = TypeId::of::

(); let buf_blocks_len = if pad_type_id == TypeId::of::() { - if msg_len % bs != 0 { - panic!( - "NoPadding is used with a {msg_len}‑byte message, - which is not a multiple of the {bs}‑byte cipher block size" - ); - } + assert!( + msg_len % bs == 0, + "NoPadding is used with a {msg_len}‑byte message, + which is not a multiple of the {bs}‑byte cipher block size" + ); msg_len / bs } else if pad_type_id == TypeId::of::() { msg_len.div_ceil(bs) @@ -329,6 +334,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { /// Decrypt blocks buffer-to-buffer. /// + /// # Errors /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` /// have different lengths. #[inline] @@ -343,6 +349,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { /// Decrypt input and unpad it. Returns resulting plaintext slice. /// + /// # Errors /// Returns [`block_padding::Error`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] @@ -361,6 +368,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { /// Decrypt input and unpad it in-place. Returns resulting plaintext slice. /// + /// # Errors /// Returns [`block_padding::Error`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] @@ -372,6 +380,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { /// Decrypt input and unpad it buffer-to-buffer. Returns resulting /// plaintext slice. /// + /// # Errors /// Returns [`block_padding::Error`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] @@ -393,6 +402,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { /// Decrypt input and unpad it in a newly allocated Vec. Returns resulting /// plaintext `Vec`. /// + /// # Errors /// Returns [`block_padding::Error`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(all(feature = "block-padding", feature = "alloc"))] diff --git a/cipher/src/dev/block_cipher.rs b/cipher/src/dev/block_cipher.rs index 5c91a785d..ae6739c42 100644 --- a/cipher/src/dev/block_cipher.rs +++ b/cipher/src/dev/block_cipher.rs @@ -1,5 +1,7 @@ //! Development-related functionality for block ciphers +#![allow(clippy::missing_errors_doc)] + use crate::{Block, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; /// Block cipher test vector @@ -24,6 +26,7 @@ fn encrypt_test_inner( return Err("single block encryption failure"); } + #[allow(clippy::cast_possible_truncation)] let mut blocks1: [Block; 101] = core::array::from_fn(|i| { let mut block = pt.clone(); block[0] ^= i as u8; @@ -54,6 +57,7 @@ fn decrypt_test_inner( return Err("single block decryption failure"); } + #[allow(clippy::cast_possible_truncation)] let mut blocks1: [Block; 101] = core::array::from_fn(|i| { let mut block = ct.clone(); block[0] ^= i as u8; diff --git a/cipher/src/dev/block_mode.rs b/cipher/src/dev/block_mode.rs index 1ac8e9ec2..81a8f0cd9 100644 --- a/cipher/src/dev/block_mode.rs +++ b/cipher/src/dev/block_mode.rs @@ -1,5 +1,7 @@ //! Development-related functionality for block modes +#![allow(clippy::missing_errors_doc)] + use crate::{BlockModeDecrypt, BlockModeEncrypt, KeyIvInit, inout::InOutBuf}; const MAX_MSG_LEN: usize = 1 << 12; diff --git a/cipher/src/dev/stream.rs b/cipher/src/dev/stream.rs index 50e13b28f..55ca6e5f9 100644 --- a/cipher/src/dev/stream.rs +++ b/cipher/src/dev/stream.rs @@ -1,4 +1,7 @@ //! Development-related functionality for stream ciphers + +#![allow(clippy::missing_errors_doc)] + use crate::{KeyIvInit, StreamCipher}; /// Stream cipher test vector diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 2146eeec2..956d217b9 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -5,12 +5,6 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] -#![warn( - missing_docs, - rust_2018_idioms, - unused_lifetimes, - missing_debug_implementations -)] #![forbid(unsafe_code)] #[cfg(feature = "alloc")] diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 3728fe690..42ea8b72d 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -70,6 +70,9 @@ pub trait AsyncStreamCipher: Sized { } /// Encrypt data from buffer to buffer. + /// + /// # Errors + /// Returns [`NotEqualError`] if provided `in_buf` and `out_buf` have different lengths. fn encrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> where Self: BlockModeEncrypt, @@ -78,6 +81,9 @@ pub trait AsyncStreamCipher: Sized { } /// Decrypt data from buffer to buffer. + /// + /// # Errors + /// Returns [`NotEqualError`] if provided `in_buf` and `out_buf` have different lengths. fn decrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> where Self: BlockModeDecrypt, @@ -110,30 +116,42 @@ pub trait AsyncStreamCipher: Sized { /// and the seeking methods defined in the [`StreamCipherSeek`] trait. pub trait StreamCipher { /// Check that the cipher can generate a keystream with a length of `data_len` bytes. + /// + /// # Errors + /// Returns [`StreamCipherError`] in the event it cannot. fn check_remaining(&self, data_len: usize) -> Result<(), StreamCipherError>; /// Apply keystream to `inout` without checking for keystream repetition. /// - /// # WARNING + ///

+ /// WARNING + /// /// This method should be used with extreme caution! Triggering keystream repetition can expose /// the stream cipher to chosen plaintext attacks. + ///
fn unchecked_apply_keystream_inout(&mut self, buf: InOutBuf<'_, '_, u8>); /// Apply keystream to `buf` without checking for keystream repetition. /// - /// # WARNING + ///
+ /// WARNING + /// /// This method should be used with extreme caution! Triggering keystream repetition can expose /// the stream cipher to chosen plaintext attacks. + ///
fn unchecked_write_keystream(&mut self, buf: &mut [u8]); /// Apply keystream to data behind `buf` without checking for keystream repetition. /// - /// # WARNING + ///
+ /// WARNING + /// /// This method should be used with extreme caution! Triggering keystream repetition can expose /// the stream cipher to chosen plaintext attacks. + ///
#[inline] fn unchecked_apply_keystream(&mut self, buf: &mut [u8]) { - self.unchecked_apply_keystream_inout(buf.into()) + self.unchecked_apply_keystream_inout(buf.into()); } /// Apply keystream to data buffer-to-buffer without checking for keystream repetition. @@ -141,11 +159,15 @@ pub trait StreamCipher { /// It will XOR generated keystream with data from the `input` buffer /// and will write result to the `output` buffer. /// + /// # Errors /// Returns [`NotEqualError`] if the `input` and `output` buffers have different lengths. /// - /// # WARNING + ///
+ /// WARNING + /// /// This method should be used with extreme caution! Triggering keystream repetition can expose /// the stream cipher to chosen plaintext attacks. + ///
#[inline] fn unchecked_apply_keystream_b2b( &mut self, @@ -159,6 +181,7 @@ pub trait StreamCipher { /// Apply keystream to `inout` data. /// + /// # Errors /// If the end of the keystream is reached with the given buffer length, /// the method will return [`StreamCipherError`] without modifying `buf`. fn try_apply_keystream_inout( @@ -172,6 +195,7 @@ pub trait StreamCipher { /// Apply keystream to data behind `buf`. /// + /// # Errors /// If the end of the keystream is reached with the given buffer length, /// the method will return [`StreamCipherError`] without modifying `buf`. #[inline] @@ -184,6 +208,7 @@ pub trait StreamCipher { /// It will XOR generated keystream with data from the `input` buffer /// and will write result to the `output` buffer. /// + /// # Errors /// Returns [`StreamCipherError`] without modifying the buffers if the `input` and `output` /// buffers have different lengths, or if the end of the keystream is reached with /// the given data length. @@ -200,6 +225,7 @@ pub trait StreamCipher { /// Write keystream to `buf`. /// + /// # Errors /// If the end of the keystream is reached with the given buffer length, /// the method will return [`StreamCipherError`] without modifying `buf`. #[inline] @@ -218,7 +244,8 @@ pub trait StreamCipher { /// If the end of the keystream is reached with the given buffer length. #[inline] fn apply_keystream_inout(&mut self, buf: InOutBuf<'_, '_, u8>) { - self.try_apply_keystream_inout(buf).unwrap(); + self.try_apply_keystream_inout(buf) + .expect("end of keystream reached"); } /// Apply keystream to data in-place. @@ -230,7 +257,8 @@ pub trait StreamCipher { /// If the end of the keystream is reached with the given buffer length. #[inline] fn apply_keystream(&mut self, buf: &mut [u8]) { - self.try_apply_keystream(buf).unwrap(); + self.try_apply_keystream(buf) + .expect("end of keystream reached"); } /// Apply keystream to data buffer-to-buffer. @@ -246,7 +274,7 @@ pub trait StreamCipher { let Ok(buf) = InOutBuf::new(input, output) else { panic!("Lengths of input and output buffers are not equal to each other!"); }; - self.apply_keystream_inout(buf) + self.apply_keystream_inout(buf); } /// Write keystream to `buf`. @@ -255,7 +283,8 @@ pub trait StreamCipher { /// If the end of the keystream is reached with the given buffer length. #[inline] fn write_keystream(&mut self, buf: &mut [u8]) { - self.try_write_keystream(buf).unwrap(); + self.try_write_keystream(buf) + .expect("end of keystream reached"); } } @@ -266,11 +295,13 @@ pub trait StreamCipher { pub trait StreamCipherSeek { /// Try to get current keystream position in bytes. /// + /// # Errors /// Returns [`OverflowError`] if the position value can not be represented by type `T`. fn try_current_pos(&self) -> Result; /// Try to seek to the provided position in bytes. /// + /// # Errors /// Returns [`StreamCipherError`] if the position value is bigger than keystream length. fn try_seek(&mut self, pos: T) -> Result<(), StreamCipherError>; @@ -279,7 +310,8 @@ pub trait StreamCipherSeek { /// # Panics /// If the position value can not be represented by type `T`. fn current_pos(&self) -> T { - self.try_current_pos().unwrap() + self.try_current_pos() + .expect("position cannot be represented by `T`") } /// Seek to the provided keystream position in bytes. @@ -287,7 +319,8 @@ pub trait StreamCipherSeek { /// # Panics /// If the position value is bigger than keystream length. fn seek(&mut self, pos: T) { - self.try_seek(pos).unwrap() + self.try_seek(pos) + .expect("position value bigger than keystream length"); } } @@ -299,12 +332,12 @@ impl StreamCipher for &mut C { #[inline] fn unchecked_apply_keystream_inout(&mut self, buf: InOutBuf<'_, '_, u8>) { - C::unchecked_apply_keystream_inout(self, buf) + C::unchecked_apply_keystream_inout(self, buf); } #[inline] fn unchecked_write_keystream(&mut self, buf: &mut [u8]) { - C::unchecked_write_keystream(self, buf) + C::unchecked_write_keystream(self, buf); } } @@ -316,6 +349,9 @@ 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`. + /// + /// # Errors + /// Returns [`OverflowError`] in the event of a counter overflow. fn from_block_byte( block: T, byte: u8, @@ -323,6 +359,9 @@ pub trait SeekNum: Sized { ) -> Result; /// Try to get block number and bytes position for given block size `bs`. + /// + /// # Errors + /// Returns [`OverflowError`] in the event of a counter overflow. fn into_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; } diff --git a/cipher/src/stream/core_api.rs b/cipher/src/stream/core_api.rs index 7a534f154..d9b447077 100644 --- a/cipher/src/stream/core_api.rs +++ b/cipher/src/stream/core_api.rs @@ -92,7 +92,8 @@ pub trait StreamCipherCore: BlockSizeUser + Sized { /// /// Consumes cipher since it may consume the final keystream block only partially. /// - /// Returns an error if the number of remaining blocks is not sufficient + /// # Errors + /// Returns [`StreamCipherError`] if the number of remaining blocks is not sufficient /// for processing of the input data. #[inline] fn try_apply_keystream_partial( @@ -138,7 +139,8 @@ pub trait StreamCipherCore: BlockSizeUser + Sized { /// input data. #[inline] fn apply_keystream_partial(self, buf: InOutBuf<'_, '_, u8>) { - self.try_apply_keystream_partial(buf).unwrap() + self.try_apply_keystream_partial(buf) + .expect("number of remaining blocks insufficient"); } } diff --git a/cipher/src/stream/wrapper.rs b/cipher/src/stream/wrapper.rs index e764a55e3..282d7cb82 100644 --- a/cipher/src/stream/wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -108,6 +108,7 @@ impl StreamCipher for StreamCipherCoreWrapper { } impl StreamCipherSeek for StreamCipherCoreWrapper { + #[allow(clippy::unwrap_in_result)] fn try_current_pos(&self) -> Result { let pos = u8::try_from(self.buffer.get_pos()) .expect("buffer position is always smaller than 256"); @@ -175,8 +176,8 @@ impl ZeroizeOnDrop for StreamCipherCoreWrap // Assert that `ReadBuffer` implements `ZeroizeOnDrop` #[cfg(feature = "zeroize")] const _: () = { - #[allow(dead_code)] + #[allow(dead_code, trivial_casts)] fn check_buffer(v: &ReadBuffer) { - let _ = v as &dyn crate::zeroize::ZeroizeOnDrop; + let _ = v as &dyn ZeroizeOnDrop; } }; diff --git a/cipher/src/tweak/zero.rs b/cipher/src/tweak/zero.rs index 6672fbc2a..fb0a1f761 100644 --- a/cipher/src/tweak/zero.rs +++ b/cipher/src/tweak/zero.rs @@ -65,7 +65,7 @@ where self.f.call(&BackendWrapper { backend, _pd: PhantomData, - }) + }); } } @@ -78,7 +78,7 @@ where self.f.call(&BackendWrapper { backend, _pd: PhantomData, - }) + }); } } diff --git a/cipher/tests/stream.rs b/cipher/tests/stream.rs index 7f9d8c547..7b618a179 100644 --- a/cipher/tests/stream.rs +++ b/cipher/tests/stream.rs @@ -1,3 +1,5 @@ +//! Stream cipher tests. + use cipher::{ BlockSizeUser, IvSizeUser, KeyIvInit, KeySizeUser, ParBlocksSizeUser, StreamCipherBackend, StreamCipherClosure, StreamCipherCore, StreamCipherSeekCore, @@ -9,6 +11,8 @@ const KEY: [u8; 4] = hex!("00010203"); const IV: [u8; 4] = hex!("04050607"); /// Core of dummy insecure stream cipher. +#[derive(Debug)] +#[allow(missing_copy_implementations)] pub struct DummyStreamCipherCore { key_iv: u64, pos: u64,