Skip to content

Commit d379be9

Browse files
committed
block-padding: tweak pad_detached, add PaddedData enum
1 parent 1b849b1 commit d379be9

File tree

2 files changed

+70
-10
lines changed

2 files changed

+70
-10
lines changed

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/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)