Skip to main content

bssl_crypto/cipher/
aes_ctr.rs

1// Copyright 2023 The BoringSSL Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::cipher::{
16    Cipher, CipherError, CipherInitPurpose, EvpAes128Ctr, EvpAes256Ctr, StreamCipher,
17};
18
19/// AES-CTR-128 Cipher implementation.
20pub struct Aes128Ctr(Cipher<EvpAes128Ctr>);
21
22impl StreamCipher for Aes128Ctr {
23    type Key = [u8; 16];
24    type Nonce = [u8; 16];
25
26    /// Creates a new AES-128-CTR cipher instance from key material.
27    fn new(key: &Self::Key, nonce: &Self::Nonce) -> Self {
28        Self(Cipher::new(key, nonce, CipherInitPurpose::Encrypt))
29    }
30
31    /// Applies the keystream in-place, advancing the counter state appropriately.
32    fn apply_keystream(&mut self, buffer: &mut [u8]) -> Result<(), CipherError> {
33        self.0.apply_keystream_in_place(buffer)
34    }
35}
36
37/// AES-CTR-256 Cipher implementation.
38pub struct Aes256Ctr(Cipher<EvpAes256Ctr>);
39
40impl StreamCipher for Aes256Ctr {
41    type Key = [u8; 32];
42    type Nonce = [u8; 16];
43
44    /// Creates a new AES-256-CTR cipher instance from key material.
45    fn new(key: &Self::Key, nonce: &Self::Nonce) -> Self {
46        Self(Cipher::new(key, nonce, CipherInitPurpose::Encrypt))
47    }
48
49    /// Applies the keystream in-place, advancing the counter state appropriately.
50    fn apply_keystream(&mut self, buffer: &mut [u8]) -> Result<(), CipherError> {
51        self.0.apply_keystream_in_place(buffer)
52    }
53}
54
55#[cfg(test)]
56mod test {
57    use super::*;
58    use crate::test_helpers::decode_hex;
59
60    #[test]
61    fn aes_128_ctr_test_encrypt() {
62        // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.1
63        let iv = decode_hex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
64        let key = decode_hex("2b7e151628aed2a6abf7158809cf4f3c");
65
66        let mut cipher = Aes128Ctr::new(&key, &iv);
67        let mut block: [u8; 16];
68        block = decode_hex("6bc1bee22e409f96e93d7e117393172a");
69
70        cipher
71            .apply_keystream(&mut block)
72            .expect("Failed to apply keystream");
73
74        let expected_ciphertext_1 = decode_hex("874d6191b620e3261bef6864990db6ce");
75        assert_eq!(expected_ciphertext_1, block);
76
77        block = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51");
78        cipher
79            .apply_keystream(&mut block)
80            .expect("Failed to apply keystream");
81        let expected_ciphertext_2 = decode_hex("9806f66b7970fdff8617187bb9fffdff");
82        assert_eq!(expected_ciphertext_2, block);
83
84        block = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef");
85        cipher
86            .apply_keystream(&mut block)
87            .expect("Failed to apply keystream");
88        let expected_ciphertext_3 = decode_hex("5ae4df3edbd5d35e5b4f09020db03eab");
89        assert_eq!(expected_ciphertext_3, block);
90
91        block = decode_hex("f69f2445df4f9b17ad2b417be66c3710");
92        cipher
93            .apply_keystream(&mut block)
94            .expect("Failed to apply keystream");
95        let expected_ciphertext_3 = decode_hex("1e031dda2fbe03d1792170a0f3009cee");
96        assert_eq!(expected_ciphertext_3, block);
97    }
98
99    #[test]
100    fn aes_128_ctr_test_decrypt() {
101        // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.2
102        let key = decode_hex("2b7e151628aed2a6abf7158809cf4f3c");
103        let iv = decode_hex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
104        let mut cipher = Aes128Ctr::new(&key, &iv);
105
106        let mut block: [u8; 16];
107        block = decode_hex("874d6191b620e3261bef6864990db6ce");
108        cipher
109            .apply_keystream(&mut block)
110            .expect("Failed to apply keystream");
111        let expected_plaintext_1 = decode_hex("6bc1bee22e409f96e93d7e117393172a");
112        assert_eq!(expected_plaintext_1, block);
113
114        block = decode_hex("9806f66b7970fdff8617187bb9fffdff");
115        cipher
116            .apply_keystream(&mut block)
117            .expect("Failed to apply keystream");
118        let expected_plaintext_2 = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51");
119        assert_eq!(expected_plaintext_2, block);
120
121        block = decode_hex("5ae4df3edbd5d35e5b4f09020db03eab");
122        cipher
123            .apply_keystream(&mut block)
124            .expect("Failed to apply keystream");
125        let expected_plaintext_3 = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef");
126        assert_eq!(expected_plaintext_3, block);
127
128        block = decode_hex("1e031dda2fbe03d1792170a0f3009cee");
129        cipher
130            .apply_keystream(&mut block)
131            .expect("Failed to apply keystream");
132        let expected_plaintext_3 = decode_hex("f69f2445df4f9b17ad2b417be66c3710");
133        assert_eq!(expected_plaintext_3, block);
134    }
135
136    #[test]
137    pub fn aes_256_ctr_test_encrypt() {
138        // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.5
139        let key = decode_hex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
140        let iv = decode_hex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
141        let mut block: [u8; 16];
142        let mut cipher = Aes256Ctr::new(&key, &iv);
143
144        block = decode_hex("6bc1bee22e409f96e93d7e117393172a");
145        cipher
146            .apply_keystream(&mut block)
147            .expect("Failed to apply keystream");
148        let expected_ciphertext_1 = decode_hex("601ec313775789a5b7a7f504bbf3d228");
149        assert_eq!(expected_ciphertext_1, block);
150
151        block = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51");
152        cipher
153            .apply_keystream(&mut block)
154            .expect("Failed to apply keystream");
155        let expected_ciphertext_2 = decode_hex("f443e3ca4d62b59aca84e990cacaf5c5");
156        assert_eq!(expected_ciphertext_2, block);
157
158        block = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef");
159        cipher
160            .apply_keystream(&mut block)
161            .expect("Failed to apply keystream");
162        let expected_ciphertext_3 = decode_hex("2b0930daa23de94ce87017ba2d84988d");
163        assert_eq!(expected_ciphertext_3, block);
164
165        block = decode_hex("f69f2445df4f9b17ad2b417be66c3710");
166        cipher
167            .apply_keystream(&mut block)
168            .expect("Failed to apply keystream");
169        let expected_ciphertext_3 = decode_hex("dfc9c58db67aada613c2dd08457941a6");
170        assert_eq!(expected_ciphertext_3, block);
171    }
172
173    #[test]
174    fn aes_256_ctr_test_decrypt() {
175        // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.6
176        let key = decode_hex("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
177        let iv = decode_hex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
178        let mut cipher = Aes256Ctr::new(&key, &iv);
179
180        let mut block: [u8; 16];
181        block = decode_hex("601ec313775789a5b7a7f504bbf3d228");
182        cipher
183            .apply_keystream(&mut block)
184            .expect("Failed to apply keystream");
185        let expected_plaintext_1 = decode_hex("6bc1bee22e409f96e93d7e117393172a");
186        assert_eq!(expected_plaintext_1, block);
187
188        block = decode_hex("f443e3ca4d62b59aca84e990cacaf5c5");
189        cipher
190            .apply_keystream(&mut block)
191            .expect("Failed to apply keystream");
192        let expected_plaintext_2 = decode_hex("ae2d8a571e03ac9c9eb76fac45af8e51");
193        assert_eq!(expected_plaintext_2, block);
194
195        block = decode_hex("2b0930daa23de94ce87017ba2d84988d");
196        cipher
197            .apply_keystream(&mut block)
198            .expect("Failed to apply keystream");
199        let expected_plaintext_3 = decode_hex("30c81c46a35ce411e5fbc1191a0a52ef");
200        assert_eq!(expected_plaintext_3, block);
201
202        block = decode_hex("dfc9c58db67aada613c2dd08457941a6");
203        cipher
204            .apply_keystream(&mut block)
205            .expect("Failed to apply keystream");
206        let expected_plaintext_3 = decode_hex("f69f2445df4f9b17ad2b417be66c3710");
207        assert_eq!(expected_plaintext_3, block);
208    }
209}