From 045378dc70c08d6948f6e75e336d4d323dfcaa1a Mon Sep 17 00:00:00 2001 From: Charles Zinn Date: Sat, 25 Mar 2023 16:28:36 -0400 Subject: [PATCH 1/3] Add RawPadding trait to block-padding for padding blocks of arbitrary size --- block-padding/src/lib.rs | 105 +++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/block-padding/src/lib.rs b/block-padding/src/lib.rs index 3f2fc67e..127a91f7 100644 --- a/block-padding/src/lib.rs +++ b/block-padding/src/lib.rs @@ -29,6 +29,25 @@ pub enum PadType { NoPadding, } +/// Trait for padding messages divided into blocks of arbitrary size +pub trait RawPadding { + /// Padding type + const TYPE: PadType; + + /// Pads `block` filled with data up to `pos` (i.e length of a message + /// stored in the block is equal to `pos`). + /// + /// # Panics + /// If `pos` is bigger than `block.len()`. Most padding algorithms also + /// panic if they are equal. + fn raw_pad(block: &mut [u8], pos: usize); + + /// Unpad data in the `block`. + /// + /// Returns `Err(UnpadError)` if the block contains malformed padding. + fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError>; +} + /// Block size. pub type Block = GenericArray; @@ -73,6 +92,20 @@ pub trait Padding> { } } +impl> Padding for T where T: RawPadding { + const TYPE: PadType = T::TYPE; + + #[inline] + fn pad(block: &mut Block, pos: usize) { + T::raw_pad(block.as_mut_slice(), pos); + } + + #[inline] + fn unpad(block: &Block) -> Result<&[u8], UnpadError> { + T::raw_unpad(block.as_slice()) + } +} + /// Pad block with zeros. /// /// ``` @@ -94,12 +127,12 @@ pub trait Padding> { #[derive(Clone, Copy, Debug)] pub struct ZeroPadding; -impl> Padding for ZeroPadding { +impl RawPadding for ZeroPadding { const TYPE: PadType = PadType::Ambiguous; #[inline] - fn pad(block: &mut Block, pos: usize) { - if pos > B::USIZE { + fn raw_pad(block: &mut [u8], pos: usize) { + if pos > block.len() { panic!("`pos` is bigger than block size"); } for b in &mut block[pos..] { @@ -108,8 +141,8 @@ impl> Padding for ZeroPadding { } #[inline] - fn unpad(block: &Block) -> Result<&[u8], UnpadError> { - for i in (0..B::USIZE).rev() { + fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError> { + for i in (0..block.len()).rev() { if block[i] != 0 { return Ok(&block[..i + 1]); } @@ -140,12 +173,12 @@ pub struct Pkcs7; impl Pkcs7 { #[inline] - fn unpad>(block: &Block, strict: bool) -> Result<&[u8], UnpadError> { + fn unpad(block: &[u8], strict: bool) -> Result<&[u8], UnpadError> { // TODO: use bounds to check it at compile time - if B::USIZE > 255 { + if block.len() > 255 { panic!("block size is too big for PKCS#7"); } - let bs = B::USIZE; + let bs = block.len(); let n = block[bs - 1]; if n == 0 || n as usize > bs { return Err(UnpadError); @@ -158,26 +191,26 @@ impl Pkcs7 { } } -impl> Padding for Pkcs7 { +impl RawPadding for Pkcs7 { const TYPE: PadType = PadType::Reversible; #[inline] - fn pad(block: &mut Block, pos: usize) { - // TODO: use bounds to check it at compile time - if B::USIZE > 255 { + fn raw_pad(block: &mut [u8], pos: usize) { + // TODO: use bounds to check it at compile time for Padding + if block.len() > 255 { panic!("block size is too big for PKCS#7"); } - if pos >= B::USIZE { + if pos >= block.len() { panic!("`pos` is bigger or equal to block size"); } - let n = (B::USIZE - pos) as u8; + let n = (block.len() - pos) as u8; for b in &mut block[pos..] { *b = n; } } #[inline] - fn unpad(block: &Block) -> Result<&[u8], UnpadError> { + fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError> { Pkcs7::unpad(block, true) } } @@ -202,18 +235,18 @@ impl> Padding for Pkcs7 { #[derive(Clone, Copy, Debug)] pub struct Iso10126; -impl> Padding for Iso10126 { +impl RawPadding for Iso10126 { const TYPE: PadType = PadType::Reversible; #[inline] - fn pad(block: &mut Block, pos: usize) { + fn raw_pad(block: &mut [u8], pos: usize) { // Instead of generating random bytes as specified by Iso10126 we // simply use Pkcs7 padding. - Pkcs7::pad(block, pos) + Pkcs7::raw_pad(block, pos) } #[inline] - fn unpad(block: &Block) -> Result<&[u8], UnpadError> { + fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError> { Pkcs7::unpad(block, false) } } @@ -237,19 +270,19 @@ impl> Padding for Iso10126 { #[derive(Clone, Copy, Debug)] pub struct AnsiX923; -impl> Padding for AnsiX923 { +impl RawPadding for AnsiX923 { const TYPE: PadType = PadType::Reversible; #[inline] - fn pad(block: &mut Block, pos: usize) { + fn raw_pad(block: &mut [u8], pos: usize) { // TODO: use bounds to check it at compile time - if B::USIZE > 255 { + if block.len() > 255 { panic!("block size is too big for PKCS#7"); } - if pos >= B::USIZE { + if pos >= block.len() { panic!("`pos` is bigger or equal to block size"); } - let bs = B::USIZE; + let bs = block.len(); for b in &mut block[pos..bs - 1] { *b = 0; } @@ -257,12 +290,12 @@ impl> Padding for AnsiX923 { } #[inline] - fn unpad(block: &Block) -> Result<&[u8], UnpadError> { + fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError> { // TODO: use bounds to check it at compile time - if B::USIZE > 255 { + if block.len() > 255 { panic!("block size is too big for PKCS#7"); } - let bs = B::USIZE; + let bs = block.len(); let n = block[bs - 1] as usize; if n == 0 || n > bs { return Err(UnpadError); @@ -293,12 +326,12 @@ impl> Padding for AnsiX923 { #[derive(Clone, Copy, Debug)] pub struct Iso7816; -impl> Padding for Iso7816 { +impl RawPadding for Iso7816 { const TYPE: PadType = PadType::Reversible; #[inline] - fn pad(block: &mut Block, pos: usize) { - if pos >= B::USIZE { + fn raw_pad(block: &mut [u8], pos: usize) { + if pos >= block.len() { panic!("`pos` is bigger or equal to block size"); } block[pos] = 0x80; @@ -308,8 +341,8 @@ impl> Padding for Iso7816 { } #[inline] - fn unpad(block: &Block) -> Result<&[u8], UnpadError> { - for i in (0..B::USIZE).rev() { + fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError> { + for i in (0..block.len()).rev() { match block[i] { 0x80 => return Ok(&block[..i]), 0x00 => continue, @@ -344,18 +377,18 @@ impl> Padding for Iso7816 { #[derive(Clone, Copy, Debug)] pub struct NoPadding; -impl> Padding for NoPadding { +impl RawPadding for NoPadding { const TYPE: PadType = PadType::NoPadding; #[inline] - fn pad(_block: &mut Block, pos: usize) { - if pos > B::USIZE { + fn raw_pad(block: &mut [u8], pos: usize) { + if pos > block.len() { panic!("`pos` is bigger than block size"); } } #[inline] - fn unpad(block: &Block) -> Result<&[u8], UnpadError> { + fn raw_unpad(block: &[u8]) -> Result<&[u8], UnpadError> { Ok(block) } } From 5d5d36c6d6b992f6aaddad8125240eae6aa02a21 Mon Sep 17 00:00:00 2001 From: Charles Zinn Date: Sat, 25 Mar 2023 17:01:07 -0400 Subject: [PATCH 2/3] update version and changelog --- block-padding/CHANGELOG.md | 6 ++++++ block-padding/Cargo.toml | 2 +- block-padding/src/lib.rs | 5 ++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/block-padding/CHANGELOG.md b/block-padding/CHANGELOG.md index d2262996..86859c84 100644 --- a/block-padding/CHANGELOG.md +++ b/block-padding/CHANGELOG.md @@ -4,6 +4,12 @@ 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.3.3 (2023-03-25) +### Added +- `RawPadding` trait for padding blocks of arbitrary size ([#870]) + +[#870]: https://github.com/RustCrypto/utils/pull/870 + ## 0.3.2 (2022-03-10) ### Fixed - Potential unsoundness for incorrect `Padding` implementations ([#748]) diff --git a/block-padding/Cargo.toml b/block-padding/Cargo.toml index e8d66f02..6a049717 100644 --- a/block-padding/Cargo.toml +++ b/block-padding/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "block-padding" -version = "0.3.2" +version = "0.3.3" description = "Padding and unpadding of messages divided into blocks." authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" diff --git a/block-padding/src/lib.rs b/block-padding/src/lib.rs index 127a91f7..be950cc6 100644 --- a/block-padding/src/lib.rs +++ b/block-padding/src/lib.rs @@ -92,7 +92,10 @@ pub trait Padding> { } } -impl> Padding for T where T: RawPadding { +impl> Padding for T +where + T: RawPadding, +{ const TYPE: PadType = T::TYPE; #[inline] From ff11d805b87a93f6c1f9afff2a2c929e8f58eac9 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 1 Apr 2023 23:48:05 +0000 Subject: [PATCH 3/3] Update CHANGELOG.md --- block-padding/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block-padding/CHANGELOG.md b/block-padding/CHANGELOG.md index 86859c84..8afef8b3 100644 --- a/block-padding/CHANGELOG.md +++ b/block-padding/CHANGELOG.md @@ -4,7 +4,7 @@ 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.3.3 (2023-03-25) +## 0.3.3 (2023-04-02) ### Added - `RawPadding` trait for padding blocks of arbitrary size ([#870])