@@ -29,6 +29,25 @@ pub enum PadType {
2929 NoPadding ,
3030}
3131
32+ /// Trait for padding messages divided into blocks of arbitrary size
33+ pub trait RawPadding {
34+ /// Padding type
35+ const TYPE : PadType ;
36+
37+ /// Pads `block` filled with data up to `pos` (i.e length of a message
38+ /// stored in the block is equal to `pos`).
39+ ///
40+ /// # Panics
41+ /// If `pos` is bigger than `block.len()`. Most padding algorithms also
42+ /// panic if they are equal.
43+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) ;
44+
45+ /// Unpad data in the `block`.
46+ ///
47+ /// Returns `Err(UnpadError)` if the block contains malformed padding.
48+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > ;
49+ }
50+
3251/// Block size.
3352pub type Block < B > = GenericArray < u8 , B > ;
3453
@@ -73,6 +92,23 @@ pub trait Padding<BlockSize: ArrayLength<u8>> {
7392 }
7493}
7594
95+ impl < T , B : ArrayLength < u8 > > Padding < B > for T
96+ where
97+ T : RawPadding ,
98+ {
99+ const TYPE : PadType = T :: TYPE ;
100+
101+ #[ inline]
102+ fn pad ( block : & mut Block < B > , pos : usize ) {
103+ T :: raw_pad ( block. as_mut_slice ( ) , pos) ;
104+ }
105+
106+ #[ inline]
107+ fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
108+ T :: raw_unpad ( block. as_slice ( ) )
109+ }
110+ }
111+
76112/// Pad block with zeros.
77113///
78114/// ```
@@ -94,12 +130,12 @@ pub trait Padding<BlockSize: ArrayLength<u8>> {
94130#[ derive( Clone , Copy , Debug ) ]
95131pub struct ZeroPadding ;
96132
97- impl < B : ArrayLength < u8 > > Padding < B > for ZeroPadding {
133+ impl RawPadding for ZeroPadding {
98134 const TYPE : PadType = PadType :: Ambiguous ;
99135
100136 #[ inline]
101- fn pad ( block : & mut Block < B > , pos : usize ) {
102- if pos > B :: USIZE {
137+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
138+ if pos > block . len ( ) {
103139 panic ! ( "`pos` is bigger than block size" ) ;
104140 }
105141 for b in & mut block[ pos..] {
@@ -108,8 +144,8 @@ impl<B: ArrayLength<u8>> Padding<B> for ZeroPadding {
108144 }
109145
110146 #[ inline]
111- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
112- for i in ( 0 ..B :: USIZE ) . rev ( ) {
147+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
148+ for i in ( 0 ..block . len ( ) ) . rev ( ) {
113149 if block[ i] != 0 {
114150 return Ok ( & block[ ..i + 1 ] ) ;
115151 }
@@ -140,12 +176,12 @@ pub struct Pkcs7;
140176
141177impl Pkcs7 {
142178 #[ inline]
143- fn unpad < B : ArrayLength < u8 > > ( block : & Block < B > , strict : bool ) -> Result < & [ u8 ] , UnpadError > {
179+ fn unpad ( block : & [ u8 ] , strict : bool ) -> Result < & [ u8 ] , UnpadError > {
144180 // TODO: use bounds to check it at compile time
145- if B :: USIZE > 255 {
181+ if block . len ( ) > 255 {
146182 panic ! ( "block size is too big for PKCS#7" ) ;
147183 }
148- let bs = B :: USIZE ;
184+ let bs = block . len ( ) ;
149185 let n = block[ bs - 1 ] ;
150186 if n == 0 || n as usize > bs {
151187 return Err ( UnpadError ) ;
@@ -158,26 +194,26 @@ impl Pkcs7 {
158194 }
159195}
160196
161- impl < B : ArrayLength < u8 > > Padding < B > for Pkcs7 {
197+ impl RawPadding for Pkcs7 {
162198 const TYPE : PadType = PadType :: Reversible ;
163199
164200 #[ inline]
165- fn pad ( block : & mut Block < B > , pos : usize ) {
166- // TODO: use bounds to check it at compile time
167- if B :: USIZE > 255 {
201+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
202+ // TODO: use bounds to check it at compile time for Padding<B>
203+ if block . len ( ) > 255 {
168204 panic ! ( "block size is too big for PKCS#7" ) ;
169205 }
170- if pos >= B :: USIZE {
206+ if pos >= block . len ( ) {
171207 panic ! ( "`pos` is bigger or equal to block size" ) ;
172208 }
173- let n = ( B :: USIZE - pos) as u8 ;
209+ let n = ( block . len ( ) - pos) as u8 ;
174210 for b in & mut block[ pos..] {
175211 * b = n;
176212 }
177213 }
178214
179215 #[ inline]
180- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
216+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
181217 Pkcs7 :: unpad ( block, true )
182218 }
183219}
@@ -202,18 +238,18 @@ impl<B: ArrayLength<u8>> Padding<B> for Pkcs7 {
202238#[ derive( Clone , Copy , Debug ) ]
203239pub struct Iso10126 ;
204240
205- impl < B : ArrayLength < u8 > > Padding < B > for Iso10126 {
241+ impl RawPadding for Iso10126 {
206242 const TYPE : PadType = PadType :: Reversible ;
207243
208244 #[ inline]
209- fn pad ( block : & mut Block < B > , pos : usize ) {
245+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
210246 // Instead of generating random bytes as specified by Iso10126 we
211247 // simply use Pkcs7 padding.
212- Pkcs7 :: pad ( block, pos)
248+ Pkcs7 :: raw_pad ( block, pos)
213249 }
214250
215251 #[ inline]
216- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
252+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
217253 Pkcs7 :: unpad ( block, false )
218254 }
219255}
@@ -237,32 +273,32 @@ impl<B: ArrayLength<u8>> Padding<B> for Iso10126 {
237273#[ derive( Clone , Copy , Debug ) ]
238274pub struct AnsiX923 ;
239275
240- impl < B : ArrayLength < u8 > > Padding < B > for AnsiX923 {
276+ impl RawPadding for AnsiX923 {
241277 const TYPE : PadType = PadType :: Reversible ;
242278
243279 #[ inline]
244- fn pad ( block : & mut Block < B > , pos : usize ) {
280+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
245281 // TODO: use bounds to check it at compile time
246- if B :: USIZE > 255 {
282+ if block . len ( ) > 255 {
247283 panic ! ( "block size is too big for PKCS#7" ) ;
248284 }
249- if pos >= B :: USIZE {
285+ if pos >= block . len ( ) {
250286 panic ! ( "`pos` is bigger or equal to block size" ) ;
251287 }
252- let bs = B :: USIZE ;
288+ let bs = block . len ( ) ;
253289 for b in & mut block[ pos..bs - 1 ] {
254290 * b = 0 ;
255291 }
256292 block[ bs - 1 ] = ( bs - pos) as u8 ;
257293 }
258294
259295 #[ inline]
260- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
296+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
261297 // TODO: use bounds to check it at compile time
262- if B :: USIZE > 255 {
298+ if block . len ( ) > 255 {
263299 panic ! ( "block size is too big for PKCS#7" ) ;
264300 }
265- let bs = B :: USIZE ;
301+ let bs = block . len ( ) ;
266302 let n = block[ bs - 1 ] as usize ;
267303 if n == 0 || n > bs {
268304 return Err ( UnpadError ) ;
@@ -293,12 +329,12 @@ impl<B: ArrayLength<u8>> Padding<B> for AnsiX923 {
293329#[ derive( Clone , Copy , Debug ) ]
294330pub struct Iso7816 ;
295331
296- impl < B : ArrayLength < u8 > > Padding < B > for Iso7816 {
332+ impl RawPadding for Iso7816 {
297333 const TYPE : PadType = PadType :: Reversible ;
298334
299335 #[ inline]
300- fn pad ( block : & mut Block < B > , pos : usize ) {
301- if pos >= B :: USIZE {
336+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
337+ if pos >= block . len ( ) {
302338 panic ! ( "`pos` is bigger or equal to block size" ) ;
303339 }
304340 block[ pos] = 0x80 ;
@@ -308,8 +344,8 @@ impl<B: ArrayLength<u8>> Padding<B> for Iso7816 {
308344 }
309345
310346 #[ inline]
311- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
312- for i in ( 0 ..B :: USIZE ) . rev ( ) {
347+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
348+ for i in ( 0 ..block . len ( ) ) . rev ( ) {
313349 match block[ i] {
314350 0x80 => return Ok ( & block[ ..i] ) ,
315351 0x00 => continue ,
@@ -344,18 +380,18 @@ impl<B: ArrayLength<u8>> Padding<B> for Iso7816 {
344380#[ derive( Clone , Copy , Debug ) ]
345381pub struct NoPadding ;
346382
347- impl < B : ArrayLength < u8 > > Padding < B > for NoPadding {
383+ impl RawPadding for NoPadding {
348384 const TYPE : PadType = PadType :: NoPadding ;
349385
350386 #[ inline]
351- fn pad ( _block : & mut Block < B > , pos : usize ) {
352- if pos > B :: USIZE {
387+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
388+ if pos > block . len ( ) {
353389 panic ! ( "`pos` is bigger than block size" ) ;
354390 }
355391 }
356392
357393 #[ inline]
358- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
394+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
359395 Ok ( block)
360396 }
361397}
0 commit comments