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 12, 2022
1 parent 2137b13 commit 0735d1e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
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
67 changes: 67 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,13 @@ 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>(pos: usize) -> Vec<u8> {
let bs = BS::block_size();
let pad = (bs - (pos % bs)) % bs;
vec![0; pos + pad]
}

/// 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 0735d1e

Please sign in to comment.