Skip to content

Commit

Permalink
cipher: restore allocating padded encrypt/decrypt
Browse files Browse the repository at this point in the history
Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
  • Loading branch information
Keruspe committed Feb 13, 2022
1 parent ab8c7a2 commit 843e4e4
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 1 deletion.
6 changes: 6 additions & 0 deletions cipher/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,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).

## UNRELEASED
### Added
- Allocating padded encrypt/decrypt ([#936])

[#936]: https://github.com/RustCrypto/traits/pull/936

## 0.3.0 (2022-02-10)
### Changed
- Major rework of traits. Core functionality of block and stream ciphers
Expand Down
4 changes: 3 additions & 1 deletion cipher/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ blobby = { version = "0.3", optional = true }
zeroize = { version = "1.5", optional = true, default-features = false }

[features]
std = ["crypto-common/std", "inout/std"]
default = ["alloc"]
alloc = []
std = ["alloc", "crypto-common/std", "inout/std"]
block-padding = ["inout/block-padding"]
rand_core = ["crypto-common/rand_core"] # Enable random key and IV generation methods
dev = ["blobby"]
Expand Down
66 changes: 66 additions & 0 deletions cipher/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
//! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

use crate::{ParBlocks, ParBlocksSizeUser};
#[cfg(all(feature = "block-padding", feature = "alloc"))]
use alloc::{vec, vec::Vec};
#[cfg(feature = "block-padding")]
use inout::{
block_padding::{Padding, UnpadError},
Expand Down Expand Up @@ -173,6 +175,17 @@ pub trait BlockEncrypt: BlockSizeUser + Sized {
let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?;
self.encrypt_padded_inout::<P>(buf)
}

/// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec.
#[cfg(all(feature = "block-padding", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))]
#[inline]
fn encrypt_padded_vec<P: Padding<Self::BlockSize>>(&self, msg: &[u8]) -> Vec<u8> {
let mut out = allocate_out_vec::<Self>(msg.len());
self.encrypt_padded_b2b::<P>(msg, &mut out)
.expect("enough space for encrypting is allocated");
out
}
}

/// Decrypt-only functionality for block ciphers.
Expand Down Expand Up @@ -281,6 +294,24 @@ pub trait BlockDecrypt: BlockSizeUser {
let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?;
self.decrypt_padded_inout::<P>(buf)
}

/// Decrypt input and unpad it in a newly allocated Vec. Returns resulting
/// ciphertext Vec.
///
/// Returns [`UnpadError`] if padding is malformed or if input length is
/// not multiple of `Self::BlockSize`.
#[cfg(all(feature = "block-padding", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))]
#[inline]
fn decrypt_padded_vec<P: Padding<Self::BlockSize>>(
&self,
buf: &[u8],
) -> Result<Vec<u8>, UnpadError> {
let mut out = vec![0; buf.len()];
let len = self.decrypt_padded_b2b::<P>(buf, &mut out)?.len();
out.truncate(len);
Ok(out)
}
}

/// Encrypt-only functionality for block ciphers and modes with mutable access to `self`.
Expand Down Expand Up @@ -386,6 +417,17 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized {
let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?;
self.encrypt_padded_inout_mut::<P>(buf)
}

/// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec.
#[cfg(all(feature = "block-padding", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))]
#[inline]
fn encrypt_padded_vec_mut<P: Padding<Self::BlockSize>>(self, msg: &[u8]) -> Vec<u8> {
let mut out = allocate_out_vec::<Self>(msg.len());
self.encrypt_padded_b2b_mut::<P>(msg, &mut out)
.expect("enough space for encrypting is allocated");
out
}
}

/// Decrypt-only functionality for block ciphers and modes with mutable access to `self`.
Expand Down Expand Up @@ -498,6 +540,24 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized {
let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?;
self.decrypt_padded_inout_mut::<P>(buf)
}

/// Decrypt input and unpad it in a newly allocated Vec. Returns resulting
/// ciphertext Vec.
///
/// Returns [`UnpadError`] if padding is malformed or if input length is
/// not multiple of `Self::BlockSize`.
#[cfg(all(feature = "block-padding", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))]
#[inline]
fn decrypt_padded_vec<P: Padding<Self::BlockSize>>(
self,
buf: &[u8],
) -> Result<Vec<u8>, UnpadError> {
let mut out = vec![0; buf.len()];
let len = self.decrypt_padded_b2b_mut::<P>(buf, &mut out)?.len();
out.truncate(len);
Ok(out)
}
}

impl<Alg: BlockEncrypt> BlockEncryptMut for Alg {
Expand Down Expand Up @@ -568,6 +628,12 @@ impl<'inp, 'out, BS: ArrayLength<u8>> BlockClosure for BlocksCtx<'inp, 'out, BS>
}
}

#[cfg(all(feature = "block-padding", feature = "alloc"))]
fn allocate_out_vec<BS: BlockSizeUser>(len: usize) -> Vec<u8> {
let bs = BS::BlockSize::USIZE;
vec![0; bs * (len / bs + 1)]
}

/// Implement simple block backend
#[macro_export]
macro_rules! impl_simple_block_encdec {
Expand Down
3 changes: 3 additions & 0 deletions cipher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
pub use crypto_common;
pub use inout;

#[cfg(all(feature = "block-padding", feature = "alloc"))]
extern crate alloc;

#[cfg(feature = "std")]
extern crate std;

Expand Down

0 comments on commit 843e4e4

Please sign in to comment.