diff --git a/Cargo.lock b/Cargo.lock index b4f547e8..052a5f1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0" +version = "0.4.1" dependencies = [ "hybrid-array", ] @@ -130,7 +130,7 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0" +version = "0.2.1" dependencies = [ "block-padding", "hybrid-array", diff --git a/block-padding/CHANGELOG.md b/block-padding/CHANGELOG.md index 03105fb5..6b9cd109 100644 --- a/block-padding/CHANGELOG.md +++ b/block-padding/CHANGELOG.md @@ -4,7 +4,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.4.0 (2025-10-06) +## 0.4.1 (2025-10-06) +### Added +- `PaddedData` enum ([#1227]) + +### Changed +- `Padding::pad_detached` method returns `PaddedData` ([#1227]) + +### Fixed +- `Padding::pad_detached` method for `NoPadding` and `ZeroPadding` ([#1227]) + +[#1227]: https://github.com/RustCrypto/utils/pull/1227 + +## 0.4.0 (2025-10-06) [YANKED] ### Added - `Padding::pad_detached` method ([#1225]) diff --git a/block-padding/Cargo.toml b/block-padding/Cargo.toml index 7376d6d4..6c6e7489 100644 --- a/block-padding/Cargo.toml +++ b/block-padding/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "block-padding" -version = "0.4.0" +version = "0.4.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/block-padding/src/lib.rs b/block-padding/src/lib.rs index 7fe9da7a..9b195bc9 100644 --- a/block-padding/src/lib.rs +++ b/block-padding/src/lib.rs @@ -48,21 +48,18 @@ pub trait Padding { /// Pad message and return padded tail block. /// - /// `Err` is returned only by [`NoPadding`] if `data` length is not multiple of the block size. - /// [`NoPadding`] and [`ZeroPadding`] return `Ok((blocks, None))` if `data` length - /// is multiple of block size. All other padding implementations should always return - /// `Ok((blocks, Some(tail_block)))`. - #[allow(clippy::type_complexity)] + /// [`PaddedData::Error`] is returned only by [`NoPadding`] if `data` length is not multiple + /// of the block size. [`NoPadding`] and [`ZeroPadding`] return [`PaddedData::NoPad`] + /// if `data` length is multiple of block size. All other padding implementations + /// should always return [`PaddedData::Pad`]. #[inline] - fn pad_detached( - data: &[u8], - ) -> Result<(&[Array], Option>), Error> { + fn pad_detached(data: &[u8]) -> PaddedData<'_, BlockSize> { let (blocks, tail) = Array::slice_as_chunks(data); let mut tail_block = Array::default(); let pos = tail.len(); tail_block[..pos].copy_from_slice(tail); Self::pad(&mut tail_block, pos); - Ok((blocks, Some(tail_block))) + PaddedData::Pad { blocks, tail_block } } /// Unpad data in `blocks` and return unpadded byte slice. @@ -120,6 +117,19 @@ impl Padding for ZeroPadding { Ok(&block[..0]) } + #[inline] + fn pad_detached(data: &[u8]) -> PaddedData<'_, BlockSize> { + let (blocks, tail) = Array::slice_as_chunks(data); + if tail.is_empty() { + return PaddedData::NoPad { blocks }; + } + let mut tail_block = Array::default(); + let pos = tail.len(); + tail_block[..pos].copy_from_slice(tail); + Self::pad(&mut tail_block, pos); + PaddedData::Pad { blocks, tail_block } + } + #[inline] fn unpad_blocks(blocks: &[Array]) -> Result<&[u8], Error> { let buf = Array::slice_as_flattened(blocks); @@ -353,6 +363,16 @@ impl Padding for NoPadding { Ok(block) } + #[inline] + fn pad_detached(data: &[u8]) -> PaddedData<'_, BlockSize> { + let (blocks, tail) = Array::slice_as_chunks(data); + if tail.is_empty() { + PaddedData::NoPad { blocks } + } else { + PaddedData::Error + } + } + #[inline] fn unpad_blocks(blocks: &[Array]) -> Result<&[u8], Error> { Ok(Array::slice_as_flattened(blocks)) @@ -370,3 +390,37 @@ impl fmt::Display for Error { } impl core::error::Error for Error {} + +/// Padded data split into blocks with detached last block returned by [`Padding::pad_detached`]. +#[derive(Debug)] +pub enum PaddedData<'a, BlockSize: ArraySize> { + /// Message split into blocks with detached and padded `tail_block`. + Pad { + /// Message blocks. + blocks: &'a [Array], + /// Last message block with padding. + tail_block: Array, + }, + /// [`NoPadding`] or [`ZeroPadding`] were used on a message which does not require any padding. + NoPad { + /// Message blocks. + blocks: &'a [Array], + }, + /// [`NoPadding`] was used on a message with size not multiple of the block size. + Error, +} + +impl<'a, BlockSize: ArraySize> PaddedData<'a, BlockSize> { + /// Unwrap the `Pad` variant. + pub fn unwrap(self) -> (&'a [Array], Array) { + match self { + PaddedData::Pad { blocks, tail_block } => (blocks, tail_block), + PaddedData::NoPad { .. } => { + panic!("Expected `PaddedData::Pad`, but got `PaddedData::NoPad`"); + } + PaddedData::Error => { + panic!("Expected `PaddedData::Pad`, but got `PaddedData::Error`"); + } + } + } +} diff --git a/inout/CHANGELOG.md b/inout/CHANGELOG.md index 879d5853..52b3c4c3 100644 --- a/inout/CHANGELOG.md +++ b/inout/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.2.0 (2025-10-06) +## 0.2.1 (2025-10-06) +### Changed +- Migrate to fixed `Padding::pad_detached` from `block-padding` v0.4.1 ([#1227]) + +[#1227]: https://github.com/RustCrypto/utils/pull/1227 + +## 0.2.0 (2025-10-06) [YANKED] ### Changed - Migrated from `generic-array` to `hybrid-array` ([#944]) - Edition changed to 2024 and MSRV bumped to 1.85 ([#1149]) diff --git a/inout/Cargo.toml b/inout/Cargo.toml index 00330fc4..aa667fdd 100644 --- a/inout/Cargo.toml +++ b/inout/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "inout" -version = "0.2.0" +version = "0.2.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/inout/src/reserved.rs b/inout/src/reserved.rs index ab143dfe..95152c17 100644 --- a/inout/src/reserved.rs +++ b/inout/src/reserved.rs @@ -160,7 +160,13 @@ impl<'inp, 'out> InOutBufReserved<'inp, 'out, u8> { { let bs = BS::USIZE; let blocks_len = self.in_len / bs; - let (blocks, tail_block) = P::pad_detached(self.get_in()).map_err(|_| PadError)?; + + use block_padding::PaddedData; + let (blocks, tail_block) = match P::pad_detached(self.get_in()) { + PaddedData::Pad { blocks, tail_block } => (blocks, Some(tail_block)), + PaddedData::NoPad { blocks } => (blocks, None), + PaddedData::Error => return Err(PadError), + }; assert_eq!(blocks.len(), blocks_len);