Skip to content

Commit

Permalink
cipher: restore allocating padded encrypt/decrypt (#936)
Browse files Browse the repository at this point in the history
  • Loading branch information
Keruspe committed Feb 16, 2022
1 parent 2137b13 commit b4162de
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
override: true
profile: minimal
- run: cargo clippy --all --all-features -- -D warnings
- run: cargo clippy --all --all-features -- -D warnings
working-directory: cipher
- run: cargo clippy --all --all-features -- -D warnings
working-directory: crypto
- run: cargo clippy --all --all-features -- -D warnings
Expand Down
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
84 changes: 78 additions & 6 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,20 @@ 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());
let len = self
.encrypt_padded_b2b::<P>(msg, &mut out)
.expect("enough space for encrypting is allocated")
.len();
out.truncate(len);
out
}
}

/// Decrypt-only functionality for block ciphers.
Expand Down Expand Up @@ -281,6 +297,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 @@ -363,11 +397,11 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized {
#[cfg(feature = "block-padding")]
#[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))]
#[inline]
fn encrypt_padded_mut<'a, P: Padding<Self::BlockSize>>(
fn encrypt_padded_mut<P: Padding<Self::BlockSize>>(
self,
buf: &'a mut [u8],
buf: &mut [u8],
msg_len: usize,
) -> Result<&'a [u8], PadError> {
) -> Result<&[u8], PadError> {
let buf = InOutBufReserved::from_mut_slice(buf, msg_len).map_err(|_| PadError)?;
self.encrypt_padded_inout_mut::<P>(buf)
}
Expand All @@ -386,6 +420,20 @@ 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());
let len = self
.encrypt_padded_b2b_mut::<P>(msg, &mut out)
.expect("enough space for encrypting is allocated")
.len();
out.truncate(len);
out
}
}

/// Decrypt-only functionality for block ciphers and modes with mutable access to `self`.
Expand Down Expand Up @@ -470,10 +518,10 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized {
#[cfg(feature = "block-padding")]
#[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))]
#[inline]
fn decrypt_padded_mut<'a, P: Padding<Self::BlockSize>>(
fn decrypt_padded_mut<P: Padding<Self::BlockSize>>(
self,
buf: &'a mut [u8],
) -> Result<&'a [u8], UnpadError> {
buf: &mut [u8],
) -> Result<&[u8], UnpadError> {
self.decrypt_padded_inout_mut::<P>(buf.into())
}

Expand All @@ -498,6 +546,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>>(

This comment has been minimized.

Copy link
@Keruspe

Keruspe Feb 16, 2022

Author Contributor

@newpavlov argh, just noticed the missing _mut here while using it in another crate

This comment has been minimized.

Copy link
@newpavlov

newpavlov Feb 16, 2022

Member

Oh, I've missed it as well. I will do a quick fix release.

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 +634,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 b4162de

Please sign in to comment.