Skip to main content

bssl_crypto/cipher/
aes_ctr.rs

1/* Copyright 2023 The BoringSSL Authors
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 */
15
16use crate::cipher::{
17    Cipher, CipherError, CipherInitPurpose, EvpAes128Ctr, EvpAes256Ctr, StreamCipher,
18};
19
20/// AES-CTR-128 Cipher implementation.
21pub struct Aes128Ctr(Cipher<EvpAes128Ctr>);
22
23impl StreamCipher for Aes128Ctr {
24    type Key = [u8; 16];
25    type Nonce = [u8; 16];
26
27    /// Creates a new AES-128-CTR cipher instance from key material.
28    fn new(key: &Self::Key, nonce: &Self::Nonce) -> Self {
29        Self(Cipher::new(key, nonce, CipherInitPurpose::Encrypt))
30    }
31
32    /// Applies the keystream in-place, advancing the counter state appropriately.
33    fn apply_keystream(&mut self, buffer: &mut [u8]) -> Result<(), CipherError> {
34        self.0.apply_keystream_in_place(buffer)
35    }
36}
37
38/// AES-CTR-256 Cipher implementation.
39pub struct Aes256Ctr(Cipher<EvpAes256Ctr>);
40
41impl StreamCipher for Aes256Ctr {
42    type Key = [u8; 32];
43    type Nonce = [u8; 16];
44
45    /// Creates a new AES-256-CTR cipher instance from key material.
46    fn new(key: &Self::Key, nonce: &Self::Nonce) -> Self {
47        Self(Cipher::new(key, nonce, CipherInitPurpose::Encrypt))
48    }
49
50    /// Applies the keystream in-place, advancing the counter state appropriately.
51    fn apply_keystream(&mut self, buffer: &mut [u8]) -> Result<(), CipherError> {
52        self.0.apply_keystream_in_place(buffer)
53    }
54}
55
56#[cfg(test)]
57mod test {
58    use super::*;
59    use crate::test_helpers::decode_hex;
60
61    #[test]
62    fn aes_128_ctr_test_encrypt() {
63        // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.1
64        let iv = decode_hex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
65        let key = decode_hex("2b7e151628aed2a6abf7158809cf4f3c");
66
67        let mut cipher = Aes128Ctr::new(&key, &iv);
68        let mut block: [u8; 16];
69        block = decode_hex("6bc1bee22e409f96e93d7e117393172a");
70
71        cipher
72            .apply_keystream(&mut block)
73            .expect("Failed to apply keystream");
74
75        let expected_ciphertext_1 = decode_hex("874d6191b620e3261bef6864990db6ce");
76        assert_eq!(expected_ciphertext_1, block);
77
78        block = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51");
79        cipher
80            .apply_keystream(&mut block)
81            .expect("Failed to apply keystream");
82        let expected_ciphertext_2 = decode_hex("9806f66b7970fdff8617187bb9fffdff");
83        assert_eq!(expected_ciphertext_2, block);
84
85        block = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef");
86        cipher
87            .apply_keystream(&mut block)
88            .expect("Failed to apply keystream");
89        let expected_ciphertext_3 = decode_hex("5ae4df3edbd5d35e5b4f09020db03eab");
90        assert_eq!(expected_ciphertext_3, block);
91
92        block = decode_hex("f69f2445df4f9b17ad2b417be66c3710");
93        cipher
94            .apply_keystream(&mut block)
95            .expect("Failed to apply keystream");
96        let expected_ciphertext_3 = decode_hex("1e031dda2fbe03d1792170a0f3009cee");
97        assert_eq!(expected_ciphertext_3, block);
98    }
99
100    #[test]
101    fn aes_128_ctr_test_decrypt() {
102        // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.2
103        let key = decode_hex("2b7e151628aed2a6abf7158809cf4f3c");
104        let iv = decode_hex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
105        let mut cipher = Aes128Ctr::new(&key, &iv);
106
107        let mut block: [u8; 16];
108        block = decode_hex("874d6191b620e3261bef6864990db6ce");
109        cipher
110            .apply_keystream(&mut block)
111            .expect("Failed to apply keystream");
112        let expected_plaintext_1 = decode_hex("6bc1bee22e409f96e93d7e117393172a");
113        assert_eq!(expected_plaintext_1, block);
114
115        block = decode_hex("9806f66b7970fdff8617187bb9fffdff");
116        cipher
117            .apply_keystream(&mut block)
118            .expect("Failed to apply keystream");
119        let expected_plaintext_2 = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51");
120        assert_eq!(expected_plaintext_2, block);
121
122        block = decode_hex("5ae4df3edbd5d35e5b4f09020db03eab");
123        cipher
124            .apply_keystream(&mut block)
125            .expect("Failed to apply keystream");
126        let expected_plaintext_3 = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef");
127        assert_eq!(expected_plaintext_3, block);
128
129        block = decode_hex("1e031dda2fbe03d1792170a0f3009cee");
130        cipher
131            .apply_keystream(&mut block)
132            .expect("Failed to apply keystream");
133        let expected_plaintext_3 = decode_hex("f69f2445df4f9b17ad2b417be66c3710");
134        assert_eq!(expected_plaintext_3, block);
135    }
136
137    #[test]
138    pub fn aes_256_ctr_test_encrypt() {
139        // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.5
140        let key = decode_hex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
141        let iv = decode_hex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
142        let mut block: [u8; 16];
143        let mut cipher = Aes256Ctr::new(&key, &iv);
144
145        block = decode_hex("6bc1bee22e409f96e93d7e117393172a");
146        cipher
147            .apply_keystream(&mut block)
148            .expect("Failed to apply keystream");
149        let expected_ciphertext_1 = decode_hex("601ec313775789a5b7a7f504bbf3d228");
150        assert_eq!(expected_ciphertext_1, block);
151
152        block = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51");
153        cipher
154            .apply_keystream(&mut block)
155            .expect("Failed to apply keystream");
156        let expected_ciphertext_2 = decode_hex("f443e3ca4d62b59aca84e990cacaf5c5");
157        assert_eq!(expected_ciphertext_2, block);
158
159        block = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef");
160        cipher
161            .apply_keystream(&mut block)
162            .expect("Failed to apply keystream");
163        let expected_ciphertext_3 = decode_hex("2b0930daa23de94ce87017ba2d84988d");
164        assert_eq!(expected_ciphertext_3, block);
165
166        block = decode_hex("f69f2445df4f9b17ad2b417be66c3710");
167        cipher
168            .apply_keystream(&mut block)
169            .expect("Failed to apply keystream");
170        let expected_ciphertext_3 = decode_hex("dfc9c58db67aada613c2dd08457941a6");
171        assert_eq!(expected_ciphertext_3, block);
172    }
173
174    #[test]
175    fn aes_256_ctr_test_decrypt() {
176        // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.6
177        let key = decode_hex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
178        let iv = decode_hex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
179        let mut cipher = Aes256Ctr::new(&key, &iv);
180
181        let mut block: [u8; 16];
182        block = decode_hex("601ec313775789a5b7a7f504bbf3d228");
183        cipher
184            .apply_keystream(&mut block)
185            .expect("Failed to apply keystream");
186        let expected_plaintext_1 = decode_hex("6bc1bee22e409f96e93d7e117393172a");
187        assert_eq!(expected_plaintext_1, block);
188
189        block = decode_hex("f443e3ca4d62b59aca84e990cacaf5c5");
190        cipher
191            .apply_keystream(&mut block)
192            .expect("Failed to apply keystream");
193        let expected_plaintext_2 = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51");
194        assert_eq!(expected_plaintext_2, block);
195
196        block = decode_hex("2b0930daa23de94ce87017ba2d84988d");
197        cipher
198            .apply_keystream(&mut block)
199            .expect("Failed to apply keystream");
200        let expected_plaintext_3 = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef");
201        assert_eq!(expected_plaintext_3, block);
202
203        block = decode_hex("dfc9c58db67aada613c2dd08457941a6");
204        cipher
205            .apply_keystream(&mut block)
206            .expect("Failed to apply keystream");
207        let expected_plaintext_3 = decode_hex("f69f2445df4f9b17ad2b417be66c3710");
208        assert_eq!(expected_plaintext_3, block);
209    }
210}