diff --git a/Cargo.lock b/Cargo.lock index 3ca9a67bd..45c4eb83a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d28ed5f5f65056148fd25e1a596b5b6d9e772270abf9a9085d7cbfbf26c563" +checksum = "710f1dd022ef4e93f8a438b4ba958de7f64308434fa6a87104481645cc30068b" dependencies = [ "hybrid-array", ] @@ -212,7 +212,7 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "getrandom" version = "0.3.4" -source = "git+https://github.com/rust-random/getrandom#6cbbcb4a434f918a9a54bede9694f8138df2856d" +source = "git+https://github.com/rust-random/getrandom#658bb1a43cade84eb7aa63a3225cfa9d12b826b8" dependencies = [ "cfg-if", "libc", @@ -469,7 +469,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.109", + "syn 2.0.111", ] [[package]] @@ -519,9 +519,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.109" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", diff --git a/cipher/src/block.rs b/cipher/src/block.rs index b930199d9..4b797ad5b 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -127,19 +127,43 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized { self.encrypt_padded_inout::

(buf) } - /// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec. + /// Pad `msg` with padding algorithm `P`, encrypt it into a newly allocated `Vec`, + /// and return the resulting ciphertext vector. + /// + /// # Panics + /// If `NoPadding` is used with a message size that is not a multiple of the cipher block size. #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] fn encrypt_padded_vec(&self, msg: &[u8]) -> Vec { + use block_padding::{NoPadding, ZeroPadding}; + use core::any::TypeId; use crypto_common::typenum::Unsigned; + let bs = Self::BlockSize::USIZE; - let mut out = vec![0; bs * (msg.len() / bs + 1)]; - let len = self - .encrypt_padded_b2b::

(msg, &mut out) - .expect("enough space for encrypting is allocated") + let msg_len = msg.len(); + + let pad_type_id = TypeId::of::

(); + let buf_blocks_len = if pad_type_id == TypeId::of::() { + if msg_len % bs != 0 { + panic!( + "NoPadding is used with a {msg_len}‑byte message, + which is not a multiple of the {bs}‑byte cipher block size" + ); + } + msg_len / bs + } else if pad_type_id == TypeId::of::() { + msg_len.div_ceil(bs) + } else { + 1 + msg_len / bs + }; + + let mut buf = vec![0; bs * buf_blocks_len]; + let res_len = self + .encrypt_padded_b2b::

(msg, &mut buf) + .expect("`buf` has enough space for encryption") .len(); - out.truncate(len); - out + buf.truncate(res_len); + buf } } @@ -371,19 +395,43 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { self.encrypt_padded_inout::

(buf) } - /// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec. + /// Pad `msg` with padding algorithm `P`, encrypt it into a newly allocated `Vec`, + /// and return the resulting ciphertext vector. + /// + /// # Panics + /// If `NoPadding` is used with a message size that is not a multiple of the cipher block size. #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] fn encrypt_padded_vec(self, msg: &[u8]) -> Vec { + use block_padding::{NoPadding, ZeroPadding}; + use core::any::TypeId; use crypto_common::typenum::Unsigned; + let bs = Self::BlockSize::USIZE; - let mut out = vec![0; bs * (msg.len() / bs + 1)]; - let len = self - .encrypt_padded_b2b::

(msg, &mut out) - .expect("enough space for encrypting is allocated") + let msg_len = msg.len(); + + let pad_type_id = TypeId::of::

(); + let buf_blocks_len = if pad_type_id == TypeId::of::() { + if msg_len % bs != 0 { + panic!( + "NoPadding is used with a {msg_len}‑byte message, + which is not a multiple of the {bs}‑byte cipher block size" + ); + } + msg_len / bs + } else if pad_type_id == TypeId::of::() { + msg_len.div_ceil(bs) + } else { + 1 + msg_len / bs + }; + + let mut buf = vec![0; bs * buf_blocks_len]; + let res_len = self + .encrypt_padded_b2b::

(msg, &mut buf) + .expect("`buf` has enough space for encryption") .len(); - out.truncate(len); - out + buf.truncate(res_len); + buf } }