@@ -16,37 +16,23 @@ pub use hybrid_array as array;
1616use core:: fmt;
1717use hybrid_array:: { Array , ArraySize } ;
1818
19- /// Padding types
20- #[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
21- pub enum PadType {
22- /// Reversible padding
23- Reversible ,
24- /// Ambiguous padding
25- Ambiguous ,
26- /// No padding, message must be multiple of block size
27- NoPadding ,
28- }
29-
30- /// Trait for messages padding algorithms.
19+ /// Trait for message padding algorithms.
3120pub trait Padding {
32- /// Padding type
33- const TYPE : PadType ;
34-
35- /// Pads `block` filled with data up to `pos` (i.e length of a message
36- /// stored in the block is equal to `pos`).
21+ /// Pads `block` filled with data up to `pos` (i.e the message length
22+ /// stored in `block` is equal to `pos`).
3723 ///
3824 /// # Panics
3925 /// If `pos` is bigger than `block.len()`. Most padding algorithms also
4026 /// panic if they are equal.
4127 fn raw_pad ( block : & mut [ u8 ] , pos : usize ) ;
4228
43- /// Unpad data in the `block`.
29+ /// Unpad data in `block`.
4430 ///
4531 /// Returns `Err(UnpadError)` if the block contains malformed padding.
4632 fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > ;
4733
48- /// Pads `block` filled with data up to `pos` (i.e length of a message
49- /// stored in the block is equal to `pos`).
34+ /// Pads `block` filled with data up to `pos` (i.e the message length
35+ /// stored in ` block` is equal to `pos`).
5036 ///
5137 /// # Panics
5238 /// If `pos` is bigger than `BlockSize`. Most padding algorithms also
@@ -55,32 +41,26 @@ pub trait Padding {
5541 Self :: raw_pad ( block. as_mut_slice ( ) , pos) ;
5642 }
5743
58- /// Unpad data in the `block`.
44+ /// Unpad data in `block`.
5945 ///
6046 /// Returns `Err(UnpadError)` if the block contains malformed padding.
6147 fn unpad < BlockSize : ArraySize > ( block : & Array < u8 , BlockSize > ) -> Result < & [ u8 ] , UnpadError > {
6248 Self :: raw_unpad ( block. as_slice ( ) )
6349 }
6450
65- /// Unpad data in the `blocks`.
51+ /// Unpad data in `blocks` and return unpadded byte slice .
6652 ///
6753 /// Returns `Err(UnpadError)` if the block contains malformed padding.
6854 fn unpad_blocks < BlockSize : ArraySize > (
6955 blocks : & [ Array < u8 , BlockSize > ] ,
7056 ) -> Result < & [ u8 ] , UnpadError > {
7157 let bs = BlockSize :: USIZE ;
72- let res_len = match ( blocks. last ( ) , Self :: TYPE ) {
73- ( _, PadType :: NoPadding ) => bs * blocks. len ( ) ,
74- ( Some ( last_block) , _) => {
75- let n = Self :: unpad ( last_block) ?. len ( ) ;
76- assert ! ( n <= bs) ;
77- n + bs * ( blocks. len ( ) - 1 )
78- }
79- ( None , PadType :: Ambiguous ) => 0 ,
80- ( None , PadType :: Reversible ) => return Err ( UnpadError ) ,
81- } ;
82- let data = Array :: slice_as_flattened ( blocks) ;
83- Ok ( & data[ ..res_len] )
58+ let ( last_block, full_blocks) = blocks. split_last ( ) . ok_or ( UnpadError ) ?;
59+ let unpad_len = Self :: unpad ( last_block) ?. len ( ) ;
60+ assert ! ( unpad_len <= bs) ;
61+ let buf = Array :: slice_as_flattened ( blocks) ;
62+ let data_len = full_blocks. len ( ) * bs + unpad_len;
63+ Ok ( & buf[ ..data_len] )
8464 }
8565}
8666
@@ -106,8 +86,6 @@ pub trait Padding {
10686pub struct ZeroPadding ;
10787
10888impl Padding for ZeroPadding {
109- const TYPE : PadType = PadType :: Ambiguous ;
110-
11189 #[ inline]
11290 fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
11391 if pos > block. len ( ) {
@@ -125,6 +103,21 @@ impl Padding for ZeroPadding {
125103 }
126104 Ok ( & block[ ..0 ] )
127105 }
106+
107+ fn unpad_blocks < BlockSize : ArraySize > (
108+ blocks : & [ Array < u8 , BlockSize > ] ,
109+ ) -> Result < & [ u8 ] , UnpadError > {
110+ let buf = Array :: slice_as_flattened ( blocks) ;
111+ if blocks. is_empty ( ) {
112+ return Ok ( buf) ;
113+ }
114+ let bs = BlockSize :: USIZE ;
115+ let ( last_block, full_blocks) = blocks. split_last ( ) . unwrap ( ) ;
116+ let unpad_len = Self :: unpad ( last_block) ?. len ( ) ;
117+ assert ! ( unpad_len <= bs) ;
118+ let data_len = full_blocks. len ( ) * bs + unpad_len;
119+ Ok ( & buf[ ..data_len] )
120+ }
128121}
129122
130123/// Pad block with bytes with value equal to the number of bytes added.
@@ -168,8 +161,6 @@ impl Pkcs7 {
168161}
169162
170163impl Padding for Pkcs7 {
171- const TYPE : PadType = PadType :: Reversible ;
172-
173164 #[ inline]
174165 fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
175166 // TODO: use bounds to check it at compile time for Padding<B>
@@ -210,8 +201,6 @@ impl Padding for Pkcs7 {
210201pub struct Iso10126 ;
211202
212203impl Padding for Iso10126 {
213- const TYPE : PadType = PadType :: Reversible ;
214-
215204 #[ inline]
216205 fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
217206 // Instead of generating random bytes as specified by Iso10126 we
@@ -245,8 +234,6 @@ impl Padding for Iso10126 {
245234pub struct AnsiX923 ;
246235
247236impl Padding for AnsiX923 {
248- const TYPE : PadType = PadType :: Reversible ;
249-
250237 #[ inline]
251238 fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
252239 // TODO: use bounds to check it at compile time
@@ -299,8 +286,6 @@ impl Padding for AnsiX923 {
299286pub struct Iso7816 ;
300287
301288impl Padding for Iso7816 {
302- const TYPE : PadType = PadType :: Reversible ;
303-
304289 #[ inline]
305290 fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
306291 if pos >= block. len ( ) {
@@ -348,8 +333,6 @@ impl Padding for Iso7816 {
348333pub struct NoPadding ;
349334
350335impl Padding for NoPadding {
351- const TYPE : PadType = PadType :: NoPadding ;
352-
353336 #[ inline]
354337 fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
355338 if pos > block. len ( ) {
@@ -361,6 +344,12 @@ impl Padding for NoPadding {
361344 fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
362345 Ok ( block)
363346 }
347+
348+ fn unpad_blocks < BlockSize : ArraySize > (
349+ blocks : & [ Array < u8 , BlockSize > ] ,
350+ ) -> Result < & [ u8 ] , UnpadError > {
351+ Ok ( Array :: slice_as_flattened ( blocks) )
352+ }
364353}
365354
366355/// Failed unpadding operation error.
0 commit comments