@@ -145,7 +145,7 @@ impl<O: Operation, T: Type> Cipher<O, T, Fresh> {
145
145
146
146
// Put together the structure to return
147
147
Ok ( Cipher {
148
- raw_cipher : raw_cipher ,
148
+ raw_cipher,
149
149
padding : raw:: CipherPadding :: Pkcs7 ,
150
150
_op : PhantomData ,
151
151
_type : PhantomData ,
@@ -273,6 +273,27 @@ impl Cipher<Encryption, TraditionalNoIv, Fresh> {
273
273
}
274
274
275
275
impl Cipher < Encryption , Authenticated , AdditionalData > {
276
+ /// The authenticated encryption (AEAD/NIST_KW) function.
277
+ ///
278
+ /// For AEAD modes, the tag will be appended to the ciphertext, as recommended by RFC 5116.
279
+ /// (NIST_KW doesn't have a separate tag.)
280
+ ///
281
+ /// # Arguments
282
+ ///
283
+ /// * `ad` - The additional data to authenticate.
284
+ /// * `plain` - The plaintext data to be encrypted and authenticated.
285
+ /// * `cipher_and_tag` - A mutable reference to a byte array where the ciphertext and authentication tag will be written.
286
+ /// * `tag_len` - The length of the tag to be generated.
287
+ ///
288
+ /// # Returns
289
+ ///
290
+ /// * `Result<usize>` - The length of the encrypted data on success.
291
+ ///
292
+ /// # Errors
293
+ ///
294
+ /// * `codes::CipherBadInputData` - For authenticated cipher mode plain_text length should be smaller than cipher length, except
295
+ /// AES KW and KWP cipher mode.
296
+ /// * Any other errors from underlying `mbedtls_cipher_auth_encrypt_ext` function.
276
297
pub fn encrypt_auth (
277
298
mut self ,
278
299
ad : & [ u8 ] ,
@@ -287,21 +308,58 @@ impl Cipher<Encryption, Authenticated, AdditionalData> {
287
308
) )
288
309
}
289
310
311
+ /// The authenticated encryption (AEAD/NIST_KW) function.
312
+ ///
313
+ /// For AEAD modes, the tag will be appended to the ciphertext, as recommended by RFC 5116.
314
+ /// (NIST_KW doesn't have a separate tag.)
315
+ ///
316
+ /// # Arguments
317
+ ///
318
+ /// * `ad` - The additional data to authenticate
319
+ /// * `data_with_tag` - The data to be encrypted and authenticated, along with space for the tag
320
+ /// * `tag_len` - The length of the tag to be generated
321
+ ///
322
+ /// # Returns
323
+ ///
324
+ /// * `Result<usize>` - The length of the encrypted data on success
325
+ ///
326
+ /// # Errors
327
+ ///
328
+ /// * `codes::CipherBadInputData` - If the size of `data_with_tag` minus `tag_len` is less than
329
+ /// or equal to zero
290
330
pub fn encrypt_auth_inplace (
291
331
mut self ,
292
332
ad : & [ u8 ] ,
293
- data : & mut [ u8 ] ,
294
- tag : & mut [ u8 ] ,
333
+ data_with_tag : & mut [ u8 ] ,
334
+ tag_len : usize ,
295
335
) -> Result < ( usize , Cipher < Encryption , Authenticated , Finished > ) > {
296
336
Ok ( (
297
337
self . raw_cipher
298
- . encrypt_auth_inplace ( ad, data , tag ) ?,
338
+ . encrypt_auth_inplace ( ad, data_with_tag , tag_len ) ?,
299
339
self . change_state ( ) ,
300
340
) )
301
341
}
302
342
}
303
343
304
344
impl Cipher < Decryption , Authenticated , AdditionalData > {
345
+ /// The authenticated decryption (AEAD/NIST_KW) function.
346
+ ///
347
+ /// # Arguments
348
+ ///
349
+ /// * `ad` - The additional data that was authenticated.
350
+ /// * `cipher_and_tag` - The ciphertext and authentication tag that were generated by the corresponding call to `encrypt_auth`.
351
+ /// * `plain_text` - A mutable reference to a byte array where the decrypted plaintext will be written.
352
+ /// * `tag_len` - The length of the tag.
353
+ ///
354
+ /// # Returns
355
+ ///
356
+ /// * `Result<usize>` - The length of the decrypted data on success.
357
+ ///
358
+ /// # Errors
359
+ ///
360
+ /// * `codes::CipherBadInputData` - For authenticated cipher mode plain_text length should be smaller than cipher length, except
361
+ /// AES KW and KWP cipher mode.
362
+ /// * Any other errors from underlying `mbedtls_cipher_auth_decrypt_ext` mbedtls function.
305
363
pub fn decrypt_auth (
306
364
mut self ,
307
365
ad : & [ u8 ] ,
@@ -316,15 +374,37 @@ impl Cipher<Decryption, Authenticated, AdditionalData> {
316
374
) )
317
375
}
318
376
377
+ /// The authenticated decryption (AEAD/NIST_KW) function.
378
+ ///
379
+ /// If the data is not authentic, then the output buffer is zeroed out to
380
+ /// prevent the unauthentic plaintext being used, making this interface safer.
381
+ ///
382
+ /// For AEAD modes, the tag must be appended to the ciphertext, as recommended by RFC 5116.
383
+ /// (NIST_KW doesn't have a separate tag.)
384
+ ///
385
+ /// # Arguments
386
+ ///
387
+ /// * `ad` - The additional data to authenticate
388
+ /// * `data_with_tag` - The data to be decrypted and authenticated, along with space for the tag
389
+ /// * `tag_len` - The length of the tag to be generated
390
+ ///
391
+ /// # Returns
392
+ ///
393
+ /// * `Result<usize>` - The length of the decrypted data on success
394
+ ///
395
+ /// # Errors
396
+ ///
397
+ /// * `codes::CipherBadInputData` - If the size of `data_with_tag` minus `tag_len` is less than
398
+ /// or equal to zero
319
399
pub fn decrypt_auth_inplace (
320
400
mut self ,
321
401
ad : & [ u8 ] ,
322
- data : & mut [ u8 ] ,
323
- tag : & [ u8 ] ,
402
+ data_with_tag : & mut [ u8 ] ,
403
+ tag_len : usize ,
324
404
) -> Result < ( usize , Cipher < Decryption , Authenticated , Finished > ) > {
325
405
Ok ( (
326
406
self . raw_cipher
327
- . decrypt_auth_inplace ( ad, data , tag ) ?,
407
+ . decrypt_auth_inplace ( ad, data_with_tag , tag_len ) ?,
328
408
self . change_state ( ) ,
329
409
) )
330
410
}
@@ -437,6 +517,7 @@ fn ccm_inplace() {
437
517
let iv = [ 0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 ] ;
438
518
let ad = [ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ] ;
439
519
let mut c = [ 0x20 , 0x21 , 0x22 , 0x23 , 0x0 , 0x0 , 0x0 , 0x0 ] ;
520
+ let tag_len: usize = 4 ;
440
521
let validate_cipher = [ 0x71 , 0x62 , 0x01 , 0x5b , 0x4d , 0xac , 0x25 , 0x5d ] ;
441
522
let validate_plain = [ 0x20 , 0x21 , 0x22 , 0x23 ] ;
442
523
@@ -447,9 +528,8 @@ fn ccm_inplace() {
447
528
)
448
529
. unwrap ( ) ;
449
530
let cipher = cipher. set_key_iv ( & k, & iv) . unwrap ( ) ;
450
- let ( data, tag) = c. split_at_mut ( 4 ) ;
451
531
cipher
452
- . encrypt_auth_inplace ( & ad, data , tag )
532
+ . encrypt_auth_inplace ( & ad, & mut c , tag_len )
453
533
. unwrap ( ) ;
454
534
assert_eq ! ( c, validate_cipher) ;
455
535
@@ -460,9 +540,8 @@ fn ccm_inplace() {
460
540
)
461
541
. unwrap ( ) ;
462
542
let cipher = cipher. set_key_iv ( & k, & iv) . unwrap ( ) ;
463
- let ( data, tag) = c. split_at_mut ( 4 ) ;
464
- cipher. decrypt_auth_inplace ( & ad, data, tag) . unwrap ( ) ;
465
- assert_eq ! ( validate_plain, data) ;
543
+ cipher. decrypt_auth_inplace ( & ad, & mut c, tag_len) . unwrap ( ) ;
544
+ assert_eq ! ( validate_plain, c[ ..c. len( ) - tag_len] ) ;
466
545
}
467
546
468
547
#[ test]
@@ -504,3 +583,41 @@ fn aes_kwp() {
504
583
let out_len = cipher. decrypt_auth ( & [ ] , & c, & mut p_out, 0 ) . unwrap ( ) . 0 ;
505
584
assert_eq ! ( p, & p_out[ ..out_len] ) ;
506
585
}
586
+
587
+ #[ test]
588
+ fn aes_gcm ( ) {
589
+ let k = [
590
+ 0x40 , 0x41 , 0x42 , 0x43 , 0x44 , 0x45 , 0x46 , 0x47 , 0x48 , 0x49 , 0x4a , 0x4b , 0x4c , 0x4d , 0x4e ,
591
+ 0x4f , 0x40 , 0x41 , 0x42 , 0x43 , 0x44 , 0x45 , 0x46 , 0x47 , 0x48 , 0x49 , 0x4a , 0x4b , 0x4c , 0x4d ,
592
+ 0x4e , 0x4f ,
593
+ ] ;
594
+ let iv = [ 0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 ] ;
595
+
596
+ let ad = [ 0x03 , 0x04 , 0x05 ] ;
597
+ let p = [ 0x20 , 0x21 , 0x22 , 0x23 ] ;
598
+ let c = [ 0x01 , 0x08 , 0x55 , 0x0f ] ;
599
+ let t = [ 0x3f , 0xd9 , 0x8e , 0x74 ] ;
600
+ let mut p_out = [ 0u8 ; 4 ] ;
601
+ let mut c_out = [ 0u8 ; 8 ] ;
602
+
603
+ let cipher = Cipher :: < Encryption , Authenticated , Fresh > :: new (
604
+ raw:: CipherId :: Aes ,
605
+ raw:: CipherMode :: GCM ,
606
+ ( k. len ( ) * 8 ) as _ ,
607
+ )
608
+ . unwrap ( ) ;
609
+ let cipher = cipher. set_key_iv ( & k, & iv) . unwrap ( ) ;
610
+
611
+ cipher. encrypt_auth ( & ad, & p, & mut c_out, 4 ) . unwrap ( ) ;
612
+ assert_eq ! ( c, c_out[ 0 ..4 ] ) ;
613
+ assert_eq ! ( t, c_out[ 4 ..8 ] ) ;
614
+ let cipher = Cipher :: < _ , Authenticated , _ > :: new (
615
+ raw:: CipherId :: Aes ,
616
+ raw:: CipherMode :: GCM ,
617
+ ( k. len ( ) * 8 ) as _ ,
618
+ )
619
+ . unwrap ( ) ;
620
+ let cipher = cipher. set_key_iv ( & k, & iv) . unwrap ( ) ;
621
+ cipher. decrypt_auth ( & ad, & c_out, & mut p_out, 4 ) . unwrap ( ) ;
622
+ assert_eq ! ( p, p_out) ;
623
+ }
0 commit comments