1use crate::BlockCipher;
26
27pub mod chacha20_poly1305;
28pub mod eax;
29pub mod gcm_siv;
30pub mod ocb;
31pub mod poly1305;
32pub mod siv;
33pub use chacha20_poly1305::ChaCha20Poly1305;
34pub use eax::Eax;
35pub use gcm_siv::{Aes128GcmSiv, Aes256GcmSiv};
36pub use ocb::Ocb;
37pub use poly1305::Poly1305;
38pub use siv::Siv;
39
40#[inline]
41fn assert_block_multiple<C: BlockCipher>(buf: &[u8]) {
42 assert_eq!(
43 buf.len() % C::BLOCK_LEN,
44 0,
45 "buffer length must be a multiple of the block length"
46 );
47}
48
49#[inline]
50fn xor_in_place(dst: &mut [u8], src: &[u8]) {
51 for (d, s) in dst.iter_mut().zip(src.iter()) {
52 *d ^= *s;
53 }
54}
55
56#[inline]
57fn increment_be(counter: &mut [u8]) {
58 for b in counter.iter_mut().rev() {
62 let (next, carry) = b.overflowing_add(1);
63 *b = next;
64 if !carry {
65 break;
66 }
67 }
68}
69
70#[inline]
71fn rb_for(block_len: usize) -> u8 {
72 match block_len {
73 8 => 0x1b,
74 16 => 0x87,
75 _ => panic!("CMAC only supports 64-bit or 128-bit block ciphers"),
76 }
77}
78
79fn dbl(block: &[u8]) -> Vec<u8> {
80 let mut out = vec![0u8; block.len()];
84 let mut carry = 0u8;
85 for (o, &b) in out.iter_mut().rev().zip(block.iter().rev()) {
86 *o = (b << 1) | carry;
87 carry = b >> 7;
88 }
89 if carry != 0 {
90 let last = out.len() - 1;
91 out[last] ^= rb_for(block.len());
92 }
93 out
94}
95
96#[inline]
97fn assert_block_128<C: BlockCipher>() {
98 assert_eq!(
99 C::BLOCK_LEN,
100 16,
101 "this mode requires a 128-bit block cipher"
102 );
103}
104
105#[inline]
106fn xor_block16_in_place(dst: &mut [u8; 16], src: &[u8; 16]) {
107 for i in 0..16 {
108 dst[i] ^= src[i];
109 }
110}
111
112#[inline]
113fn increment_be32(counter: &mut [u8; 16]) {
114 for b in counter[12..].iter_mut().rev() {
117 let (next, carry) = b.overflowing_add(1);
118 *b = next;
119 if !carry {
120 break;
121 }
122 }
123}
124
125const GCM_MAX_COUNTER_BLOCKS: u64 = (u32::MAX as u64) - 1;
126const GCM_MAX_PAYLOAD_BYTES: u64 = GCM_MAX_COUNTER_BLOCKS * 16;
127
128#[inline]
129fn gcm_payload_len_allowed_u64(len_bytes: u64) -> bool {
130 len_bytes.saturating_add(15) / 16 <= GCM_MAX_COUNTER_BLOCKS
132}
133
134#[inline]
135fn gcm_payload_len_allowed(len_bytes: usize) -> bool {
136 gcm_payload_len_allowed_u64(u64::try_from(len_bytes).unwrap_or(u64::MAX))
137}
138
139#[inline]
140fn assert_gcm_payload_len(len_bytes: usize) {
141 assert!(
142 gcm_payload_len_allowed(len_bytes),
143 "GCM payload too large: max {} bytes per key/nonce",
144 GCM_MAX_PAYLOAD_BYTES
145 );
146}
147
148#[inline]
149fn gf_mul_x_xts(tweak: &mut [u8; 16]) {
150 let mut carry = 0u8;
155 for b in tweak.iter_mut() {
156 let next = *b >> 7;
157 *b = (*b << 1) | carry;
158 carry = next;
159 }
160 if carry != 0 {
161 tweak[0] ^= 0x87;
162 }
163}
164
165#[inline]
166fn xex_encrypt_block<C: BlockCipher>(cipher: &C, tweak: &[u8; 16], block: &mut [u8; 16]) {
167 xor_block16_in_place(block, tweak);
168 cipher.encrypt(block);
169 xor_block16_in_place(block, tweak);
170}
171
172#[inline]
173fn xex_decrypt_block<C: BlockCipher>(cipher: &C, tweak: &[u8; 16], block: &mut [u8; 16]) {
174 xor_block16_in_place(block, tweak);
175 cipher.decrypt(block);
176 xor_block16_in_place(block, tweak);
177}
178
179#[inline]
202fn ghash_mul_vt(x: u128, y: u128) -> u128 {
203 const R: u128 = 0xe100_0000_0000_0000_0000_0000_0000_0000;
207
208 let mut z = 0u128;
209 let mut v = y;
210 for i in 0..128 {
211 if ((x >> (127 - i)) & 1) != 0 {
212 z ^= v;
213 }
214 if (v & 1) == 0 {
215 v >>= 1;
216 } else {
217 v = (v >> 1) ^ R;
218 }
219 }
220 z
221}
222
223#[inline]
229fn ghash_mul_ct(x: u128, y: u128) -> u128 {
230 const R: u128 = 0xe100_0000_0000_0000_0000_0000_0000_0000;
233
234 let mut z = 0u128;
235 let mut v = y;
236 for i in 0..128 {
237 let bit = u8::try_from((x >> (127 - i)) & 1).expect("single bit fits in u8");
240 let bit_mask = 0u128.wrapping_sub(u128::from(bit));
241 z ^= v & bit_mask;
242
243 let lsb = u8::try_from(v & 1).expect("single bit fits in u8");
244 let lsb_mask = 0u128.wrapping_sub(u128::from(lsb));
245 v = (v >> 1) ^ (R & lsb_mask);
246 }
247 z
248}
249
250type GhashMulFn = fn(u128, u128) -> u128;
251
252fn ghash_update(y: &mut u128, h: u128, data: &[u8], mul: GhashMulFn) {
253 let mut block = [0u8; 16];
254 for chunk in data.chunks(16) {
255 block.fill(0);
256 block[..chunk.len()].copy_from_slice(chunk);
257 *y ^= u128::from_be_bytes(block);
258 *y = mul(*y, h);
259 }
260}
261
262fn ghash(h: u128, aad: &[u8], ciphertext: &[u8], mul: GhashMulFn) -> u128 {
263 let mut y = 0u128;
264 ghash_update(&mut y, h, aad, mul);
265 ghash_update(&mut y, h, ciphertext, mul);
266
267 let mut len_block = [0u8; 16];
268 len_block[..8].copy_from_slice(&((aad.len() as u64) << 3).to_be_bytes());
270 len_block[8..].copy_from_slice(&((ciphertext.len() as u64) << 3).to_be_bytes());
271 y ^= u128::from_be_bytes(len_block);
272 mul(y, h)
273}
274
275#[inline]
276fn ghash_iv(h: u128, iv: &[u8], mul: GhashMulFn) -> [u8; 16] {
277 if iv.len() == 12 {
279 let mut j0 = [0u8; 16];
280 j0[..12].copy_from_slice(iv);
281 j0[15] = 1;
282 return j0;
283 }
284 ghash(h, &[], iv, mul).to_be_bytes()
286}
287
288#[inline]
289fn gcm_hash_subkey<C: BlockCipher>(cipher: &C) -> u128 {
290 let mut h = [0u8; 16];
292 cipher.encrypt(&mut h);
293 u128::from_be_bytes(h)
294}
295
296#[inline]
297fn counter_keystream<C: BlockCipher>(cipher: &C, counter: &[u8; 16]) -> [u8; 16] {
298 let mut out = *counter;
299 cipher.encrypt(&mut out);
300 out
301}
302
303fn gcm_compute_tag<C: BlockCipher>(
304 cipher: &C,
305 nonce: &[u8],
306 aad: &[u8],
307 ciphertext: &[u8],
308 mul: GhashMulFn,
309) -> [u8; 16] {
310 assert_block_128::<C>();
311 assert_gcm_payload_len(ciphertext.len());
312 let h = gcm_hash_subkey(cipher);
313 let j0 = ghash_iv(h, nonce, mul);
314 let s = ghash(h, aad, ciphertext, mul);
315 let tag_mask = u128::from_be_bytes(counter_keystream(cipher, &j0));
316 (s ^ tag_mask).to_be_bytes()
317}
318
319fn gcm_compute_tag_with_h<C: BlockCipher>(
320 cipher: &C,
321 h: u128,
322 nonce: &[u8],
323 aad: &[u8],
324 ciphertext: &[u8],
325 mul: GhashMulFn,
326) -> [u8; 16] {
327 assert_gcm_payload_len(ciphertext.len());
328 let j0 = ghash_iv(h, nonce, mul);
329 let s = ghash(h, aad, ciphertext, mul);
330 let tag_mask = u128::from_be_bytes(counter_keystream(cipher, &j0));
331 (s ^ tag_mask).to_be_bytes()
332}
333
334#[inline]
335fn ccm_l_from_nonce(nonce: &[u8]) -> usize {
336 assert!(
337 (7..=13).contains(&nonce.len()),
338 "CCM nonce length must be in 7..=13 bytes"
339 );
340 15 - nonce.len()
341}
342
343#[inline]
344fn assert_ccm_tag_len(tag_len: usize) {
345 assert!(
346 (4..=16).contains(&tag_len) && tag_len.is_multiple_of(2),
347 "CCM tag length must be one of {{4,6,8,10,12,14,16}}"
348 );
349}
350
351#[inline]
352fn ccm_pack_len(block: &mut [u8; 16], l: usize, value: u64) {
353 let needed_bits = l * 8;
354 assert!(
355 needed_bits >= 64 || value < (1u64 << needed_bits),
356 "CCM length/counter does not fit in L bytes"
357 );
358 for i in 0..l {
359 block[15 - i] = u8::try_from((value >> (8 * i)) & 0xff).expect("single byte");
360 }
361}
362
363#[inline]
364fn ccm_b0(nonce: &[u8], msg_len: usize, aad_len: usize, tag_len: usize) -> [u8; 16] {
365 let l = ccm_l_from_nonce(nonce);
366 assert_ccm_tag_len(tag_len);
367 let msg_len_u64 = u64::try_from(msg_len).expect("message length fits u64");
368
369 let mut b0 = [0u8; 16];
370 let aad_flag = u8::from(aad_len != 0) << 6;
371 let t_field = u8::try_from((tag_len - 2) / 2).expect("CCM tag field fits u8") << 3;
372 let l_field = u8::try_from(l - 1).expect("CCM L field fits u8");
373 b0[0] = aad_flag | t_field | l_field;
374 b0[1..1 + nonce.len()].copy_from_slice(nonce);
375 ccm_pack_len(&mut b0, l, msg_len_u64);
376 b0
377}
378
379#[inline]
380fn ccm_counter_block(nonce: &[u8], counter: u64) -> [u8; 16] {
381 let l = ccm_l_from_nonce(nonce);
382 let mut ctr = [0u8; 16];
383 ctr[0] = u8::try_from(l - 1).expect("CCM L field fits u8");
384 ctr[1..1 + nonce.len()].copy_from_slice(nonce);
385 ccm_pack_len(&mut ctr, l, counter);
386 ctr
387}
388
389fn ccm_encode_aad(aad: &[u8]) -> Vec<u8> {
390 if aad.is_empty() {
391 return Vec::new();
392 }
393
394 let mut out = Vec::with_capacity(aad.len() + 16);
395 let aad_len = aad.len() as u64;
396 if aad_len < ((1u64 << 16) - (1u64 << 8)) {
397 out.extend_from_slice(
398 &u16::try_from(aad_len)
399 .expect("length range checked")
400 .to_be_bytes(),
401 );
402 } else if aad_len < (1u64 << 32) {
403 out.extend_from_slice(&[0xff, 0xfe]);
404 out.extend_from_slice(&(aad_len as u32).to_be_bytes());
405 } else {
406 out.extend_from_slice(&[0xff, 0xff]);
407 out.extend_from_slice(&aad_len.to_be_bytes());
408 }
409 out.extend_from_slice(aad);
410 if !out.len().is_multiple_of(16) {
411 out.resize(out.len().next_multiple_of(16), 0);
412 }
413 out
414}
415
416fn ccm_cbc_mac<C: BlockCipher>(
417 cipher: &C,
418 nonce: &[u8],
419 aad: &[u8],
420 plaintext: &[u8],
421 tag_len: usize,
422) -> [u8; 16] {
423 assert_block_128::<C>();
424 let mut y = [0u8; 16];
425
426 let b0 = ccm_b0(nonce, plaintext.len(), aad.len(), tag_len);
427 xor_block16_in_place(&mut y, &b0);
428 cipher.encrypt(&mut y);
429
430 let aad_encoded = ccm_encode_aad(aad);
431 for chunk in aad_encoded.chunks(16) {
432 let mut block = [0u8; 16];
433 block.copy_from_slice(chunk);
434 xor_block16_in_place(&mut y, &block);
435 cipher.encrypt(&mut y);
436 }
437
438 for chunk in plaintext.chunks(16) {
439 let mut block = [0u8; 16];
440 block[..chunk.len()].copy_from_slice(chunk);
441 xor_block16_in_place(&mut y, &block);
442 cipher.encrypt(&mut y);
443 }
444
445 y
446}
447
448fn ccm_apply_ctr<C: BlockCipher>(cipher: &C, nonce: &[u8], data: &mut [u8]) {
449 for (i, chunk) in data.chunks_mut(16).enumerate() {
450 let ctr = ccm_counter_block(nonce, u64::try_from(i + 1).expect("counter fits u64"));
451 let stream = counter_keystream(cipher, &ctr);
452 xor_in_place(chunk, &stream[..chunk.len()]);
453 }
454}
455
456const AES_KEY_WRAP_DEFAULT_IV: [u8; 8] = [0xA6; 8];
457
458#[inline]
459fn xor_aes_kw_t(a: &mut [u8; 8], t: u64) {
460 let t_be = t.to_be_bytes();
461 for i in 0..8 {
462 a[i] ^= t_be[i];
463 }
464}
465
466pub struct AesKeyWrap<C> {
471 cipher: C,
472}
473
474impl<C> AesKeyWrap<C> {
475 pub fn new(cipher: C) -> Self {
477 Self { cipher }
478 }
479
480 pub fn cipher(&self) -> &C {
482 &self.cipher
483 }
484}
485
486impl<C: BlockCipher> AesKeyWrap<C> {
487 pub fn wrap_key(&self, key_data: &[u8]) -> Option<Vec<u8>> {
492 self.wrap_key_with_iv(key_data, &AES_KEY_WRAP_DEFAULT_IV)
493 }
494
495 pub fn wrap_key_with_iv(&self, key_data: &[u8], iv: &[u8; 8]) -> Option<Vec<u8>> {
500 assert_block_128::<C>();
501 if !key_data.len().is_multiple_of(8) || key_data.len() < 16 {
502 return None;
503 }
504
505 let n = key_data.len() / 8;
506 let mut a = *iv;
507 let mut r = Vec::with_capacity(n);
508 for chunk in key_data.chunks_exact(8) {
509 let mut block = [0u8; 8];
510 block.copy_from_slice(chunk);
511 r.push(block);
512 }
513
514 for j in 0..6usize {
515 for (i, ri) in r.iter_mut().enumerate() {
516 let mut b = [0u8; 16];
517 b[..8].copy_from_slice(&a);
518 b[8..].copy_from_slice(ri);
519 self.cipher.encrypt(&mut b);
520
521 a.copy_from_slice(&b[..8]);
522 let t =
523 u64::try_from(j * n + i + 1).expect("AES-KW step index must fit in 64 bits");
524 xor_aes_kw_t(&mut a, t);
525 ri.copy_from_slice(&b[8..]);
526 }
527 }
528
529 let mut wrapped = Vec::with_capacity((n + 1) * 8);
530 wrapped.extend_from_slice(&a);
531 for ri in r {
532 wrapped.extend_from_slice(&ri);
533 }
534 Some(wrapped)
535 }
536
537 pub fn unwrap_key(&self, wrapped: &[u8]) -> Option<Vec<u8>> {
542 self.unwrap_key_with_iv(wrapped, &AES_KEY_WRAP_DEFAULT_IV)
543 }
544
545 pub fn unwrap_key_with_iv(&self, wrapped: &[u8], iv: &[u8; 8]) -> Option<Vec<u8>> {
550 assert_block_128::<C>();
551 if !wrapped.len().is_multiple_of(8) || wrapped.len() < 24 {
552 return None;
553 }
554
555 let n = (wrapped.len() / 8) - 1;
556 let mut a = [0u8; 8];
557 a.copy_from_slice(&wrapped[..8]);
558
559 let mut r = Vec::with_capacity(n);
560 for chunk in wrapped[8..].chunks_exact(8) {
561 let mut block = [0u8; 8];
562 block.copy_from_slice(chunk);
563 r.push(block);
564 }
565
566 for j in (0..6usize).rev() {
567 for i in (0..n).rev() {
568 let t =
569 u64::try_from(j * n + i + 1).expect("AES-KW step index must fit in 64 bits");
570 let mut a_xor_t = a;
571 xor_aes_kw_t(&mut a_xor_t, t);
572
573 let mut b = [0u8; 16];
574 b[..8].copy_from_slice(&a_xor_t);
575 b[8..].copy_from_slice(&r[i]);
576 self.cipher.decrypt(&mut b);
577
578 a.copy_from_slice(&b[..8]);
579 r[i].copy_from_slice(&b[8..]);
580 }
581 }
582
583 if crate::ct::constant_time_eq_mask(&a, iv) != u8::MAX {
584 return None;
585 }
586
587 let mut key_data = Vec::with_capacity(n * 8);
588 for ri in r {
589 key_data.extend_from_slice(&ri);
590 }
591 Some(key_data)
592 }
593}
594
595pub struct Ecb<C> {
601 cipher: C,
602}
603
604impl<C> Ecb<C> {
605 pub fn new(cipher: C) -> Self {
607 Self { cipher }
608 }
609
610 pub fn cipher(&self) -> &C {
612 &self.cipher
613 }
614}
615
616impl<C: BlockCipher> Ecb<C> {
617 pub fn encrypt_nopad(&self, data: &mut [u8]) {
619 assert_block_multiple::<C>(data);
620 for block in data.chunks_exact_mut(C::BLOCK_LEN) {
621 self.cipher.encrypt(block);
622 }
623 }
624
625 pub fn decrypt_nopad(&self, data: &mut [u8]) {
627 assert_block_multiple::<C>(data);
628 for block in data.chunks_exact_mut(C::BLOCK_LEN) {
629 self.cipher.decrypt(block);
630 }
631 }
632}
633
634pub struct Cbc<C> {
636 cipher: C,
637}
638
639impl<C> Cbc<C> {
640 pub fn new(cipher: C) -> Self {
642 Self { cipher }
643 }
644
645 pub fn cipher(&self) -> &C {
647 &self.cipher
648 }
649}
650
651impl<C: BlockCipher> Cbc<C> {
652 pub fn encrypt_nopad(&self, iv: &[u8], data: &mut [u8]) {
657 assert_eq!(iv.len(), C::BLOCK_LEN, "wrong IV length");
658 assert_block_multiple::<C>(data);
659
660 let mut prev = iv.to_vec();
661 for block in data.chunks_exact_mut(C::BLOCK_LEN) {
662 xor_in_place(block, &prev);
663 self.cipher.encrypt(block);
664 prev.copy_from_slice(block);
665 }
666 }
667
668 pub fn decrypt_nopad(&self, iv: &[u8], data: &mut [u8]) {
673 assert_eq!(iv.len(), C::BLOCK_LEN, "wrong IV length");
674 assert_block_multiple::<C>(data);
675
676 let mut prev = iv.to_vec();
677 let mut tmp = vec![0u8; C::BLOCK_LEN];
678
679 for block in data.chunks_exact_mut(C::BLOCK_LEN) {
680 tmp.copy_from_slice(block);
681 self.cipher.decrypt(block);
682 xor_in_place(block, &prev);
683 prev.copy_from_slice(&tmp);
684 }
685 }
686}
687
688pub struct Cfb<C> {
690 cipher: C,
691}
692
693impl<C> Cfb<C> {
694 pub fn new(cipher: C) -> Self {
696 Self { cipher }
697 }
698
699 pub fn cipher(&self) -> &C {
701 &self.cipher
702 }
703}
704
705impl<C: BlockCipher> Cfb<C> {
706 pub fn encrypt_nopad(&self, iv: &[u8], data: &mut [u8]) {
711 assert_eq!(iv.len(), C::BLOCK_LEN, "wrong IV length");
712 assert_block_multiple::<C>(data);
713
714 let mut feedback = iv.to_vec();
715 let mut keystream = feedback.clone();
716
717 for block in data.chunks_exact_mut(C::BLOCK_LEN) {
718 keystream.copy_from_slice(&feedback);
719 self.cipher.encrypt(&mut keystream);
720 xor_in_place(block, &keystream);
721 feedback.copy_from_slice(block);
722 }
723 }
724
725 pub fn decrypt_nopad(&self, iv: &[u8], data: &mut [u8]) {
730 assert_eq!(iv.len(), C::BLOCK_LEN, "wrong IV length");
731 assert_block_multiple::<C>(data);
732
733 let mut feedback = iv.to_vec();
734 let mut keystream = feedback.clone();
735 let mut tmp = vec![0u8; C::BLOCK_LEN];
736
737 for block in data.chunks_exact_mut(C::BLOCK_LEN) {
738 tmp.copy_from_slice(block);
739 keystream.copy_from_slice(&feedback);
740 self.cipher.encrypt(&mut keystream);
741 xor_in_place(block, &keystream);
742 feedback.copy_from_slice(&tmp);
743 }
744 }
745}
746
747pub struct Cfb8<C> {
749 cipher: C,
750}
751
752impl<C> Cfb8<C> {
753 pub fn new(cipher: C) -> Self {
755 Self { cipher }
756 }
757
758 pub fn cipher(&self) -> &C {
760 &self.cipher
761 }
762}
763
764impl<C: BlockCipher> Cfb8<C> {
765 pub fn encrypt(&self, iv: &[u8], data: &mut [u8]) {
769 assert_eq!(iv.len(), C::BLOCK_LEN, "wrong IV length");
770 let mut state = iv.to_vec();
771 let mut stream = vec![0u8; C::BLOCK_LEN];
772
773 for byte in data.iter_mut() {
774 stream.copy_from_slice(&state);
775 self.cipher.encrypt(&mut stream);
776 let ct = *byte ^ stream[0];
777 state.rotate_left(1);
778 state[C::BLOCK_LEN - 1] = ct;
779 *byte = ct;
780 }
781 }
782
783 pub fn decrypt(&self, iv: &[u8], data: &mut [u8]) {
787 assert_eq!(iv.len(), C::BLOCK_LEN, "wrong IV length");
788 let mut state = iv.to_vec();
789 let mut stream = vec![0u8; C::BLOCK_LEN];
790
791 for byte in data.iter_mut() {
792 let ct = *byte;
793 stream.copy_from_slice(&state);
794 self.cipher.encrypt(&mut stream);
795 *byte = ct ^ stream[0];
796 state.rotate_left(1);
797 state[C::BLOCK_LEN - 1] = ct;
798 }
799 }
800}
801
802pub struct Ofb<C> {
804 cipher: C,
805}
806
807impl<C> Ofb<C> {
808 pub fn new(cipher: C) -> Self {
810 Self { cipher }
811 }
812
813 pub fn cipher(&self) -> &C {
815 &self.cipher
816 }
817}
818
819impl<C: BlockCipher> Ofb<C> {
820 pub fn apply_keystream(&self, iv: &[u8], data: &mut [u8]) {
824 assert_eq!(iv.len(), C::BLOCK_LEN, "wrong IV length");
825
826 let mut feedback = iv.to_vec();
827 for chunk in data.chunks_mut(C::BLOCK_LEN) {
828 self.cipher.encrypt(&mut feedback);
829 xor_in_place(chunk, &feedback[..chunk.len()]);
830 }
831 }
832}
833
834pub struct Ctr<C> {
836 cipher: C,
837}
838
839impl<C> Ctr<C> {
840 pub fn new(cipher: C) -> Self {
842 Self { cipher }
843 }
844
845 pub fn cipher(&self) -> &C {
847 &self.cipher
848 }
849}
850
851impl<C: BlockCipher> Ctr<C> {
852 pub fn apply_keystream(&self, counter: &[u8], data: &mut [u8]) {
856 assert_eq!(counter.len(), C::BLOCK_LEN, "wrong counter length");
857
858 let mut ctr = counter.to_vec();
859 let mut stream = ctr.clone();
860
861 for chunk in data.chunks_mut(C::BLOCK_LEN) {
862 stream.copy_from_slice(&ctr);
863 self.cipher.encrypt(&mut stream);
864 xor_in_place(chunk, &stream[..chunk.len()]);
865 increment_be(&mut ctr);
866 }
867 }
868}
869
870pub struct Xts<C> {
875 data_cipher: C,
876 tweak_cipher: C,
877}
878
879impl<C> Xts<C> {
880 pub fn new(data_cipher: C, tweak_cipher: C) -> Self {
885 Self {
886 data_cipher,
887 tweak_cipher,
888 }
889 }
890
891 pub fn data_cipher(&self) -> &C {
893 &self.data_cipher
894 }
895
896 pub fn tweak_cipher(&self) -> &C {
898 &self.tweak_cipher
899 }
900}
901
902impl<C: BlockCipher> Xts<C> {
903 pub fn encrypt_sector(&self, tweak_value: &[u8; 16], data: &mut [u8]) {
908 assert_block_128::<C>();
909 assert!(
910 data.len() >= 16,
911 "XTS requires at least one complete block in each data unit"
912 );
913
914 let full_blocks = data.len() / 16;
915 let rem = data.len() % 16;
916
917 let mut tweak = *tweak_value;
918 self.tweak_cipher.encrypt(&mut tweak);
919
920 if rem == 0 {
921 for block in data.chunks_exact_mut(16) {
922 let mut tmp = [0u8; 16];
923 tmp.copy_from_slice(block);
924 xex_encrypt_block(&self.data_cipher, &tweak, &mut tmp);
925 block.copy_from_slice(&tmp);
926 gf_mul_x_xts(&mut tweak);
927 }
928 return;
929 }
930
931 for block in data[..(full_blocks - 1) * 16].chunks_exact_mut(16) {
932 let mut tmp = [0u8; 16];
933 tmp.copy_from_slice(block);
934 xex_encrypt_block(&self.data_cipher, &tweak, &mut tmp);
935 block.copy_from_slice(&tmp);
936 gf_mul_x_xts(&mut tweak);
937 }
938
939 let last_full_start = (full_blocks - 1) * 16;
940 let mut cc = [0u8; 16];
941 cc.copy_from_slice(&data[last_full_start..last_full_start + 16]);
942 xex_encrypt_block(&self.data_cipher, &tweak, &mut cc);
943
944 let mut pp = [0u8; 16];
945 pp[..rem].copy_from_slice(&data[last_full_start + 16..]);
946 pp[rem..].copy_from_slice(&cc[rem..]);
947 data[last_full_start + 16..].copy_from_slice(&cc[..rem]);
948
949 let mut next_tweak = tweak;
950 gf_mul_x_xts(&mut next_tweak);
951 xex_encrypt_block(&self.data_cipher, &next_tweak, &mut pp);
952 data[last_full_start..last_full_start + 16].copy_from_slice(&pp);
953 }
954
955 pub fn decrypt_sector(&self, tweak_value: &[u8; 16], data: &mut [u8]) {
960 assert_block_128::<C>();
961 assert!(
962 data.len() >= 16,
963 "XTS requires at least one complete block in each data unit"
964 );
965
966 let full_blocks = data.len() / 16;
967 let rem = data.len() % 16;
968
969 let mut tweak = *tweak_value;
970 self.tweak_cipher.encrypt(&mut tweak);
971
972 if rem == 0 {
973 for block in data.chunks_exact_mut(16) {
974 let mut tmp = [0u8; 16];
975 tmp.copy_from_slice(block);
976 xex_decrypt_block(&self.data_cipher, &tweak, &mut tmp);
977 block.copy_from_slice(&tmp);
978 gf_mul_x_xts(&mut tweak);
979 }
980 return;
981 }
982
983 for block in data[..(full_blocks - 1) * 16].chunks_exact_mut(16) {
984 let mut tmp = [0u8; 16];
985 tmp.copy_from_slice(block);
986 xex_decrypt_block(&self.data_cipher, &tweak, &mut tmp);
987 block.copy_from_slice(&tmp);
988 gf_mul_x_xts(&mut tweak);
989 }
990
991 let last_full_start = (full_blocks - 1) * 16;
992 let mut next_tweak = tweak;
993 gf_mul_x_xts(&mut next_tweak);
994
995 let mut pp = [0u8; 16];
996 pp.copy_from_slice(&data[last_full_start..last_full_start + 16]);
997 xex_decrypt_block(&self.data_cipher, &next_tweak, &mut pp);
998
999 let mut cc = [0u8; 16];
1000 cc[..rem].copy_from_slice(&data[last_full_start + 16..]);
1001 cc[rem..].copy_from_slice(&pp[rem..]);
1002
1003 let mut last_full = cc;
1004 xex_decrypt_block(&self.data_cipher, &tweak, &mut last_full);
1005
1006 data[last_full_start..last_full_start + 16].copy_from_slice(&last_full);
1007 data[last_full_start + 16..].copy_from_slice(&pp[..rem]);
1008 }
1009}
1010
1011pub struct Cmac<C> {
1013 cipher: C,
1014}
1015
1016impl<C> Cmac<C> {
1017 pub fn new(cipher: C) -> Self {
1019 Self { cipher }
1020 }
1021
1022 pub fn cipher(&self) -> &C {
1024 &self.cipher
1025 }
1026}
1027
1028pub struct Ccm<C, const TAG_LEN: usize = 16> {
1033 cipher: C,
1034}
1035
1036impl<C, const TAG_LEN: usize> Ccm<C, TAG_LEN> {
1037 pub fn new(cipher: C) -> Self {
1039 assert_ccm_tag_len(TAG_LEN);
1040 Self { cipher }
1041 }
1042
1043 pub fn cipher(&self) -> &C {
1045 &self.cipher
1046 }
1047
1048 pub fn tag_len(&self) -> usize {
1050 TAG_LEN
1051 }
1052}
1053
1054impl<C: BlockCipher, const TAG_LEN: usize> Ccm<C, TAG_LEN> {
1055 #[must_use]
1057 pub fn compute_tag(&self, nonce: &[u8], aad: &[u8], plaintext: &[u8]) -> [u8; TAG_LEN] {
1058 let t = ccm_cbc_mac(&self.cipher, nonce, aad, plaintext, TAG_LEN);
1059 let s0 = counter_keystream(&self.cipher, &ccm_counter_block(nonce, 0));
1060 let mut tag = [0u8; TAG_LEN];
1061 for i in 0..TAG_LEN {
1062 tag[i] = t[i] ^ s0[i];
1063 }
1064 tag
1065 }
1066
1067 #[must_use]
1069 pub fn encrypt(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> [u8; TAG_LEN] {
1070 assert_block_128::<C>();
1071 let tag = self.compute_tag(nonce, aad, data);
1072 ccm_apply_ctr(&self.cipher, nonce, data);
1073 tag
1074 }
1075
1076 pub fn decrypt(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &[u8; TAG_LEN]) -> bool {
1080 assert_block_128::<C>();
1081
1082 let mut plaintext = data.to_vec();
1085 ccm_apply_ctr(&self.cipher, nonce, &mut plaintext);
1086
1087 let expected = self.compute_tag(nonce, aad, &plaintext);
1088 if crate::ct::constant_time_eq_mask(&expected, tag) != u8::MAX {
1089 crate::ct::zeroize_slice(&mut plaintext);
1093 return false;
1094 }
1095
1096 data.copy_from_slice(&plaintext);
1097 true
1098 }
1099}
1100
1101pub struct Gcm<C> {
1128 cipher: C,
1129}
1130
1131pub struct GcmVt<C> {
1139 cipher: C,
1140}
1141
1142impl<C> Gcm<C> {
1143 pub fn new(cipher: C) -> Self {
1145 Self { cipher }
1146 }
1147
1148 pub fn cipher(&self) -> &C {
1150 &self.cipher
1151 }
1152}
1153
1154impl<C> GcmVt<C> {
1155 pub fn new(cipher: C) -> Self {
1157 Self { cipher }
1158 }
1159
1160 pub fn cipher(&self) -> &C {
1162 &self.cipher
1163 }
1164}
1165
1166impl<C: BlockCipher> Gcm<C> {
1167 #[must_use]
1172 pub fn compute_tag(&self, nonce: &[u8], aad: &[u8], ciphertext: &[u8]) -> [u8; 16] {
1173 gcm_compute_tag(&self.cipher, nonce, aad, ciphertext, ghash_mul_ct)
1174 }
1175
1176 #[must_use]
1181 pub fn encrypt(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> [u8; 16] {
1182 assert_block_128::<C>();
1183 assert_gcm_payload_len(data.len());
1184 let mut h = [0u8; 16];
1185 self.cipher.encrypt(&mut h);
1186 let h = u128::from_be_bytes(h);
1187 let j0 = ghash_iv(h, nonce, ghash_mul_ct);
1188 let mut counter = j0;
1189 increment_be32(&mut counter);
1190
1191 for chunk in data.chunks_mut(16) {
1192 let stream = counter_keystream(&self.cipher, &counter);
1193 xor_in_place(chunk, &stream[..chunk.len()]);
1194 increment_be32(&mut counter);
1195 }
1196
1197 let s = ghash(h, aad, data, ghash_mul_ct);
1198 let tag_mask = u128::from_be_bytes(counter_keystream(&self.cipher, &j0));
1199 (s ^ tag_mask).to_be_bytes()
1200 }
1201
1202 pub fn decrypt(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &[u8]) -> bool {
1209 assert_block_128::<C>();
1210 assert_gcm_payload_len(data.len());
1211 let h = gcm_hash_subkey(&self.cipher);
1212 let expected = gcm_compute_tag_with_h(&self.cipher, h, nonce, aad, data, ghash_mul_ct);
1213 if crate::ct::constant_time_eq_mask(&expected, tag) != u8::MAX {
1214 return false;
1215 }
1216 let j0 = ghash_iv(h, nonce, ghash_mul_ct);
1217 let mut counter = j0;
1218 increment_be32(&mut counter);
1219
1220 for chunk in data.chunks_mut(16) {
1221 let stream = counter_keystream(&self.cipher, &counter);
1222 xor_in_place(chunk, &stream[..chunk.len()]);
1223 increment_be32(&mut counter);
1224 }
1225
1226 true
1227 }
1228}
1229
1230impl<C: BlockCipher> GcmVt<C> {
1231 #[must_use]
1236 pub fn compute_tag(&self, nonce: &[u8], aad: &[u8], ciphertext: &[u8]) -> [u8; 16] {
1237 gcm_compute_tag(&self.cipher, nonce, aad, ciphertext, ghash_mul_vt)
1238 }
1239
1240 #[must_use]
1245 pub fn encrypt(&self, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> [u8; 16] {
1246 assert_block_128::<C>();
1247 assert_gcm_payload_len(data.len());
1248 let mut h = [0u8; 16];
1249 self.cipher.encrypt(&mut h);
1250 let h = u128::from_be_bytes(h);
1251 let j0 = ghash_iv(h, nonce, ghash_mul_vt);
1252 let mut counter = j0;
1253 increment_be32(&mut counter);
1254
1255 for chunk in data.chunks_mut(16) {
1256 let stream = counter_keystream(&self.cipher, &counter);
1257 xor_in_place(chunk, &stream[..chunk.len()]);
1258 increment_be32(&mut counter);
1259 }
1260
1261 let s = ghash(h, aad, data, ghash_mul_vt);
1262 let tag_mask = u128::from_be_bytes(counter_keystream(&self.cipher, &j0));
1263 (s ^ tag_mask).to_be_bytes()
1264 }
1265
1266 pub fn decrypt(&self, nonce: &[u8], aad: &[u8], data: &mut [u8], tag: &[u8]) -> bool {
1273 assert_block_128::<C>();
1274 assert_gcm_payload_len(data.len());
1275 let h = gcm_hash_subkey(&self.cipher);
1276 let expected = gcm_compute_tag_with_h(&self.cipher, h, nonce, aad, data, ghash_mul_vt);
1277 if crate::ct::constant_time_eq_mask(&expected, tag) != u8::MAX {
1278 return false;
1279 }
1280 let j0 = ghash_iv(h, nonce, ghash_mul_vt);
1281 let mut counter = j0;
1282 increment_be32(&mut counter);
1283
1284 for chunk in data.chunks_mut(16) {
1285 let stream = counter_keystream(&self.cipher, &counter);
1286 xor_in_place(chunk, &stream[..chunk.len()]);
1287 increment_be32(&mut counter);
1288 }
1289
1290 true
1291 }
1292}
1293
1294pub struct Gmac<C> {
1296 cipher: C,
1297}
1298
1299pub struct GmacVt<C> {
1304 cipher: C,
1305}
1306
1307impl<C> Gmac<C> {
1308 pub fn new(cipher: C) -> Self {
1310 Self { cipher }
1311 }
1312
1313 pub fn cipher(&self) -> &C {
1315 &self.cipher
1316 }
1317}
1318
1319impl<C> GmacVt<C> {
1320 pub fn new(cipher: C) -> Self {
1322 Self { cipher }
1323 }
1324
1325 pub fn cipher(&self) -> &C {
1327 &self.cipher
1328 }
1329}
1330
1331impl<C: BlockCipher> Gmac<C> {
1332 #[must_use]
1334 pub fn compute(&self, nonce: &[u8], aad: &[u8]) -> [u8; 16] {
1335 gcm_compute_tag(&self.cipher, nonce, aad, &[], ghash_mul_ct)
1336 }
1337
1338 pub fn verify(&self, nonce: &[u8], aad: &[u8], tag: &[u8]) -> bool {
1340 crate::ct::constant_time_eq_mask(&self.compute(nonce, aad), tag) == u8::MAX
1341 }
1342}
1343
1344impl<C: BlockCipher> GmacVt<C> {
1345 #[must_use]
1347 pub fn compute(&self, nonce: &[u8], aad: &[u8]) -> [u8; 16] {
1348 gcm_compute_tag(&self.cipher, nonce, aad, &[], ghash_mul_vt)
1349 }
1350
1351 pub fn verify(&self, nonce: &[u8], aad: &[u8], tag: &[u8]) -> bool {
1353 crate::ct::constant_time_eq_mask(&self.compute(nonce, aad), tag) == u8::MAX
1354 }
1355}
1356
1357impl<C: BlockCipher> Cmac<C> {
1358 pub fn compute(&self, data: &[u8]) -> Vec<u8> {
1360 let blk = C::BLOCK_LEN;
1361 let mut l = vec![0u8; blk];
1362 self.cipher.encrypt(&mut l);
1363 let k1 = dbl(&l);
1364 let k2 = dbl(&k1);
1365
1366 let n = if data.is_empty() {
1367 1
1368 } else {
1369 data.len().div_ceil(blk)
1370 };
1371 let last_complete = !data.is_empty() && data.len().is_multiple_of(blk);
1372
1373 let mut x = vec![0u8; blk];
1374 let mut y = vec![0u8; blk];
1375
1376 for block in data.chunks(blk).take(n.saturating_sub(1)) {
1377 y.copy_from_slice(&x);
1378 xor_in_place(&mut y, block);
1379 self.cipher.encrypt(&mut y);
1380 x.copy_from_slice(&y);
1381 }
1382
1383 let mut m_last = vec![0u8; blk];
1384 if last_complete {
1385 let start = (n - 1) * blk;
1386 m_last.copy_from_slice(&data[start..start + blk]);
1387 xor_in_place(&mut m_last, &k1);
1388 } else {
1389 let start = (n - 1) * blk;
1390 let rem = data.len().saturating_sub(start);
1391 if rem != 0 {
1392 m_last[..rem].copy_from_slice(&data[start..]);
1393 }
1394 m_last[rem] = 0x80;
1395 xor_in_place(&mut m_last, &k2);
1396 }
1397
1398 xor_in_place(&mut m_last, &x);
1399 self.cipher.encrypt(&mut m_last);
1400 m_last
1401 }
1402
1403 pub fn verify(&self, data: &[u8], tag: &[u8]) -> bool {
1405 crate::ct::constant_time_eq_mask(&self.compute(data), tag) == u8::MAX
1406 }
1407}
1408
1409#[cfg(test)]
1410mod tests {
1411 use super::*;
1412 use crate::{Aes128, Aes192, Aes256};
1413
1414 fn parse<const N: usize>(s: &str) -> [u8; N] {
1415 let mut out = [0u8; N];
1416 assert_eq!(s.len(), 2 * N);
1417 for i in 0..N {
1418 out[i] = u8::from_str_radix(&s[2 * i..2 * i + 2], 16).unwrap();
1419 }
1420 out
1421 }
1422
1423 fn parse_vec(s: &str) -> Vec<u8> {
1424 assert_eq!(s.len() % 2, 0);
1425 let mut out = Vec::with_capacity(s.len() / 2);
1426 let bytes = s.as_bytes();
1427 let mut i = 0usize;
1428 while i + 1 < bytes.len() {
1429 let hi =
1430 u8::from_str_radix(std::str::from_utf8(&bytes[i..i + 1]).unwrap(), 16).unwrap();
1431 let lo =
1432 u8::from_str_radix(std::str::from_utf8(&bytes[i + 1..i + 2]).unwrap(), 16).unwrap();
1433 out.push((hi << 4) | lo);
1434 i += 2;
1435 }
1436 out
1437 }
1438
1439 #[test]
1440 fn ecb_aes128_sp800_38a() {
1441 let key = parse::<16>("2b7e151628aed2a6abf7158809cf4f3c");
1442 let mut data = [
1443 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1444 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1445 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1446 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1447 ]
1448 .concat();
1449 let expected = [
1450 parse::<16>("3ad77bb40d7a3660a89ecaf32466ef97"),
1451 parse::<16>("f5d3d58503b9699de785895a96fdbaaf"),
1452 parse::<16>("43b1cd7f598ece23881b00e3ed030688"),
1453 parse::<16>("7b0c785e27e8ad3f8223207104725dd4"),
1454 ]
1455 .concat();
1456
1457 Ecb::new(Aes128::new(&key)).encrypt_nopad(&mut data);
1458 assert_eq!(data, expected);
1459 Ecb::new(Aes128::new(&key)).decrypt_nopad(&mut data);
1460 assert_eq!(
1461 data,
1462 [
1463 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1464 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1465 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1466 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1467 ]
1468 .concat()
1469 );
1470 }
1471
1472 #[test]
1473 fn ecb_aes256_sp800_38a() {
1474 let key = parse::<32>("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
1476 let mut data = [
1477 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1478 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1479 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1480 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1481 ]
1482 .concat();
1483 let expected = [
1484 parse::<16>("f3eed1bdb5d2a03c064b5a7e3db181f8"),
1485 parse::<16>("591ccb10d410ed26dc5ba74a31362870"),
1486 parse::<16>("b6ed21b99ca6f4f9f153e7b1beafed1d"),
1487 parse::<16>("23304b7a39f9f3ff067d8d8f9e24ecc7"),
1488 ]
1489 .concat();
1490
1491 Ecb::new(Aes256::new(&key)).encrypt_nopad(&mut data);
1492 assert_eq!(data, expected);
1493 Ecb::new(Aes256::new(&key)).decrypt_nopad(&mut data);
1494 assert_eq!(
1495 data,
1496 [
1497 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1498 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1499 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1500 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1501 ]
1502 .concat()
1503 );
1504 }
1505
1506 #[test]
1507 fn cbc_aes128_sp800_38a() {
1508 let key = parse::<16>("2b7e151628aed2a6abf7158809cf4f3c");
1509 let iv = parse::<16>("000102030405060708090a0b0c0d0e0f");
1510 let mut data = [
1511 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1512 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1513 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1514 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1515 ]
1516 .concat();
1517 let expected = [
1518 parse::<16>("7649abac8119b246cee98e9b12e9197d"),
1519 parse::<16>("5086cb9b507219ee95db113a917678b2"),
1520 parse::<16>("73bed6b8e3c1743b7116e69e22229516"),
1521 parse::<16>("3ff1caa1681fac09120eca307586e1a7"),
1522 ]
1523 .concat();
1524
1525 let mode = Cbc::new(Aes128::new(&key));
1526 mode.encrypt_nopad(&iv, &mut data);
1527 assert_eq!(data, expected);
1528 mode.decrypt_nopad(&iv, &mut data);
1529 assert_eq!(
1530 data,
1531 [
1532 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1533 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1534 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1535 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1536 ]
1537 .concat()
1538 );
1539 }
1540
1541 #[test]
1542 fn cbc_aes256_sp800_38a() {
1543 let key = parse::<32>("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
1545 let iv = parse::<16>("000102030405060708090a0b0c0d0e0f");
1546 let mut data = [
1547 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1548 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1549 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1550 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1551 ]
1552 .concat();
1553 let expected = [
1554 parse::<16>("f58c4c04d6e5f1ba779eabfb5f7bfbd6"),
1555 parse::<16>("9cfc4e967edb808d679f777bc6702c7d"),
1556 parse::<16>("39f23369a9d9bacfa530e26304231461"),
1557 parse::<16>("b2eb05e2c39be9fcda6c19078c6a9d1b"),
1558 ]
1559 .concat();
1560
1561 let mode = Cbc::new(Aes256::new(&key));
1562 mode.encrypt_nopad(&iv, &mut data);
1563 assert_eq!(data, expected);
1564 mode.decrypt_nopad(&iv, &mut data);
1565 assert_eq!(
1566 data,
1567 [
1568 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1569 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1570 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1571 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1572 ]
1573 .concat()
1574 );
1575 }
1576
1577 #[test]
1578 fn cfb_aes128_sp800_38a() {
1579 let key = parse::<16>("2b7e151628aed2a6abf7158809cf4f3c");
1580 let iv = parse::<16>("000102030405060708090a0b0c0d0e0f");
1581 let mut data = [
1582 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1583 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1584 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1585 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1586 ]
1587 .concat();
1588 let expected = [
1589 parse::<16>("3b3fd92eb72dad20333449f8e83cfb4a"),
1590 parse::<16>("c8a64537a0b3a93fcde3cdad9f1ce58b"),
1591 parse::<16>("26751f67a3cbb140b1808cf187a4f4df"),
1592 parse::<16>("c04b05357c5d1c0eeac4c66f9ff7f2e6"),
1593 ]
1594 .concat();
1595
1596 let mode = Cfb::new(Aes128::new(&key));
1597 mode.encrypt_nopad(&iv, &mut data);
1598 assert_eq!(data, expected);
1599 mode.decrypt_nopad(&iv, &mut data);
1600 assert_eq!(
1601 data,
1602 [
1603 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1604 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1605 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1606 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1607 ]
1608 .concat()
1609 );
1610 }
1611
1612 #[test]
1613 fn cfb_aes256_sp800_38a() {
1614 let key = parse::<32>("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
1616 let iv = parse::<16>("000102030405060708090a0b0c0d0e0f");
1617 let mut data = [
1618 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1619 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1620 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1621 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1622 ]
1623 .concat();
1624 let expected = [
1625 parse::<16>("dc7e84bfda79164b7ecd8486985d3860"),
1626 parse::<16>("39ffed143b28b1c832113c6331e5407b"),
1627 parse::<16>("df10132415e54b92a13ed0a8267ae2f9"),
1628 parse::<16>("75a385741ab9cef82031623d55b1e471"),
1629 ]
1630 .concat();
1631
1632 let mode = Cfb::new(Aes256::new(&key));
1633 mode.encrypt_nopad(&iv, &mut data);
1634 assert_eq!(data, expected);
1635 mode.decrypt_nopad(&iv, &mut data);
1636 assert_eq!(
1637 data,
1638 [
1639 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1640 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1641 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1642 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1643 ]
1644 .concat()
1645 );
1646 }
1647
1648 #[test]
1649 fn cfb8_aes128_roundtrip() {
1650 let key = parse::<16>("2b7e151628aed2a6abf7158809cf4f3c");
1651 let iv = parse::<16>("000102030405060708090a0b0c0d0e0f");
1652 let plaintext = *b"cfb8 mode roundtrip check";
1653 let mut data = plaintext;
1654
1655 let mode = Cfb8::new(Aes128::new(&key));
1656 mode.encrypt(&iv, &mut data);
1657 assert_ne!(data, plaintext);
1658 mode.decrypt(&iv, &mut data);
1659 assert_eq!(data, plaintext);
1660 }
1661
1662 #[test]
1663 fn cfb8_aes128_sp800_38a_prefix_vector() {
1664 let key = parse::<16>("2b7e151628aed2a6abf7158809cf4f3c");
1666 let iv = parse::<16>("000102030405060708090a0b0c0d0e0f");
1667 let mut data = parse_vec("6bc1bee22e409f96e93d7e117393172aae2d");
1668 let expected = parse_vec("3b79424c9c0dd436bace9e0ed4586a4f32b9");
1669
1670 let mode = Cfb8::new(Aes128::new(&key));
1671 mode.encrypt(&iv, &mut data);
1672 assert_eq!(data, expected);
1673 mode.decrypt(&iv, &mut data);
1674 assert_eq!(data, parse_vec("6bc1bee22e409f96e93d7e117393172aae2d"));
1675 }
1676
1677 #[test]
1678 fn ofb_aes128_sp800_38a() {
1679 let key = parse::<16>("2b7e151628aed2a6abf7158809cf4f3c");
1680 let iv = parse::<16>("000102030405060708090a0b0c0d0e0f");
1681 let mut data = [
1682 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1683 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1684 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1685 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1686 ]
1687 .concat();
1688 let expected = [
1689 parse::<16>("3b3fd92eb72dad20333449f8e83cfb4a"),
1690 parse::<16>("7789508d16918f03f53c52dac54ed825"),
1691 parse::<16>("9740051e9c5fecf64344f7a82260edcc"),
1692 parse::<16>("304c6528f659c77866a510d9c1d6ae5e"),
1693 ]
1694 .concat();
1695
1696 let mode = Ofb::new(Aes128::new(&key));
1697 mode.apply_keystream(&iv, &mut data);
1698 assert_eq!(data, expected);
1699 mode.apply_keystream(&iv, &mut data);
1700 assert_eq!(
1701 data,
1702 [
1703 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1704 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1705 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1706 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1707 ]
1708 .concat()
1709 );
1710 }
1711
1712 #[test]
1713 fn ofb_aes256_sp800_38a() {
1714 let key = parse::<32>("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
1716 let iv = parse::<16>("000102030405060708090a0b0c0d0e0f");
1717 let mut data = [
1718 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1719 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1720 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1721 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1722 ]
1723 .concat();
1724 let expected = [
1725 parse::<16>("dc7e84bfda79164b7ecd8486985d3860"),
1726 parse::<16>("4febdc6740d20b3ac88f6ad82a4fb08d"),
1727 parse::<16>("71ab47a086e86eedf39d1c5bba97c408"),
1728 parse::<16>("0126141d67f37be8538f5a8be740e484"),
1729 ]
1730 .concat();
1731
1732 let mode = Ofb::new(Aes256::new(&key));
1733 mode.apply_keystream(&iv, &mut data);
1734 assert_eq!(data, expected);
1735 mode.apply_keystream(&iv, &mut data);
1736 assert_eq!(
1737 data,
1738 [
1739 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1740 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1741 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1742 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1743 ]
1744 .concat()
1745 );
1746 }
1747
1748 #[test]
1749 fn ctr_aes128_sp800_38a() {
1750 let key = parse::<16>("2b7e151628aed2a6abf7158809cf4f3c");
1751 let ctr = parse::<16>("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
1752 let mut data = [
1753 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1754 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1755 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1756 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1757 ]
1758 .concat();
1759 let expected = [
1760 parse::<16>("874d6191b620e3261bef6864990db6ce"),
1761 parse::<16>("9806f66b7970fdff8617187bb9fffdff"),
1762 parse::<16>("5ae4df3edbd5d35e5b4f09020db03eab"),
1763 parse::<16>("1e031dda2fbe03d1792170a0f3009cee"),
1764 ]
1765 .concat();
1766
1767 let mode = Ctr::new(Aes128::new(&key));
1768 mode.apply_keystream(&ctr, &mut data);
1769 assert_eq!(data, expected);
1770 mode.apply_keystream(&ctr, &mut data);
1771 assert_eq!(
1772 data,
1773 [
1774 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1775 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1776 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1777 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1778 ]
1779 .concat()
1780 );
1781 }
1782
1783 #[test]
1784 fn ctr_aes256_sp800_38a() {
1785 let key = parse::<32>("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
1787 let ctr = parse::<16>("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
1788 let mut data = [
1789 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1790 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1791 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1792 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1793 ]
1794 .concat();
1795 let expected = [
1796 parse::<16>("601ec313775789a5b7a7f504bbf3d228"),
1797 parse::<16>("f443e3ca4d62b59aca84e990cacaf5c5"),
1798 parse::<16>("2b0930daa23de94ce87017ba2d84988d"),
1799 parse::<16>("dfc9c58db67aada613c2dd08457941a6"),
1800 ]
1801 .concat();
1802
1803 let mode = Ctr::new(Aes256::new(&key));
1804 mode.apply_keystream(&ctr, &mut data);
1805 assert_eq!(data, expected);
1806 mode.apply_keystream(&ctr, &mut data);
1807 assert_eq!(
1808 data,
1809 [
1810 parse::<16>("6bc1bee22e409f96e93d7e117393172a"),
1811 parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"),
1812 parse::<16>("30c81c46a35ce411e5fbc1191a0a52ef"),
1813 parse::<16>("f69f2445df4f9b17ad2b417be66c3710"),
1814 ]
1815 .concat()
1816 );
1817 }
1818
1819 #[test]
1820 fn cmac_aes128_sp800_38b() {
1821 let key = parse::<16>("2b7e151628aed2a6abf7158809cf4f3c");
1822 let mode = Cmac::new(Aes128::new(&key));
1823
1824 assert_eq!(
1825 mode.compute(&[]),
1826 parse::<16>("bb1d6929e95937287fa37d129b756746").to_vec()
1827 );
1828 assert_eq!(
1829 mode.compute(&parse::<16>("6bc1bee22e409f96e93d7e117393172a")),
1830 parse::<16>("070a16b46b4d4144f79bdd9dd04a287c").to_vec()
1831 );
1832 let mut msg = Vec::with_capacity(40);
1833 msg.extend_from_slice(&parse::<16>("6bc1bee22e409f96e93d7e117393172a"));
1834 msg.extend_from_slice(&parse::<16>("ae2d8a571e03ac9c9eb76fac45af8e51"));
1835 msg.extend_from_slice(&parse::<8>("30c81c46a35ce411"));
1836 assert_eq!(
1837 mode.compute(&msg),
1838 parse::<16>("dfa66747de9ae63030ca32611497c827").to_vec()
1839 );
1840 assert!(mode.verify(&msg, &parse::<16>("dfa66747de9ae63030ca32611497c827")));
1841 }
1842
1843 #[test]
1844 fn xts_aes128_two_block_matches_openssl() {
1845 let key1 = parse::<16>("000102030405060708090a0b0c0d0e0f");
1846 let key2 = parse::<16>("101112131415161718191a1b1c1d1e1f");
1847 let tweak = [0u8; 16];
1848 let mut data =
1849 parse::<32>("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
1850 let expected =
1851 parse::<32>("74a109aabf1937c022d19da4b96cbc40b8ddc9c0653a7fb0dc8425c7ef276dea");
1852
1853 let mode = Xts::new(Aes128::new(&key1), Aes128::new(&key2));
1854 mode.encrypt_sector(&tweak, &mut data);
1855 assert_eq!(data, expected);
1856 mode.decrypt_sector(&tweak, &mut data);
1857 assert_eq!(
1858 data,
1859 parse::<32>("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
1860 );
1861 }
1862
1863 #[test]
1864 fn xts_aes128_ciphertext_stealing_matches_openssl() {
1865 let key1 = parse::<16>("000102030405060708090a0b0c0d0e0f");
1866 let key2 = parse::<16>("101112131415161718191a1b1c1d1e1f");
1867 let tweak = [0u8; 16];
1868 let mut data =
1869 parse::<31>("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e");
1870 let expected =
1871 parse::<31>("03ab02ee0037b6327b1110429d562a8674a109aabf1937c022d19da4b96cbc");
1872
1873 let mode = Xts::new(Aes128::new(&key1), Aes128::new(&key2));
1874 mode.encrypt_sector(&tweak, &mut data);
1875 assert_eq!(data, expected);
1876 mode.decrypt_sector(&tweak, &mut data);
1877 assert_eq!(
1878 data,
1879 parse::<31>("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e")
1880 );
1881 }
1882
1883 #[test]
1884 fn xts_aes128_runtime_cross_check_with_openssl() {
1885 let key1 = parse::<16>("000102030405060708090a0b0c0d0e0f");
1886 let key2 = parse::<16>("101112131415161718191a1b1c1d1e1f");
1887 let tweak = [0u8; 16];
1888 let plaintext =
1889 parse::<31>("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e");
1890
1891 let Some(expected) = crate::test_utils::run_openssl(
1892 &[
1893 "enc",
1894 "-aes-128-xts",
1895 "-e",
1896 "-nopad",
1897 "-K",
1898 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
1899 "-iv",
1900 "00000000000000000000000000000000",
1901 ],
1902 &plaintext,
1903 ) else {
1904 return;
1905 };
1906
1907 let mut data = plaintext;
1908 let mode = Xts::new(Aes128::new(&key1), Aes128::new(&key2));
1909 mode.encrypt_sector(&tweak, &mut data);
1910 assert_eq!(data.as_slice(), expected.as_slice());
1911 }
1912
1913 #[test]
1914 fn xts_aes128_nist_cavp_vector() {
1915 let key1 = parse::<16>("a1b90cba3f06ac353b2c343876081762");
1918 let key2 = parse::<16>("090923026e91771815f29dab01932f2f");
1919 let tweak = parse::<16>("4faef7117cda59c66e4b92013e768ad5");
1920 let mut data = parse::<16>("ebabce95b14d3c8d6fb350390790311c");
1921 let expected = parse::<16>("778ae8b43cb98d5a825081d5be471c63");
1922
1923 let mode = Xts::new(Aes128::new(&key1), Aes128::new(&key2));
1924 mode.encrypt_sector(&tweak, &mut data);
1925 assert_eq!(data, expected);
1926 mode.decrypt_sector(&tweak, &mut data);
1927 assert_eq!(data, parse::<16>("ebabce95b14d3c8d6fb350390790311c"));
1928 }
1929
1930 #[test]
1931 fn ctr_des_roundtrip_generic() {
1932 let key = parse::<8>("133457799bbcdff1");
1933 let counter = parse::<8>("0123456789abcdef");
1934 let original = *b"generic DES mode path!";
1935 let mut data = original;
1936
1937 let mode = Ctr::new(crate::Des::new(&key).expect("non-weak DES test key"));
1938 mode.apply_keystream(&counter, &mut data);
1939 assert_ne!(data, original);
1940 mode.apply_keystream(&counter, &mut data);
1941 assert_eq!(data, original);
1942 }
1943
1944 #[test]
1945 fn gcm_aes128_empty_plaintext_nist() {
1946 let key = [0u8; 16];
1947 let iv = [0u8; 12];
1948 let mut data = Vec::new();
1949 let mode = Gcm::new(Aes128::new(&key));
1950
1951 let tag = mode.encrypt(&iv, &[], &mut data);
1952 assert_eq!(data, Vec::<u8>::new());
1953 assert_eq!(tag, parse::<16>("58e2fccefa7e3061367f1d57a4e7455a"));
1954 assert!(mode.decrypt(&iv, &[], &mut data, &tag));
1955 }
1956
1957 #[test]
1958 fn gcm_aes128_single_block_nist() {
1959 let key = [0u8; 16];
1960 let iv = [0u8; 12];
1961 let mut data = [0u8; 16];
1962 let expected_ct = parse::<16>("0388dace60b6a392f328c2b971b2fe78");
1963 let expected_tag = parse::<16>("ab6e47d42cec13bdf53a67b21257bddf");
1964 let mode = Gcm::new(Aes128::new(&key));
1965
1966 let tag = mode.encrypt(&iv, &[], &mut data);
1967 assert_eq!(data, expected_ct);
1968 assert_eq!(tag, expected_tag);
1969 assert!(mode.decrypt(&iv, &[], &mut data, &tag));
1970 assert_eq!(data, [0u8; 16]);
1971 }
1972
1973 #[test]
1974 fn gcm_aes128_with_aad_nist() {
1975 let key = parse::<16>("feffe9928665731c6d6a8f9467308308");
1976 let iv = parse::<12>("cafebabefacedbaddecaf888");
1977 let aad = parse::<20>("feedfacedeadbeeffeedfacedeadbeefabaddad2");
1978 let mut data = parse::<64>(
1979 "d9313225f88406e5a55909c5aff5269a\
1980 86a7a9531534f7da2e4c303d8a318a72\
1981 1c3c0c95956809532fcf0e2449a6b525\
1982 b16aedf5aa0de657ba637b391aafd255",
1983 );
1984 let expected_ct = parse::<64>(
1985 "42831ec2217774244b7221b784d0d49c\
1986 e3aa212f2c02a4e035c17e2329aca12e\
1987 21d514b25466931c7d8f6a5aac84aa05\
1988 1ba30b396a0aac973d58e091473f5985",
1989 );
1990 let expected_tag = parse::<16>("da80ce830cfda02da2a218a1744f4c76");
1991 let mode = Gcm::new(Aes128::new(&key));
1992
1993 let tag = mode.encrypt(&iv, &aad, &mut data);
1994 assert_eq!(data, expected_ct);
1995 assert_eq!(tag, expected_tag);
1996 assert!(mode.decrypt(&iv, &aad, &mut data, &tag));
1997 assert_eq!(
1998 data,
1999 parse::<64>(
2000 "d9313225f88406e5a55909c5aff5269a\
2001 86a7a9531534f7da2e4c303d8a318a72\
2002 1c3c0c95956809532fcf0e2449a6b525\
2003 b16aedf5aa0de657ba637b391aafd255",
2004 )
2005 );
2006 }
2007
2008 #[test]
2009 fn gcm_aes256_single_block_cavp() {
2010 let key = parse::<32>("31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22");
2013 let iv = parse::<12>("0d18e06c7c725ac9e362e1ce");
2014 let mut data = parse::<16>("2db5168e932556f8089a0622981d017d");
2015 let expected_ct = parse::<16>("fa4362189661d163fcd6a56d8bf0405a");
2016 let expected_tag = parse::<16>("d636ac1bbedd5cc3ee727dc2ab4a9489");
2017
2018 let mode = Gcm::new(Aes256::new(&key));
2019 let tag = mode.encrypt(&iv, &[], &mut data);
2020 assert_eq!(data, expected_ct);
2021 assert_eq!(tag, expected_tag);
2022 assert!(mode.decrypt(&iv, &[], &mut data, &tag));
2023 assert_eq!(data, parse::<16>("2db5168e932556f8089a0622981d017d"));
2024 }
2025
2026 #[test]
2027 fn gcm_aes256_non_96bit_iv_auth_only_cavp() {
2028 let key = parse::<32>("c639f716597a86afd12319199e21a62b1fc0277a70e3ca120bd3ff745be88604");
2031 let iv = parse::<1>("29");
2032 let aad = parse::<16>("20fda1db6911d160121dc3c48e5f19b2");
2033 let mut data: [u8; 0] = [];
2034 let expected_tag = parse::<16>("221a3398f20d0d9fe913f33a6cd413d3");
2035
2036 let mode = Gcm::new(Aes256::new(&key));
2037 let tag = mode.encrypt(&iv, &aad, &mut data);
2038 assert_eq!(tag, expected_tag);
2039 assert!(mode.decrypt(&iv, &aad, &mut data, &tag));
2040 }
2041
2042 #[test]
2043 fn gcm_rejects_wrong_tag_without_decrypting() {
2044 let key = [0u8; 16];
2045 let iv = [0u8; 12];
2046 let mut data = [0u8; 16];
2047 let mode = Gcm::new(Aes128::new(&key));
2048 let tag = mode.encrypt(&iv, &[], &mut data);
2049 let mut bad_tag = tag;
2050 bad_tag[0] ^= 1;
2051 let ciphertext = data;
2052
2053 assert!(!mode.decrypt(&iv, &[], &mut data, &bad_tag));
2054 assert_eq!(data, ciphertext);
2055 }
2056
2057 #[test]
2058 fn gcm_ct_and_vt_backends_match() {
2059 let key = parse::<16>("feffe9928665731c6d6a8f9467308308");
2060 let iv = parse::<12>("cafebabefacedbaddecaf888");
2061 let aad = parse::<20>("feedfacedeadbeeffeedfacedeadbeefabaddad2");
2062 let plaintext = parse::<64>(
2063 "d9313225f88406e5a55909c5aff5269a\
2064 86a7a9531534f7da2e4c303d8a318a72\
2065 1c3c0c95956809532fcf0e2449a6b525\
2066 b16aedf5aa0de657ba637b391aafd255",
2067 );
2068
2069 let gcm_ct = Gcm::new(Aes128::new(&key));
2070 let gcm_vt = GcmVt::new(Aes128::new(&key));
2071
2072 let mut ct_data = plaintext;
2073 let mut vt_data = plaintext;
2074 let ct_tag = gcm_ct.encrypt(&iv, &aad, &mut ct_data);
2075 let vt_tag = gcm_vt.encrypt(&iv, &aad, &mut vt_data);
2076
2077 assert_eq!(ct_data, vt_data);
2078 assert_eq!(ct_tag, vt_tag);
2079 assert!(gcm_ct.decrypt(&iv, &aad, &mut ct_data, &ct_tag));
2080 assert!(gcm_vt.decrypt(&iv, &aad, &mut vt_data, &vt_tag));
2081 assert_eq!(ct_data, plaintext);
2082 assert_eq!(vt_data, plaintext);
2083 }
2084
2085 #[test]
2086 fn gcm_payload_limit_matches_sp800_38d_bound() {
2087 assert!(gcm_payload_len_allowed_u64(0));
2088 assert!(gcm_payload_len_allowed_u64(1));
2089 assert!(gcm_payload_len_allowed_u64(16));
2090 assert!(gcm_payload_len_allowed_u64(GCM_MAX_PAYLOAD_BYTES));
2091 assert!(!gcm_payload_len_allowed_u64(GCM_MAX_PAYLOAD_BYTES + 1));
2092 }
2093
2094 #[test]
2095 fn gmac_matches_gcm_on_empty_plaintext() {
2096 let key = parse::<16>("feffe9928665731c6d6a8f9467308308");
2097 let iv = parse::<12>("cafebabefacedbaddecaf888");
2098 let aad = parse::<20>("feedfacedeadbeeffeedfacedeadbeefabaddad2");
2099
2100 let gcm = Gcm::new(Aes128::new(&key));
2101 let gmac = Gmac::new(Aes128::new(&key));
2102 let tag = gmac.compute(&iv, &aad);
2103
2104 assert_eq!(tag, gcm.compute_tag(&iv, &aad, &[]));
2105 assert!(gmac.verify(&iv, &aad, &tag));
2106 }
2107
2108 #[test]
2109 fn gmac_ct_and_vt_backends_match() {
2110 let key = parse::<16>("feffe9928665731c6d6a8f9467308308");
2111 let iv = parse::<12>("cafebabefacedbaddecaf888");
2112 let aad = parse::<20>("feedfacedeadbeeffeedfacedeadbeefabaddad2");
2113
2114 let gmac_ct = Gmac::new(Aes128::new(&key));
2115 let gmac_vt = GmacVt::new(Aes128::new(&key));
2116
2117 let tag_ct = gmac_ct.compute(&iv, &aad);
2118 let tag_vt = gmac_vt.compute(&iv, &aad);
2119
2120 assert_eq!(tag_ct, tag_vt);
2121 assert!(gmac_ct.verify(&iv, &aad, &tag_ct));
2122 assert!(gmac_vt.verify(&iv, &aad, &tag_vt));
2123 }
2124
2125 #[test]
2126 fn ccm_aes128_rfc3610_packet_vector_1() {
2127 let key = parse::<16>("c0c1c2c3c4c5c6c7c8c9cacbcccdcecf");
2129 let nonce = parse::<13>("00000003020100a0a1a2a3a4a5");
2130 let aad = parse::<8>("0001020304050607");
2131 let mut msg = parse::<23>("08090a0b0c0d0e0f101112131415161718191a1b1c1d1e");
2132 let expected_ct = parse::<23>("588c979a61c663d2f066d0c2c0f989806d5f6b61dac384");
2133 let expected_tag = parse::<8>("17e8d12cfdf926e0");
2134
2135 let mode = Ccm::<_, 8>::new(Aes128::new(&key));
2136 let tag = mode.encrypt(&nonce, &aad, &mut msg);
2137 assert_eq!(msg, expected_ct);
2138 assert_eq!(tag, expected_tag);
2139
2140 assert!(mode.decrypt(&nonce, &aad, &mut msg, &tag));
2141 assert_eq!(
2142 msg,
2143 parse::<23>("08090a0b0c0d0e0f101112131415161718191a1b1c1d1e")
2144 );
2145 }
2146
2147 #[test]
2148 fn ccm_aes128_rfc3610_packet_vector_2() {
2149 let key = parse::<16>("c0c1c2c3c4c5c6c7c8c9cacbcccdcecf");
2151 let nonce = parse::<13>("00000004030201a0a1a2a3a4a5");
2152 let aad = parse::<8>("0001020304050607");
2153 let mut msg = parse::<24>("08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
2154 let expected_ct = parse::<24>("72c91a36e135f8cf291ca894085c87e3cc15c439c9e43a3b");
2155 let expected_tag = parse::<8>("a091d56e10400916");
2156
2157 let mode = Ccm::<_, 8>::new(Aes128::new(&key));
2158 let tag = mode.encrypt(&nonce, &aad, &mut msg);
2159 assert_eq!(msg, expected_ct);
2160 assert_eq!(tag, expected_tag);
2161
2162 assert!(mode.decrypt(&nonce, &aad, &mut msg, &tag));
2163 assert_eq!(
2164 msg,
2165 parse::<24>("08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
2166 );
2167 }
2168
2169 #[test]
2170 fn ccm_tag_mismatch_rejected() {
2171 let key = [0x11u8; 16];
2172 let nonce = [0x22u8; 13];
2173 let aad = b"header";
2174 let mode = Ccm::<_, 12>::new(Aes128::new(&key));
2175 let mut data = *b"ccm plaintext data";
2176 let tag = mode.encrypt(&nonce, aad, &mut data);
2177 let ciphertext = data;
2178
2179 let mut bad_tag = tag;
2180 bad_tag[0] ^= 0x80;
2181 assert!(!mode.decrypt(&nonce, aad, &mut data, &bad_tag));
2182 assert_eq!(data, ciphertext);
2183
2184 assert!(mode.decrypt(&nonce, aad, &mut data, &tag));
2185 assert_eq!(data, *b"ccm plaintext data");
2186 }
2187
2188 #[test]
2189 fn ccm_aes128_cavp_tlen_4_vector() {
2190 let key = parse::<16>("43b1a6bc8d0d22d6d1ca95c18593cca5");
2192 let nonce = parse::<13>("9882578e750b9682c6ca7f8f86");
2193 let aad = parse::<32>("2084f3861c9ad0ccee7c63a7e05aece5db8b34bd8724cc06b4ca99a7f9c4914f");
2194 let mut msg = parse::<24>("a2b381c7d1545c408fe29817a21dc435a154c87256346b05");
2195 let expected_ct = parse::<24>("cc69ed76985e0ed4c8365a72775e5a19bfccc71aeb116c85");
2196 let expected_tag = parse::<4>("a8c74677");
2197
2198 let mode = Ccm::<_, 4>::new(Aes128::new(&key));
2199 let tag = mode.encrypt(&nonce, &aad, &mut msg);
2200 assert_eq!(msg, expected_ct);
2201 assert_eq!(tag, expected_tag);
2202 assert!(mode.decrypt(&nonce, &aad, &mut msg, &tag));
2203 assert_eq!(
2204 msg,
2205 parse::<24>("a2b381c7d1545c408fe29817a21dc435a154c87256346b05")
2206 );
2207 }
2208
2209 #[test]
2210 fn ccm_aes128_cavp_tlen_16_vector() {
2211 let key = parse::<16>("4189351b5caea375a0299e81c621bf43");
2213 let nonce = parse::<13>("48c0906930561e0ab0ef4cd972");
2214 let aad = parse::<32>("40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951");
2215 let mut msg = parse::<24>("4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef");
2216 let expected_ct = parse::<24>("26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6");
2217 let expected_tag = parse::<16>("d80e8bf80f4a46cab06d4313f0db9be9");
2218
2219 let mode = Ccm::<_, 16>::new(Aes128::new(&key));
2220 let tag = mode.encrypt(&nonce, &aad, &mut msg);
2221 assert_eq!(msg, expected_ct);
2222 assert_eq!(tag, expected_tag);
2223 assert!(mode.decrypt(&nonce, &aad, &mut msg, &tag));
2224 assert_eq!(
2225 msg,
2226 parse::<24>("4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef")
2227 );
2228 }
2229
2230 #[test]
2231 fn aes_key_wrap_rfc3394_4_1() {
2232 let kek = parse::<16>("000102030405060708090A0B0C0D0E0F");
2233 let key_data = parse::<16>("00112233445566778899AABBCCDDEEFF");
2234 let expected = parse::<24>("1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5");
2235 let kw = AesKeyWrap::new(Aes128::new(&kek));
2236
2237 assert_eq!(kw.wrap_key(&key_data), Some(expected.to_vec()));
2238 assert_eq!(kw.unwrap_key(&expected), Some(key_data.to_vec()));
2239 }
2240
2241 #[test]
2242 fn aes_key_wrap_rfc3394_4_2() {
2243 let kek = parse::<24>("000102030405060708090A0B0C0D0E0F1011121314151617");
2244 let key_data = parse::<16>("00112233445566778899AABBCCDDEEFF");
2245 let expected = parse::<24>("96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D");
2246 let kw = AesKeyWrap::new(Aes192::new(&kek));
2247
2248 assert_eq!(kw.wrap_key(&key_data), Some(expected.to_vec()));
2249 assert_eq!(kw.unwrap_key(&expected), Some(key_data.to_vec()));
2250 }
2251
2252 #[test]
2253 fn aes_key_wrap_rfc3394_4_3() {
2254 let kek = parse::<32>("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
2255 let key_data = parse::<16>("00112233445566778899AABBCCDDEEFF");
2256 let expected = parse::<24>("64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7");
2257 let kw = AesKeyWrap::new(Aes256::new(&kek));
2258
2259 assert_eq!(kw.wrap_key(&key_data), Some(expected.to_vec()));
2260 assert_eq!(kw.unwrap_key(&expected), Some(key_data.to_vec()));
2261 }
2262
2263 #[test]
2264 fn aes_key_wrap_rfc3394_4_4() {
2265 let kek = parse::<24>("000102030405060708090A0B0C0D0E0F1011121314151617");
2266 let key_data = parse::<24>("00112233445566778899AABBCCDDEEFF0001020304050607");
2267 let expected =
2268 parse::<32>("031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2");
2269 let kw = AesKeyWrap::new(Aes192::new(&kek));
2270
2271 assert_eq!(kw.wrap_key(&key_data), Some(expected.to_vec()));
2272 assert_eq!(kw.unwrap_key(&expected), Some(key_data.to_vec()));
2273 }
2274
2275 #[test]
2276 fn aes_key_wrap_rfc3394_4_5() {
2277 let kek = parse::<32>("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
2278 let key_data = parse::<24>("00112233445566778899AABBCCDDEEFF0001020304050607");
2279 let expected =
2280 parse::<32>("A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1");
2281 let kw = AesKeyWrap::new(Aes256::new(&kek));
2282
2283 assert_eq!(kw.wrap_key(&key_data), Some(expected.to_vec()));
2284 assert_eq!(kw.unwrap_key(&expected), Some(key_data.to_vec()));
2285 }
2286
2287 #[test]
2288 fn aes_key_wrap_rfc3394_4_6() {
2289 let kek = parse::<32>("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
2290 let key_data =
2291 parse::<32>("00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F");
2292 let expected = parse::<40>(
2293 "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21",
2294 );
2295 let kw = AesKeyWrap::new(Aes256::new(&kek));
2296
2297 assert_eq!(kw.wrap_key(&key_data), Some(expected.to_vec()));
2298 assert_eq!(kw.unwrap_key(&expected), Some(key_data.to_vec()));
2299 }
2300
2301 #[test]
2302 fn aes_key_wrap_rejects_bad_lengths_and_tampering() {
2303 let kw = AesKeyWrap::new(Aes128::new(&[0u8; 16]));
2304
2305 assert!(kw.wrap_key(&[]).is_none());
2306 assert!(kw.wrap_key(&[0u8; 8]).is_none());
2307 assert!(kw.wrap_key(&[0u8; 15]).is_none());
2308 assert!(kw.unwrap_key(&[]).is_none());
2309 assert!(kw.unwrap_key(&[0u8; 16]).is_none());
2310
2311 let mut wrapped = kw.wrap_key(&[0u8; 16]).expect("wrap");
2312 wrapped[0] ^= 1;
2313 assert!(kw.unwrap_key(&wrapped).is_none());
2314 }
2315}