@@ -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