Skip to content

Commit 176efb8

Browse files
authored
cipher: remove padded methods from BlockCipherEncrypt/Decrypt traits (#2245)
The methods were intended to be used for the ECB mode, but they are hard to discover in practice for inexperienced users, so I plan to introduce a separate crate for the mode.
1 parent 11a4764 commit 176efb8

2 files changed

Lines changed: 5 additions & 150 deletions

File tree

cipher/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
### Fixed
1414
- Seeking implementation in the stream cipher wrapper ([#2052])
1515

16+
### Removed
17+
- `BlockCipherEncrypt::encrypt_padded*` and `BlockCipherDecrypt::decrypt_padded*` methods.
18+
Users of the ECB mode should use the `ecb-mode` crate instead. ([#2245])
19+
1620
[#1759]: https://github.com/RustCrypto/traits/pull/1759
1721
[#2052]: https://github.com/RustCrypto/traits/pull/2052
1822
[#2237]: https://github.com/RustCrypto/traits/pull/2237
23+
[#2245]: https://github.com/RustCrypto/traits/pull/2245
1924

2025
## 0.4.4 (2022-03-09)
2126
### Changed

cipher/src/block.rs

Lines changed: 0 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -81,90 +81,6 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized {
8181
InOutBuf::new(in_blocks, out_blocks)
8282
.map(|blocks| self.encrypt_with_backend(BlocksCtx { blocks }))
8383
}
84-
85-
/// Pad input and encrypt. Returns resulting ciphertext slice.
86-
///
87-
/// Returns [`PadError`] if length of output buffer is not sufficient.
88-
#[cfg(feature = "block-padding")]
89-
#[inline]
90-
fn encrypt_padded_inout<'out, P: Padding>(
91-
&self,
92-
data: InOutBufReserved<'_, 'out, u8>,
93-
) -> Result<&'out [u8], PadError> {
94-
let mut buf = data.into_padded_blocks::<P, Self::BlockSize>()?;
95-
self.encrypt_blocks_inout(buf.get_blocks());
96-
if let Some(block) = buf.get_tail_block() {
97-
self.encrypt_block_inout(block);
98-
}
99-
Ok(buf.into_out())
100-
}
101-
102-
/// Pad input and encrypt in-place. Returns resulting ciphertext slice.
103-
///
104-
/// Returns [`PadError`] if length of output buffer is not sufficient.
105-
#[cfg(feature = "block-padding")]
106-
#[inline]
107-
fn encrypt_padded<'a, P: Padding>(
108-
&self,
109-
buf: &'a mut [u8],
110-
msg_len: usize,
111-
) -> Result<&'a [u8], PadError> {
112-
let buf = InOutBufReserved::from_mut_slice(buf, msg_len).map_err(|_| PadError)?;
113-
self.encrypt_padded_inout::<P>(buf)
114-
}
115-
116-
/// Pad input and encrypt buffer-to-buffer. Returns resulting ciphertext slice.
117-
///
118-
/// Returns [`PadError`] if length of output buffer is not sufficient.
119-
#[cfg(feature = "block-padding")]
120-
#[inline]
121-
fn encrypt_padded_b2b<'a, P: Padding>(
122-
&self,
123-
msg: &[u8],
124-
out_buf: &'a mut [u8],
125-
) -> Result<&'a [u8], PadError> {
126-
let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?;
127-
self.encrypt_padded_inout::<P>(buf)
128-
}
129-
130-
/// Pad `msg` with padding algorithm `P`, encrypt it into a newly allocated `Vec`,
131-
/// and return the resulting ciphertext vector.
132-
///
133-
/// # Panics
134-
/// If `NoPadding` is used with a message size that is not a multiple of the cipher block size.
135-
#[cfg(all(feature = "block-padding", feature = "alloc"))]
136-
#[inline]
137-
fn encrypt_padded_vec<P: Padding>(&self, msg: &[u8]) -> Vec<u8> {
138-
use block_padding::{NoPadding, ZeroPadding};
139-
use common::typenum::Unsigned;
140-
use core::any::TypeId;
141-
142-
let bs = Self::BlockSize::USIZE;
143-
let msg_len = msg.len();
144-
145-
let pad_type_id = TypeId::of::<P>();
146-
let buf_blocks_len = if pad_type_id == TypeId::of::<NoPadding>() {
147-
if msg_len % bs != 0 {
148-
panic!(
149-
"NoPadding is used with a {msg_len}‑byte message,
150-
which is not a multiple of the {bs}‑byte cipher block size"
151-
);
152-
}
153-
msg_len / bs
154-
} else if pad_type_id == TypeId::of::<ZeroPadding>() {
155-
msg_len.div_ceil(bs)
156-
} else {
157-
1 + msg_len / bs
158-
};
159-
160-
let mut buf = vec![0; bs * buf_blocks_len];
161-
let res_len = self
162-
.encrypt_padded_b2b::<P>(msg, &mut buf)
163-
.expect("`buf` has enough space for encryption")
164-
.len();
165-
buf.truncate(res_len);
166-
buf
167-
}
16884
}
16985

17086
/// Decrypt-only functionality for block ciphers.
@@ -218,72 +134,6 @@ pub trait BlockCipherDecrypt: BlockSizeUser {
218134
InOutBuf::new(in_blocks, out_blocks)
219135
.map(|blocks| self.decrypt_with_backend(BlocksCtx { blocks }))
220136
}
221-
222-
/// Decrypt input and unpad it. Returns resulting plaintext slice.
223-
///
224-
/// Returns [`block_padding::Error`] if padding is malformed or if input length is
225-
/// not multiple of `Self::BlockSize`.
226-
#[cfg(feature = "block-padding")]
227-
#[inline]
228-
fn decrypt_padded_inout<'out, P: Padding>(
229-
&self,
230-
data: InOutBuf<'_, 'out, u8>,
231-
) -> Result<&'out [u8], block_padding::Error> {
232-
let (mut blocks, tail) = data.into_chunks();
233-
if !tail.is_empty() {
234-
return Err(block_padding::Error);
235-
}
236-
self.decrypt_blocks_inout(blocks.reborrow());
237-
P::unpad_blocks::<Self::BlockSize>(blocks.into_out())
238-
}
239-
240-
/// Decrypt input and unpad it in-place. Returns resulting plaintext slice.
241-
///
242-
/// Returns [`block_padding::Error`] if padding is malformed or if input length is
243-
/// not multiple of `Self::BlockSize`.
244-
#[cfg(feature = "block-padding")]
245-
#[inline]
246-
fn decrypt_padded<'a, P: Padding>(
247-
&self,
248-
buf: &'a mut [u8],
249-
) -> Result<&'a [u8], block_padding::Error> {
250-
self.decrypt_padded_inout::<P>(buf.into())
251-
}
252-
253-
/// Decrypt input and unpad it buffer-to-buffer. Returns resulting
254-
/// plaintext slice.
255-
///
256-
/// Returns [`block_padding::Error`] if padding is malformed or if input length is
257-
/// not multiple of `Self::BlockSize`.
258-
#[cfg(feature = "block-padding")]
259-
#[inline]
260-
fn decrypt_padded_b2b<'a, P: Padding>(
261-
&self,
262-
in_buf: &[u8],
263-
out_buf: &'a mut [u8],
264-
) -> Result<&'a [u8], block_padding::Error> {
265-
if out_buf.len() < in_buf.len() {
266-
return Err(block_padding::Error);
267-
}
268-
let n = in_buf.len();
269-
// note: `new` always returns `Ok` here
270-
let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| block_padding::Error)?;
271-
self.decrypt_padded_inout::<P>(buf)
272-
}
273-
274-
/// Decrypt input and unpad it in a newly allocated Vec. Returns resulting
275-
/// plaintext `Vec`.
276-
///
277-
/// Returns [`block_padding::Error`] if padding is malformed or if input length is
278-
/// not multiple of `Self::BlockSize`.
279-
#[cfg(all(feature = "block-padding", feature = "alloc"))]
280-
#[inline]
281-
fn decrypt_padded_vec<P: Padding>(&self, buf: &[u8]) -> Result<Vec<u8>, block_padding::Error> {
282-
let mut out = vec![0; buf.len()];
283-
let len = self.decrypt_padded_b2b::<P>(buf, &mut out)?.len();
284-
out.truncate(len);
285-
Ok(out)
286-
}
287137
}
288138

289139
impl<Alg: BlockCipherEncrypt> BlockCipherEncrypt for &Alg {

0 commit comments

Comments
 (0)