Skip to content

Commit 9118661

Browse files
authored
block-padding: fix pad_detached for NoPadding and ZeroPadding (#1227)
In #1225 I forgot to overwrite the default implementation of `pad_detached` for `NoPadding` and `ZeroPadding`. Additionally, this PR adds `PaddedData` enum to make return type of `pad_detached` less complex.
1 parent a3045ea commit 9118661

File tree

7 files changed

+94
-16
lines changed

7 files changed

+94
-16
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

block-padding/CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,19 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## 0.4.0 (2025-10-06)
7+
## 0.4.1 (2025-10-06)
8+
### Added
9+
- `PaddedData` enum ([#1227])
10+
11+
### Changed
12+
- `Padding::pad_detached` method returns `PaddedData` ([#1227])
13+
14+
### Fixed
15+
- `Padding::pad_detached` method for `NoPadding` and `ZeroPadding` ([#1227])
16+
17+
[#1227]: https://github.com/RustCrypto/utils/pull/1227
18+
19+
## 0.4.0 (2025-10-06) [YANKED]
820
### Added
921
- `Padding::pad_detached` method ([#1225])
1022

block-padding/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "block-padding"
3-
version = "0.4.0"
3+
version = "0.4.1"
44
authors = ["RustCrypto Developers"]
55
edition = "2024"
66
rust-version = "1.85"

block-padding/src/lib.rs

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,18 @@ pub trait Padding {
4848

4949
/// Pad message and return padded tail block.
5050
///
51-
/// `Err` is returned only by [`NoPadding`] if `data` length is not multiple of the block size.
52-
/// [`NoPadding`] and [`ZeroPadding`] return `Ok((blocks, None))` if `data` length
53-
/// is multiple of block size. All other padding implementations should always return
54-
/// `Ok((blocks, Some(tail_block)))`.
55-
#[allow(clippy::type_complexity)]
51+
/// [`PaddedData::Error`] is returned only by [`NoPadding`] if `data` length is not multiple
52+
/// of the block size. [`NoPadding`] and [`ZeroPadding`] return [`PaddedData::NoPad`]
53+
/// if `data` length is multiple of block size. All other padding implementations
54+
/// should always return [`PaddedData::Pad`].
5655
#[inline]
57-
fn pad_detached<BlockSize: ArraySize>(
58-
data: &[u8],
59-
) -> Result<(&[Array<u8, BlockSize>], Option<Array<u8, BlockSize>>), Error> {
56+
fn pad_detached<BlockSize: ArraySize>(data: &[u8]) -> PaddedData<'_, BlockSize> {
6057
let (blocks, tail) = Array::slice_as_chunks(data);
6158
let mut tail_block = Array::default();
6259
let pos = tail.len();
6360
tail_block[..pos].copy_from_slice(tail);
6461
Self::pad(&mut tail_block, pos);
65-
Ok((blocks, Some(tail_block)))
62+
PaddedData::Pad { blocks, tail_block }
6663
}
6764

6865
/// Unpad data in `blocks` and return unpadded byte slice.
@@ -120,6 +117,19 @@ impl Padding for ZeroPadding {
120117
Ok(&block[..0])
121118
}
122119

120+
#[inline]
121+
fn pad_detached<BlockSize: ArraySize>(data: &[u8]) -> PaddedData<'_, BlockSize> {
122+
let (blocks, tail) = Array::slice_as_chunks(data);
123+
if tail.is_empty() {
124+
return PaddedData::NoPad { blocks };
125+
}
126+
let mut tail_block = Array::default();
127+
let pos = tail.len();
128+
tail_block[..pos].copy_from_slice(tail);
129+
Self::pad(&mut tail_block, pos);
130+
PaddedData::Pad { blocks, tail_block }
131+
}
132+
123133
#[inline]
124134
fn unpad_blocks<BlockSize: ArraySize>(blocks: &[Array<u8, BlockSize>]) -> Result<&[u8], Error> {
125135
let buf = Array::slice_as_flattened(blocks);
@@ -353,6 +363,16 @@ impl Padding for NoPadding {
353363
Ok(block)
354364
}
355365

366+
#[inline]
367+
fn pad_detached<BlockSize: ArraySize>(data: &[u8]) -> PaddedData<'_, BlockSize> {
368+
let (blocks, tail) = Array::slice_as_chunks(data);
369+
if tail.is_empty() {
370+
PaddedData::NoPad { blocks }
371+
} else {
372+
PaddedData::Error
373+
}
374+
}
375+
356376
#[inline]
357377
fn unpad_blocks<BlockSize: ArraySize>(blocks: &[Array<u8, BlockSize>]) -> Result<&[u8], Error> {
358378
Ok(Array::slice_as_flattened(blocks))
@@ -370,3 +390,37 @@ impl fmt::Display for Error {
370390
}
371391

372392
impl core::error::Error for Error {}
393+
394+
/// Padded data split into blocks with detached last block returned by [`Padding::pad_detached`].
395+
#[derive(Debug)]
396+
pub enum PaddedData<'a, BlockSize: ArraySize> {
397+
/// Message split into blocks with detached and padded `tail_block`.
398+
Pad {
399+
/// Message blocks.
400+
blocks: &'a [Array<u8, BlockSize>],
401+
/// Last message block with padding.
402+
tail_block: Array<u8, BlockSize>,
403+
},
404+
/// [`NoPadding`] or [`ZeroPadding`] were used on a message which does not require any padding.
405+
NoPad {
406+
/// Message blocks.
407+
blocks: &'a [Array<u8, BlockSize>],
408+
},
409+
/// [`NoPadding`] was used on a message with size not multiple of the block size.
410+
Error,
411+
}
412+
413+
impl<'a, BlockSize: ArraySize> PaddedData<'a, BlockSize> {
414+
/// Unwrap the `Pad` variant.
415+
pub fn unwrap(self) -> (&'a [Array<u8, BlockSize>], Array<u8, BlockSize>) {
416+
match self {
417+
PaddedData::Pad { blocks, tail_block } => (blocks, tail_block),
418+
PaddedData::NoPad { .. } => {
419+
panic!("Expected `PaddedData::Pad`, but got `PaddedData::NoPad`");
420+
}
421+
PaddedData::Error => {
422+
panic!("Expected `PaddedData::Pad`, but got `PaddedData::Error`");
423+
}
424+
}
425+
}
426+
}

inout/CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## 0.2.0 (2025-10-06)
7+
## 0.2.1 (2025-10-06)
8+
### Changed
9+
- Migrate to fixed `Padding::pad_detached` from `block-padding` v0.4.1 ([#1227])
10+
11+
[#1227]: https://github.com/RustCrypto/utils/pull/1227
12+
13+
## 0.2.0 (2025-10-06) [YANKED]
814
### Changed
915
- Migrated from `generic-array` to `hybrid-array` ([#944])
1016
- Edition changed to 2024 and MSRV bumped to 1.85 ([#1149])

inout/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "inout"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
authors = ["RustCrypto Developers"]
55
edition = "2024"
66
rust-version = "1.85"

inout/src/reserved.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,13 @@ impl<'inp, 'out> InOutBufReserved<'inp, 'out, u8> {
160160
{
161161
let bs = BS::USIZE;
162162
let blocks_len = self.in_len / bs;
163-
let (blocks, tail_block) = P::pad_detached(self.get_in()).map_err(|_| PadError)?;
163+
164+
use block_padding::PaddedData;
165+
let (blocks, tail_block) = match P::pad_detached(self.get_in()) {
166+
PaddedData::Pad { blocks, tail_block } => (blocks, Some(tail_block)),
167+
PaddedData::NoPad { blocks } => (blocks, None),
168+
PaddedData::Error => return Err(PadError),
169+
};
164170

165171
assert_eq!(blocks.len(), blocks_len);
166172

0 commit comments

Comments
 (0)