From 0ad62932a3bbdb9981b503fb10243d935a1d45d7 Mon Sep 17 00:00:00 2001 From: tirz Date: Sun, 20 Aug 2023 16:24:49 +0200 Subject: [PATCH] block-padding: implement ISO 10126 --- block-padding/Cargo.toml | 5 +++ block-padding/src/lib.rs | 74 +++++++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/block-padding/Cargo.toml b/block-padding/Cargo.toml index 6a049717..4af7ef18 100644 --- a/block-padding/Cargo.toml +++ b/block-padding/Cargo.toml @@ -13,8 +13,13 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" +rand_core = { version = "0.6", features = ["getrandom"], optional = true } + +[dev-dependencies] +rand_chacha = "0.3" [features] +iso-10126 = ["rand_core"] std = [] [package.metadata.docs.rs] diff --git a/block-padding/src/lib.rs b/block-padding/src/lib.rs index be950cc6..6d6dc40c 100644 --- a/block-padding/src/lib.rs +++ b/block-padding/src/lib.rs @@ -18,6 +18,9 @@ use core::fmt; pub use generic_array; use generic_array::{ArrayLength, GenericArray}; +#[cfg(feature = "iso-10126")] +use rand_core::{RngCore, SeedableRng}; + /// Padding types #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum PadType { @@ -174,26 +177,6 @@ impl RawPadding for ZeroPadding { #[derive(Clone, Copy, Debug)] pub struct Pkcs7; -impl Pkcs7 { - #[inline] - fn unpad(block: &[u8], strict: bool) -> Result<&[u8], UnpadError> { - // TODO: use bounds to check it at compile time - if block.len() > 255 { - panic!("block size is too big for PKCS#7"); - } - let bs = block.len(); - let n = block[bs - 1]; - if n == 0 || n as usize > bs { - return Err(UnpadError); - } - let s = bs - n as usize; - if strict && block[s..bs - 1].iter().any(|&v| v != n) { - return Err(UnpadError); - } - Ok(&block[..s]) - } -} - impl RawPadding for Pkcs7 { const TYPE: PadType = PadType::Reversible; @@ -214,7 +197,20 @@ impl RawPadding for Pkcs7 { #[inline] fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError> { - Pkcs7::unpad(block, true) + // TODO: use bounds to check it at compile time + if block.len() > 255 { + panic!("block size is too big for PKCS#7"); + } + let bs = block.len(); + let n = block[bs - 1]; + if n == 0 || n as usize > bs { + return Err(UnpadError); + } + let s = bs - n as usize; + if block[s..bs - 1].iter().any(|&v| v != n) { + return Err(UnpadError); + } + Ok(&block[..s]) } } @@ -225,32 +221,54 @@ impl RawPadding for Pkcs7 { /// ``` /// use block_padding::{Iso10126, Padding}; /// use generic_array::{GenericArray, typenum::U8}; +/// use rand_chacha::ChaCha8Rng; /// /// let msg = b"test"; /// let pos = msg.len(); /// let mut block: GenericArray:: = [0xff; 8].into(); /// block[..pos].copy_from_slice(msg); -/// Iso10126::pad(&mut block, pos); +/// Iso10126::::pad(&mut block, pos); /// assert_eq!(&block[..], b"test\x04\x04\x04\x04"); /// let res = Iso10126::unpad(&block).unwrap(); /// assert_eq!(res, msg); /// ``` +#[cfg(feature = "iso-10126")] #[derive(Clone, Copy, Debug)] -pub struct Iso10126; +pub struct Iso10126 { + rand: core::marker::PhantomData, +} -impl RawPadding for Iso10126 { +#[cfg(feature = "iso-10126")] +impl RawPadding for Iso10126 { const TYPE: PadType = PadType::Reversible; #[inline] fn raw_pad(block: &mut [u8], pos: usize) { - // Instead of generating random bytes as specified by Iso10126 we - // simply use Pkcs7 padding. - Pkcs7::raw_pad(block, pos) + // TODO: use bounds to check it at compile time + if block.len() > 255 { + panic!("block size is too big for ISO 10126"); + } + if pos >= block.len() { + panic!("`pos` is bigger or equal to block size"); + } + let bs = block.len(); + let mut rand = R::from_entropy(); + rand.fill_bytes(&mut block[pos..bs - 1]); + block[bs - 1] = (bs - pos) as u8; } #[inline] fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError> { - Pkcs7::unpad(block, false) + // TODO: use bounds to check it at compile time + if block.len() > 255 { + panic!("block size is too big for ISO 10126"); + } + let bs = block.len(); + let n = block[bs - 1] as usize; + if n == 0 || n > bs { + return Err(UnpadError); + } + Ok(&block[..bs - n]) } }