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,