Skip to content

Commit f17bf09

Browse files
authored
cipher: improve encrypt_padded_vec methods (#2101)
1 parent a0819e2 commit f17bf09

File tree

2 files changed

+68
-20
lines changed

2 files changed

+68
-20
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cipher/src/block.rs

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,43 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized {
127127
self.encrypt_padded_inout::<P>(buf)
128128
}
129129

130-
/// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec.
130+
/// Pad `msg` with padding algorithm `P`, encrypt it into a newly allocated `Vec`,
131+
/// and return the resulting ciphertext vector.
132+
///
133+
/// # Panics
134+
/// If `NoPadding` is used with a message size that is not a multiple of the cipher block size.
131135
#[cfg(all(feature = "block-padding", feature = "alloc"))]
132136
#[inline]
133137
fn encrypt_padded_vec<P: Padding>(&self, msg: &[u8]) -> Vec<u8> {
138+
use block_padding::{NoPadding, ZeroPadding};
139+
use core::any::TypeId;
134140
use crypto_common::typenum::Unsigned;
141+
135142
let bs = Self::BlockSize::USIZE;
136-
let mut out = vec![0; bs * (msg.len() / bs + 1)];
137-
let len = self
138-
.encrypt_padded_b2b::<P>(msg, &mut out)
139-
.expect("enough space for encrypting is allocated")
143+
let msg_len = msg.len();
144+
145+
let pad_type_id = TypeId::of::<P>();
146+
let buf_blocks_len = if pad_type_id == TypeId::of::<NoPadding>() {
147+
if msg_len % bs != 0 {
148+
panic!(
149+
"NoPadding is used with a {msg_len}‑byte message,
150+
which is not a multiple of the {bs}‑byte cipher block size"
151+
);
152+
}
153+
msg_len / bs
154+
} else if pad_type_id == TypeId::of::<ZeroPadding>() {
155+
msg_len.div_ceil(bs)
156+
} else {
157+
1 + msg_len / bs
158+
};
159+
160+
let mut buf = vec![0; bs * buf_blocks_len];
161+
let res_len = self
162+
.encrypt_padded_b2b::<P>(msg, &mut buf)
163+
.expect("`buf` has enough space for encryption")
140164
.len();
141-
out.truncate(len);
142-
out
165+
buf.truncate(res_len);
166+
buf
143167
}
144168
}
145169

@@ -371,19 +395,43 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized {
371395
self.encrypt_padded_inout::<P>(buf)
372396
}
373397

374-
/// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec.
398+
/// Pad `msg` with padding algorithm `P`, encrypt it into a newly allocated `Vec`,
399+
/// and return the resulting ciphertext vector.
400+
///
401+
/// # Panics
402+
/// If `NoPadding` is used with a message size that is not a multiple of the cipher block size.
375403
#[cfg(all(feature = "block-padding", feature = "alloc"))]
376404
#[inline]
377405
fn encrypt_padded_vec<P: Padding>(self, msg: &[u8]) -> Vec<u8> {
406+
use block_padding::{NoPadding, ZeroPadding};
407+
use core::any::TypeId;
378408
use crypto_common::typenum::Unsigned;
409+
379410
let bs = Self::BlockSize::USIZE;
380-
let mut out = vec![0; bs * (msg.len() / bs + 1)];
381-
let len = self
382-
.encrypt_padded_b2b::<P>(msg, &mut out)
383-
.expect("enough space for encrypting is allocated")
411+
let msg_len = msg.len();
412+
413+
let pad_type_id = TypeId::of::<P>();
414+
let buf_blocks_len = if pad_type_id == TypeId::of::<NoPadding>() {
415+
if msg_len % bs != 0 {
416+
panic!(
417+
"NoPadding is used with a {msg_len}‑byte message,
418+
which is not a multiple of the {bs}‑byte cipher block size"
419+
);
420+
}
421+
msg_len / bs
422+
} else if pad_type_id == TypeId::of::<ZeroPadding>() {
423+
msg_len.div_ceil(bs)
424+
} else {
425+
1 + msg_len / bs
426+
};
427+
428+
let mut buf = vec![0; bs * buf_blocks_len];
429+
let res_len = self
430+
.encrypt_padded_b2b::<P>(msg, &mut buf)
431+
.expect("`buf` has enough space for encryption")
384432
.len();
385-
out.truncate(len);
386-
out
433+
buf.truncate(res_len);
434+
buf
387435
}
388436
}
389437

0 commit comments

Comments
 (0)