@@ -58,15 +58,27 @@ impl StreamingEncryptingKey {
58
58
}
59
59
60
60
pub fn cbc_pkcs7 ( key : UnboundCipherKey ) -> Result < Self , Unspecified > {
61
- let mode = OperatingMode :: CBC ;
62
- let context = key. algorithm ( ) . new_encryption_context ( mode) ?;
63
- StreamingEncryptingKey :: new ( key, mode, context)
61
+ let context = key. algorithm ( ) . new_encryption_context ( OperatingMode :: CBC ) ?;
62
+ Self :: less_safe_cbc_pkcs7 ( key, context)
63
+ }
64
+
65
+ pub fn less_safe_cbc_pkcs7 (
66
+ key : UnboundCipherKey ,
67
+ context : EncryptionContext ,
68
+ ) -> Result < Self , Unspecified > {
69
+ StreamingEncryptingKey :: new ( key, OperatingMode :: CBC , context)
64
70
}
65
71
66
72
pub fn ctr ( key : UnboundCipherKey ) -> Result < Self , Unspecified > {
67
- let mode = OperatingMode :: CTR ;
68
- let context = key. algorithm ( ) . new_encryption_context ( mode) ?;
69
- StreamingEncryptingKey :: new ( key, mode, context)
73
+ let context = key. algorithm ( ) . new_encryption_context ( OperatingMode :: CTR ) ?;
74
+ Self :: less_safe_ctr ( key, context)
75
+ }
76
+
77
+ pub fn less_safe_ctr (
78
+ key : UnboundCipherKey ,
79
+ context : EncryptionContext ,
80
+ ) -> Result < Self , Unspecified > {
81
+ StreamingEncryptingKey :: new ( key, OperatingMode :: CTR , context)
70
82
}
71
83
72
84
/// Returns the cipher operating mode.
@@ -81,7 +93,7 @@ impl StreamingEncryptingKey {
81
93
}
82
94
83
95
pub fn update < ' a > ( & self , input : & [ u8 ] , output : & ' a mut [ u8 ] ) -> Result < usize , Unspecified > {
84
- if output. len ( ) < ( input. len ( ) + self . algorithm . block_len - 1 ) {
96
+ if output. len ( ) < ( input. len ( ) + self . algorithm . block_len ) {
85
97
return Err ( Unspecified ) ;
86
98
}
87
99
@@ -215,11 +227,86 @@ impl StreamingDecryptingKey {
215
227
#[ cfg( test) ]
216
228
mod tests {
217
229
use crate :: cipher:: stream:: { StreamingDecryptingKey , StreamingEncryptingKey } ;
218
- use crate :: cipher:: { Algorithm , UnboundCipherKey , AES_256 , AES_256_KEY_LEN } ;
230
+ use crate :: cipher:: { Algorithm , DecryptionContext , UnboundCipherKey , AES_256 , AES_256_KEY_LEN } ;
219
231
use crate :: rand:: { SecureRandom , SystemRandom } ;
220
232
use paste:: * ;
221
233
222
- macro_rules! helper_stream_step_test {
234
+ fn step_encrypt (
235
+ encrypting_key : StreamingEncryptingKey ,
236
+ plaintext : & [ u8 ] ,
237
+ step : usize ,
238
+ ) -> ( Box < [ u8 ] > , DecryptionContext ) {
239
+ let alg = encrypting_key. algorithm ( ) ;
240
+ let mode = encrypting_key. mode ( ) ;
241
+ let n = plaintext. len ( ) ;
242
+ let mut ciphertext = vec ! [ 0u8 ; n + alg. block_len( ) ] ;
243
+
244
+ let mut in_idx: usize = 0 ;
245
+ let mut out_idx: usize = 0 ;
246
+ loop {
247
+ let mut in_end = in_idx + step;
248
+ if in_end > n {
249
+ in_end = n;
250
+ }
251
+ let out_end = out_idx + ( in_end - in_idx) + alg. block_len ( ) ;
252
+ let outlen = encrypting_key
253
+ . update (
254
+ & plaintext[ in_idx..in_end] ,
255
+ & mut ciphertext[ out_idx..out_end] ,
256
+ )
257
+ . unwrap ( ) ;
258
+ in_idx += step;
259
+ out_idx += outlen;
260
+ if in_idx >= n {
261
+ break ;
262
+ }
263
+ }
264
+ let out_end = out_idx + alg. block_len ( ) ;
265
+ let ( decrypt_iv, outlen) = encrypting_key
266
+ . finish ( & mut ciphertext[ out_idx..out_end] )
267
+ . unwrap ( ) ;
268
+
269
+ ciphertext. truncate ( out_idx + outlen) ;
270
+ ( ciphertext. into_boxed_slice ( ) , decrypt_iv)
271
+ }
272
+
273
+ fn step_decrypt (
274
+ decrypting_key : StreamingDecryptingKey ,
275
+ ciphertext : & [ u8 ] ,
276
+ step : usize ,
277
+ ) -> Box < [ u8 ] > {
278
+ let alg = decrypting_key. algorithm ( ) ;
279
+ let n = ciphertext. len ( ) ;
280
+ let mut output = vec ! [ 0u8 ; n + alg. block_len( ) ] ;
281
+
282
+ let mut in_idx: usize = 0 ;
283
+ let mut out_idx: usize = 0 ;
284
+ loop {
285
+ let mut in_end = in_idx + step;
286
+ if in_end > n {
287
+ in_end = n;
288
+ }
289
+ let out_end = out_idx + ( in_end - in_idx) + alg. block_len ( ) ;
290
+ let outlen = decrypting_key
291
+ . update ( & ciphertext[ in_idx..in_end] , & mut output[ out_idx..out_end] )
292
+ . unwrap ( ) ;
293
+ in_idx += step;
294
+ out_idx += outlen;
295
+ if in_idx >= n {
296
+ break ;
297
+ }
298
+ }
299
+ let out_end = out_idx + alg. block_len ( ) ;
300
+ let outlen = decrypting_key
301
+ . finish ( & mut output[ out_idx..out_end] )
302
+ . unwrap ( ) ;
303
+
304
+ output. truncate ( out_idx + outlen) ;
305
+
306
+ output. into_boxed_slice ( )
307
+ }
308
+
309
+ macro_rules! helper_stream_step_encrypt_test {
223
310
( $mode: ident) => {
224
311
paste! {
225
312
fn [ <helper_test_ $mode _stream_encrypt_step_n_bytes>] (
@@ -228,82 +315,58 @@ mod tests {
228
315
n: usize ,
229
316
step: usize ,
230
317
) {
231
- let mut input: Vec <u8 > = Vec :: with_capacity( n) ;
232
- for i in 0 ..n {
233
- let byte: u8 = ( i % 256 ) . try_into( ) . unwrap( ) ;
234
- input. push( byte) ;
235
- }
318
+ let mut input = vec![ 0u8 ; n] ;
319
+ let random = SystemRandom :: new( ) ;
320
+ random. fill( & mut input) . unwrap( ) ;
236
321
237
322
let cipher_key = UnboundCipherKey :: new( alg, key) . unwrap( ) ;
238
323
let encrypting_key = StreamingEncryptingKey :: $mode( cipher_key) . unwrap( ) ;
239
324
240
- let mut ciphertext = vec![ 0u8 ; n + alg. block_len( ) ] ;
241
-
242
- let mut in_idx: usize = 0 ;
243
- let mut out_idx: usize = 0 ;
244
- loop {
245
- let mut in_end = in_idx + step;
246
- if in_end > n {
247
- in_end = n;
248
- }
249
- let out_end = out_idx + ( in_end - in_idx) + alg. block_len( ) - 1 ;
250
- let outlen = encrypting_key
251
- . update( & input[ in_idx..in_end] , & mut ciphertext[ out_idx..out_end] )
252
- . unwrap( ) ;
253
- in_idx += step;
254
- out_idx += outlen;
255
- if in_idx >= n {
256
- break ;
257
- }
258
- }
259
- let out_end = out_idx + alg. block_len( ) ;
260
- let ( decrypt_iv, outlen) = encrypting_key
261
- . finish( & mut ciphertext[ out_idx..out_end] )
262
- . unwrap( ) ;
263
- eprintln!( "{} ciphertext length: n: {}, step: {}, cipherlength: {}" , stringify!( $mode) , n, step, out_idx + outlen) ;
264
- ciphertext. truncate( out_idx + outlen) ;
325
+ let ( ciphertext, decrypt_iv) = step_encrypt( encrypting_key, & input, step) ;
265
326
266
327
let cipher_key2 = UnboundCipherKey :: new( alg, key) . unwrap( ) ;
267
328
let decrypting_key = StreamingDecryptingKey :: $mode( cipher_key2, decrypt_iv) . unwrap( ) ;
268
329
269
- let mut plaintext = vec![ 0u8 ; n + 2 * alg. block_len( ) ] ;
270
- let outlen = decrypting_key
271
- . update( ciphertext. as_slice( ) , plaintext. as_mut_slice( ) )
272
- . unwrap( ) ;
273
- let outlen = outlen + decrypting_key. finish( & mut plaintext[ outlen..n] ) . unwrap( ) ;
330
+ let plaintext = step_decrypt( decrypting_key, & ciphertext, step) ;
274
331
275
- assert_eq!( input. as_slice( ) , & plaintext[ 0 ..outlen ] ) ;
332
+ assert_eq!( input. as_slice( ) , & * plaintext) ;
276
333
}
277
334
}
278
335
279
336
} ;
280
337
}
281
338
282
- helper_stream_step_test ! ( cbc_pkcs7) ;
283
- helper_stream_step_test ! ( ctr) ;
339
+ helper_stream_step_encrypt_test ! ( cbc_pkcs7) ;
340
+ helper_stream_step_encrypt_test ! ( ctr) ;
284
341
285
342
#[ test]
286
- fn test_cbc ( ) {
343
+ fn test_step_cbc ( ) {
287
344
let random = SystemRandom :: new ( ) ;
288
345
let mut key = [ 0u8 ; AES_256_KEY_LEN ] ;
289
346
random. fill ( & mut key) . unwrap ( ) ;
290
347
291
348
for i in 13 ..=21 {
292
- for j in 125 ..=131 {
349
+ for j in 124 ..=131 {
293
350
let _ = helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes ( & key, & AES_256 , j, i) ;
294
351
}
352
+ for j in 124 ..=131 {
353
+ let _ = helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes ( & key, & AES_256 , j, j - i) ;
354
+ }
295
355
}
296
356
}
297
357
298
358
#[ test]
299
- fn test_ctr ( ) {
359
+ fn test_step_ctr ( ) {
300
360
let random = SystemRandom :: new ( ) ;
301
361
let mut key = [ 0u8 ; AES_256_KEY_LEN ] ;
302
362
random. fill ( & mut key) . unwrap ( ) ;
303
363
for i in 13 ..=21 {
304
- for j in 125 ..=131 {
364
+ for j in 124 ..=131 {
305
365
let _ = helper_test_ctr_stream_encrypt_step_n_bytes ( & key, & AES_256 , j, i) ;
306
366
}
367
+ for j in 124 ..=131 {
368
+ let _ = helper_test_ctr_stream_encrypt_step_n_bytes ( & key, & AES_256 , j, j - i) ;
369
+ }
307
370
}
308
371
}
309
372
}
0 commit comments