Skip to content

Commit b4162de

Browse files
authored
cipher: restore allocating padded encrypt/decrypt (#936)
1 parent 2137b13 commit b4162de

File tree

5 files changed

+92
-7
lines changed

5 files changed

+92
-7
lines changed

.github/workflows/workspace.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ jobs:
2525
override: true
2626
profile: minimal
2727
- run: cargo clippy --all --all-features -- -D warnings
28+
- run: cargo clippy --all --all-features -- -D warnings
29+
working-directory: cipher
2830
- run: cargo clippy --all --all-features -- -D warnings
2931
working-directory: crypto
3032
- run: cargo clippy --all --all-features -- -D warnings

cipher/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## UNRELEASED
9+
### Added
10+
- Allocating padded encrypt/decrypt ([#936])
11+
12+
[#936]: https://github.com/RustCrypto/traits/pull/936
13+
814
## 0.3.0 (2022-02-10)
915
### Changed
1016
- Major rework of traits. Core functionality of block and stream ciphers

cipher/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ blobby = { version = "0.3", optional = true }
2525
zeroize = { version = "1.5", optional = true, default-features = false }
2626

2727
[features]
28-
std = ["crypto-common/std", "inout/std"]
28+
default = ["alloc"]
29+
alloc = []
30+
std = ["alloc", "crypto-common/std", "inout/std"]
2931
block-padding = ["inout/block-padding"]
3032
rand_core = ["crypto-common/rand_core"] # Enable random key and IV generation methods
3133
dev = ["blobby"]

cipher/src/block.rs

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm
1212
1313
use crate::{ParBlocks, ParBlocksSizeUser};
14+
#[cfg(all(feature = "block-padding", feature = "alloc"))]
15+
use alloc::{vec, vec::Vec};
1416
#[cfg(feature = "block-padding")]
1517
use inout::{
1618
block_padding::{Padding, UnpadError},
@@ -173,6 +175,20 @@ pub trait BlockEncrypt: BlockSizeUser + Sized {
173175
let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?;
174176
self.encrypt_padded_inout::<P>(buf)
175177
}
178+
179+
/// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec.
180+
#[cfg(all(feature = "block-padding", feature = "alloc"))]
181+
#[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))]
182+
#[inline]
183+
fn encrypt_padded_vec<P: Padding<Self::BlockSize>>(&self, msg: &[u8]) -> Vec<u8> {
184+
let mut out = allocate_out_vec::<Self>(msg.len());
185+
let len = self
186+
.encrypt_padded_b2b::<P>(msg, &mut out)
187+
.expect("enough space for encrypting is allocated")
188+
.len();
189+
out.truncate(len);
190+
out
191+
}
176192
}
177193

178194
/// Decrypt-only functionality for block ciphers.
@@ -281,6 +297,24 @@ pub trait BlockDecrypt: BlockSizeUser {
281297
let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?;
282298
self.decrypt_padded_inout::<P>(buf)
283299
}
300+
301+
/// Decrypt input and unpad it in a newly allocated Vec. Returns resulting
302+
/// ciphertext Vec.
303+
///
304+
/// Returns [`UnpadError`] if padding is malformed or if input length is
305+
/// not multiple of `Self::BlockSize`.
306+
#[cfg(all(feature = "block-padding", feature = "alloc"))]
307+
#[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))]
308+
#[inline]
309+
fn decrypt_padded_vec<P: Padding<Self::BlockSize>>(
310+
&self,
311+
buf: &[u8],
312+
) -> Result<Vec<u8>, UnpadError> {
313+
let mut out = vec![0; buf.len()];
314+
let len = self.decrypt_padded_b2b::<P>(buf, &mut out)?.len();
315+
out.truncate(len);
316+
Ok(out)
317+
}
284318
}
285319

286320
/// Encrypt-only functionality for block ciphers and modes with mutable access to `self`.
@@ -363,11 +397,11 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized {
363397
#[cfg(feature = "block-padding")]
364398
#[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))]
365399
#[inline]
366-
fn encrypt_padded_mut<'a, P: Padding<Self::BlockSize>>(
400+
fn encrypt_padded_mut<P: Padding<Self::BlockSize>>(
367401
self,
368-
buf: &'a mut [u8],
402+
buf: &mut [u8],
369403
msg_len: usize,
370-
) -> Result<&'a [u8], PadError> {
404+
) -> Result<&[u8], PadError> {
371405
let buf = InOutBufReserved::from_mut_slice(buf, msg_len).map_err(|_| PadError)?;
372406
self.encrypt_padded_inout_mut::<P>(buf)
373407
}
@@ -386,6 +420,20 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized {
386420
let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?;
387421
self.encrypt_padded_inout_mut::<P>(buf)
388422
}
423+
424+
/// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec.
425+
#[cfg(all(feature = "block-padding", feature = "alloc"))]
426+
#[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))]
427+
#[inline]
428+
fn encrypt_padded_vec_mut<P: Padding<Self::BlockSize>>(self, msg: &[u8]) -> Vec<u8> {
429+
let mut out = allocate_out_vec::<Self>(msg.len());
430+
let len = self
431+
.encrypt_padded_b2b_mut::<P>(msg, &mut out)
432+
.expect("enough space for encrypting is allocated")
433+
.len();
434+
out.truncate(len);
435+
out
436+
}
389437
}
390438

391439
/// Decrypt-only functionality for block ciphers and modes with mutable access to `self`.
@@ -470,10 +518,10 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized {
470518
#[cfg(feature = "block-padding")]
471519
#[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))]
472520
#[inline]
473-
fn decrypt_padded_mut<'a, P: Padding<Self::BlockSize>>(
521+
fn decrypt_padded_mut<P: Padding<Self::BlockSize>>(
474522
self,
475-
buf: &'a mut [u8],
476-
) -> Result<&'a [u8], UnpadError> {
523+
buf: &mut [u8],
524+
) -> Result<&[u8], UnpadError> {
477525
self.decrypt_padded_inout_mut::<P>(buf.into())
478526
}
479527

@@ -498,6 +546,24 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized {
498546
let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?;
499547
self.decrypt_padded_inout_mut::<P>(buf)
500548
}
549+
550+
/// Decrypt input and unpad it in a newly allocated Vec. Returns resulting
551+
/// ciphertext Vec.
552+
///
553+
/// Returns [`UnpadError`] if padding is malformed or if input length is
554+
/// not multiple of `Self::BlockSize`.
555+
#[cfg(all(feature = "block-padding", feature = "alloc"))]
556+
#[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))]
557+
#[inline]
558+
fn decrypt_padded_vec<P: Padding<Self::BlockSize>>(
559+
self,
560+
buf: &[u8],
561+
) -> Result<Vec<u8>, UnpadError> {
562+
let mut out = vec![0; buf.len()];
563+
let len = self.decrypt_padded_b2b_mut::<P>(buf, &mut out)?.len();
564+
out.truncate(len);
565+
Ok(out)
566+
}
501567
}
502568

503569
impl<Alg: BlockEncrypt> BlockEncryptMut for Alg {
@@ -568,6 +634,12 @@ impl<'inp, 'out, BS: ArrayLength<u8>> BlockClosure for BlocksCtx<'inp, 'out, BS>
568634
}
569635
}
570636

637+
#[cfg(all(feature = "block-padding", feature = "alloc"))]
638+
fn allocate_out_vec<BS: BlockSizeUser>(len: usize) -> Vec<u8> {
639+
let bs = BS::BlockSize::USIZE;
640+
vec![0; bs * (len / bs + 1)]
641+
}
642+
571643
/// Implement simple block backend
572644
#[macro_export]
573645
macro_rules! impl_simple_block_encdec {

cipher/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
pub use crypto_common;
1818
pub use inout;
1919

20+
#[cfg(all(feature = "block-padding", feature = "alloc"))]
21+
extern crate alloc;
22+
2023
#[cfg(feature = "std")]
2124
extern crate std;
2225

0 commit comments

Comments
 (0)