@@ -29,6 +29,25 @@ pub enum PadType {
29
29
NoPadding ,
30
30
}
31
31
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
+
32
51
/// Block size.
33
52
pub type Block < B > = GenericArray < u8 , B > ;
34
53
@@ -73,6 +92,23 @@ pub trait Padding<BlockSize: ArrayLength<u8>> {
73
92
}
74
93
}
75
94
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
+
76
112
/// Pad block with zeros.
77
113
///
78
114
/// ```
@@ -94,12 +130,12 @@ pub trait Padding<BlockSize: ArrayLength<u8>> {
94
130
#[ derive( Clone , Copy , Debug ) ]
95
131
pub struct ZeroPadding ;
96
132
97
- impl < B : ArrayLength < u8 > > Padding < B > for ZeroPadding {
133
+ impl RawPadding for ZeroPadding {
98
134
const TYPE : PadType = PadType :: Ambiguous ;
99
135
100
136
#[ 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 ( ) {
103
139
panic ! ( "`pos` is bigger than block size" ) ;
104
140
}
105
141
for b in & mut block[ pos..] {
@@ -108,8 +144,8 @@ impl<B: ArrayLength<u8>> Padding<B> for ZeroPadding {
108
144
}
109
145
110
146
#[ 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 ( ) {
113
149
if block[ i] != 0 {
114
150
return Ok ( & block[ ..i + 1 ] ) ;
115
151
}
@@ -140,12 +176,12 @@ pub struct Pkcs7;
140
176
141
177
impl Pkcs7 {
142
178
#[ 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 > {
144
180
// TODO: use bounds to check it at compile time
145
- if B :: USIZE > 255 {
181
+ if block . len ( ) > 255 {
146
182
panic ! ( "block size is too big for PKCS#7" ) ;
147
183
}
148
- let bs = B :: USIZE ;
184
+ let bs = block . len ( ) ;
149
185
let n = block[ bs - 1 ] ;
150
186
if n == 0 || n as usize > bs {
151
187
return Err ( UnpadError ) ;
@@ -158,26 +194,26 @@ impl Pkcs7 {
158
194
}
159
195
}
160
196
161
- impl < B : ArrayLength < u8 > > Padding < B > for Pkcs7 {
197
+ impl RawPadding for Pkcs7 {
162
198
const TYPE : PadType = PadType :: Reversible ;
163
199
164
200
#[ 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 {
168
204
panic ! ( "block size is too big for PKCS#7" ) ;
169
205
}
170
- if pos >= B :: USIZE {
206
+ if pos >= block . len ( ) {
171
207
panic ! ( "`pos` is bigger or equal to block size" ) ;
172
208
}
173
- let n = ( B :: USIZE - pos) as u8 ;
209
+ let n = ( block . len ( ) - pos) as u8 ;
174
210
for b in & mut block[ pos..] {
175
211
* b = n;
176
212
}
177
213
}
178
214
179
215
#[ inline]
180
- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
216
+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
181
217
Pkcs7 :: unpad ( block, true )
182
218
}
183
219
}
@@ -202,18 +238,18 @@ impl<B: ArrayLength<u8>> Padding<B> for Pkcs7 {
202
238
#[ derive( Clone , Copy , Debug ) ]
203
239
pub struct Iso10126 ;
204
240
205
- impl < B : ArrayLength < u8 > > Padding < B > for Iso10126 {
241
+ impl RawPadding for Iso10126 {
206
242
const TYPE : PadType = PadType :: Reversible ;
207
243
208
244
#[ inline]
209
- fn pad ( block : & mut Block < B > , pos : usize ) {
245
+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
210
246
// Instead of generating random bytes as specified by Iso10126 we
211
247
// simply use Pkcs7 padding.
212
- Pkcs7 :: pad ( block, pos)
248
+ Pkcs7 :: raw_pad ( block, pos)
213
249
}
214
250
215
251
#[ inline]
216
- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
252
+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
217
253
Pkcs7 :: unpad ( block, false )
218
254
}
219
255
}
@@ -237,32 +273,32 @@ impl<B: ArrayLength<u8>> Padding<B> for Iso10126 {
237
273
#[ derive( Clone , Copy , Debug ) ]
238
274
pub struct AnsiX923 ;
239
275
240
- impl < B : ArrayLength < u8 > > Padding < B > for AnsiX923 {
276
+ impl RawPadding for AnsiX923 {
241
277
const TYPE : PadType = PadType :: Reversible ;
242
278
243
279
#[ inline]
244
- fn pad ( block : & mut Block < B > , pos : usize ) {
280
+ fn raw_pad ( block : & mut [ u8 ] , pos : usize ) {
245
281
// TODO: use bounds to check it at compile time
246
- if B :: USIZE > 255 {
282
+ if block . len ( ) > 255 {
247
283
panic ! ( "block size is too big for PKCS#7" ) ;
248
284
}
249
- if pos >= B :: USIZE {
285
+ if pos >= block . len ( ) {
250
286
panic ! ( "`pos` is bigger or equal to block size" ) ;
251
287
}
252
- let bs = B :: USIZE ;
288
+ let bs = block . len ( ) ;
253
289
for b in & mut block[ pos..bs - 1 ] {
254
290
* b = 0 ;
255
291
}
256
292
block[ bs - 1 ] = ( bs - pos) as u8 ;
257
293
}
258
294
259
295
#[ inline]
260
- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
296
+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
261
297
// TODO: use bounds to check it at compile time
262
- if B :: USIZE > 255 {
298
+ if block . len ( ) > 255 {
263
299
panic ! ( "block size is too big for PKCS#7" ) ;
264
300
}
265
- let bs = B :: USIZE ;
301
+ let bs = block . len ( ) ;
266
302
let n = block[ bs - 1 ] as usize ;
267
303
if n == 0 || n > bs {
268
304
return Err ( UnpadError ) ;
@@ -293,12 +329,12 @@ impl<B: ArrayLength<u8>> Padding<B> for AnsiX923 {
293
329
#[ derive( Clone , Copy , Debug ) ]
294
330
pub struct Iso7816 ;
295
331
296
- impl < B : ArrayLength < u8 > > Padding < B > for Iso7816 {
332
+ impl RawPadding for Iso7816 {
297
333
const TYPE : PadType = PadType :: Reversible ;
298
334
299
335
#[ 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 ( ) {
302
338
panic ! ( "`pos` is bigger or equal to block size" ) ;
303
339
}
304
340
block[ pos] = 0x80 ;
@@ -308,8 +344,8 @@ impl<B: ArrayLength<u8>> Padding<B> for Iso7816 {
308
344
}
309
345
310
346
#[ 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 ( ) {
313
349
match block[ i] {
314
350
0x80 => return Ok ( & block[ ..i] ) ,
315
351
0x00 => continue ,
@@ -344,18 +380,18 @@ impl<B: ArrayLength<u8>> Padding<B> for Iso7816 {
344
380
#[ derive( Clone , Copy , Debug ) ]
345
381
pub struct NoPadding ;
346
382
347
- impl < B : ArrayLength < u8 > > Padding < B > for NoPadding {
383
+ impl RawPadding for NoPadding {
348
384
const TYPE : PadType = PadType :: NoPadding ;
349
385
350
386
#[ 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 ( ) {
353
389
panic ! ( "`pos` is bigger than block size" ) ;
354
390
}
355
391
}
356
392
357
393
#[ inline]
358
- fn unpad ( block : & Block < B > ) -> Result < & [ u8 ] , UnpadError > {
394
+ fn raw_unpad ( block : & [ u8 ] ) -> Result < & [ u8 ] , UnpadError > {
359
395
Ok ( block)
360
396
}
361
397
}
0 commit comments