1 //! Counter Mode with a 32-bit little endian counter
2 
3 use cipher::{consts::U16, generic_array::GenericArray, NewCipher, StreamCipher};
4 use hex_literal::hex;
5 
6 type Aes128Ctr = ctr::Ctr32LE<aes::Aes128>;
7 
8 const KEY: &[u8; 16] = &hex!("000102030405060708090A0B0C0D0E0F");
9 const NONCE1: &[u8; 16] = &hex!("11111111111111111111111111111111");
10 const NONCE2: &[u8; 16] = &hex!("FEFFFFFF222222222222222222222222");
11 
12 /// Compute nonce as used by AES-GCM-SIV
nonce(bytes: &[u8; 16]) -> GenericArray<u8, U16>13 fn nonce(bytes: &[u8; 16]) -> GenericArray<u8, U16> {
14     let mut n = *bytes;
15     n[15] |= 0x80;
16     n.into()
17 }
18 
19 #[test]
counter_incr()20 fn counter_incr() {
21     let mut ctr = Aes128Ctr::new(KEY.into(), &nonce(NONCE1));
22     assert_eq!(ctr.current_block(), 0);
23 
24     let mut buffer = [0u8; 64];
25     ctr.apply_keystream(&mut buffer);
26 
27     // assert_eq!(ctr.current_ctr(), 4);
28     assert_eq!(
29         &buffer[..],
30         &hex!(
31             "2A0680B210CAD45E886D7EF6DAB357C9F18B39AFF6930FDB2D9FCE34261FF699
32              EB96774669D24B560C9AD028C5C39C4580775A82065256B4787DC91C6942B700"
33         )[..]
34     );
35 }
36 
37 #[test]
counter_seek()38 fn counter_seek() {
39     let mut ctr = Aes128Ctr::new(KEY.into(), &nonce(NONCE1));
40     ctr.seek_block(1);
41     assert_eq!(ctr.current_block(), 1);
42 
43     let mut buffer = [0u8; 64];
44     ctr.apply_keystream(&mut buffer);
45 
46     assert_eq!(ctr.current_block(), 5);
47     assert_eq!(
48         &buffer[..],
49         &hex!(
50             "F18B39AFF6930FDB2D9FCE34261FF699EB96774669D24B560C9AD028C5C39C45
51              80775A82065256B4787DC91C6942B7001564DDA1B07DCED9201AB71BAF06905B"
52         )[..]
53     );
54 }
55 
56 #[test]
keystream_xor()57 fn keystream_xor() {
58     let mut ctr = Aes128Ctr::new(KEY.into(), &nonce(NONCE1));
59     let mut buffer = [1u8; 64];
60 
61     ctr.apply_keystream(&mut buffer);
62     assert_eq!(
63         &buffer[..],
64         &hex!(
65             "2B0781B311CBD55F896C7FF7DBB256C8F08A38AEF7920EDA2C9ECF35271EF798
66              EA97764768D34A570D9BD129C4C29D4481765B83075357B5797CC81D6843B601"
67         )[..]
68     );
69 }
70 
71 #[test]
counter_wrap()72 fn counter_wrap() {
73     let mut ctr = Aes128Ctr::new(KEY.into(), &nonce(NONCE2));
74     assert_eq!(ctr.current_block(), 0);
75 
76     let mut buffer = [0u8; 64];
77     ctr.apply_keystream(&mut buffer);
78 
79     assert_eq!(ctr.current_block(), 4);
80     assert_eq!(
81         &buffer[..],
82         &hex!(
83             "A1E649D8B382293DC28375C42443BB6A226BAADC9E9CCA8214F56E07A4024E06
84              6355A0DA2E08FB00112FFA38C26189EE55DD5B0B130ED87096FE01B59A665A60"
85         )[..]
86     );
87 }
88