• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 Google LLC
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 //      http://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 
15 //! Traits for AES-CTR.
16 use super::AesKey;
17 
18 /// An implementation of AES-CTR.
19 ///
20 /// An AesCtr impl must only be used for encryption _or_ decryption, not both. Since CTR mode
21 /// is stateful, mixing encrypts and decrypts may advance the internal state in unexpected ways.
22 /// Create separate encrypt/decrypt instances if both operations are needed.
23 pub trait AesCtr {
24     /// The [AesKey] this cipher uses. See [super::Aes128Key] and [super::Aes256Key] for the common AES-128 and
25     /// AES-256 cases.
26     type Key: AesKey;
27 
28     /// Build a `Self` from key material.
new(key: &Self::Key, iv: [u8; 16]) -> Self29     fn new(key: &Self::Key, iv: [u8; 16]) -> Self;
30 
31     /// Encrypt the data in place, advancing the counter state appropriately.
encrypt(&mut self, data: &mut [u8])32     fn encrypt(&mut self, data: &mut [u8]);
33     /// Decrypt the data in place, advancing the counter state appropriately.
decrypt(&mut self, data: &mut [u8])34     fn decrypt(&mut self, data: &mut [u8]);
35 }
36 
37 /// Module for testing implementations of this crate.
38 #[cfg(feature = "testing")]
39 pub mod testing {
40     use super::AesCtr;
41     use crate::aes::{Aes128Key, Aes256Key};
42     pub use crate::testing::prelude;
43     use core::marker;
44     use hex_literal::hex;
45     use rstest_reuse::template;
46 
47     /// Test AES-128-CTR encryption
aes_128_ctr_test_encrypt<A: AesCtr<Key = Aes128Key>>(_marker: marker::PhantomData<A>)48     pub fn aes_128_ctr_test_encrypt<A: AesCtr<Key = Aes128Key>>(_marker: marker::PhantomData<A>) {
49         // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.1
50         let key: Aes128Key = hex!("2b7e151628aed2a6abf7158809cf4f3c").into();
51         let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
52         let mut block: [u8; 16];
53         let mut cipher = A::new(&key, iv);
54 
55         block = hex!("6bc1bee22e409f96e93d7e117393172a");
56         cipher.encrypt(&mut block);
57         let expected_ciphertext_1 = hex!("874d6191b620e3261bef6864990db6ce");
58         assert_eq!(expected_ciphertext_1, block);
59 
60         block = hex!("ae2d8a571e03ac9c9eb76fac45af8e51");
61         cipher.encrypt(&mut block);
62         let expected_ciphertext_2 = hex!("9806f66b7970fdff8617187bb9fffdff");
63         assert_eq!(expected_ciphertext_2, block);
64 
65         block = hex!("30c81c46a35ce411e5fbc1191a0a52ef");
66         cipher.encrypt(&mut block);
67         let expected_ciphertext_3 = hex!("5ae4df3edbd5d35e5b4f09020db03eab");
68         assert_eq!(expected_ciphertext_3, block);
69 
70         block = hex!("f69f2445df4f9b17ad2b417be66c3710");
71         cipher.encrypt(&mut block);
72         let expected_ciphertext_3 = hex!("1e031dda2fbe03d1792170a0f3009cee");
73         assert_eq!(expected_ciphertext_3, block);
74     }
75 
76     /// Test AES-128-CTR decryption
aes_128_ctr_test_decrypt<A: AesCtr<Key = Aes128Key>>(_marker: marker::PhantomData<A>)77     pub fn aes_128_ctr_test_decrypt<A: AesCtr<Key = Aes128Key>>(_marker: marker::PhantomData<A>) {
78         // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.2
79         let key: Aes128Key = hex!("2b7e151628aed2a6abf7158809cf4f3c").into();
80         let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
81         let mut block: [u8; 16];
82         let mut cipher = A::new(&key, iv);
83 
84         block = hex!("874d6191b620e3261bef6864990db6ce");
85         cipher.encrypt(&mut block);
86         let expected_plaintext_1 = hex!("6bc1bee22e409f96e93d7e117393172a");
87         assert_eq!(expected_plaintext_1, block);
88 
89         block = hex!("9806f66b7970fdff8617187bb9fffdff");
90         cipher.encrypt(&mut block);
91         let expected_plaintext_2 = hex!("ae2d8a571e03ac9c9eb76fac45af8e51");
92         assert_eq!(expected_plaintext_2, block);
93 
94         block = hex!("5ae4df3edbd5d35e5b4f09020db03eab");
95         cipher.encrypt(&mut block);
96         let expected_plaintext_3 = hex!("30c81c46a35ce411e5fbc1191a0a52ef");
97         assert_eq!(expected_plaintext_3, block);
98 
99         block = hex!("1e031dda2fbe03d1792170a0f3009cee");
100         cipher.encrypt(&mut block);
101         let expected_plaintext_3 = hex!("f69f2445df4f9b17ad2b417be66c3710");
102         assert_eq!(expected_plaintext_3, block);
103     }
104 
105     /// Test AES-256-CTR encryption
aes_256_ctr_test_encrypt<A: AesCtr<Key = Aes256Key>>(_marker: marker::PhantomData<A>)106     pub fn aes_256_ctr_test_encrypt<A: AesCtr<Key = Aes256Key>>(_marker: marker::PhantomData<A>) {
107         // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.5
108         let key: Aes256Key =
109             hex!("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").into();
110         let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
111         let mut block: [u8; 16];
112         let mut cipher = A::new(&key, iv);
113 
114         block = hex!("6bc1bee22e409f96e93d7e117393172a");
115         cipher.encrypt(&mut block);
116         let expected_ciphertext_1 = hex!("601ec313775789a5b7a7f504bbf3d228");
117         assert_eq!(expected_ciphertext_1, block);
118 
119         block = hex!("ae2d8a571e03ac9c9eb76fac45af8e51");
120         cipher.encrypt(&mut block);
121         let expected_ciphertext_2 = hex!("f443e3ca4d62b59aca84e990cacaf5c5");
122         assert_eq!(expected_ciphertext_2, block);
123 
124         block = hex!("30c81c46a35ce411e5fbc1191a0a52ef");
125         cipher.encrypt(&mut block);
126         let expected_ciphertext_3 = hex!("2b0930daa23de94ce87017ba2d84988d");
127         assert_eq!(expected_ciphertext_3, block);
128 
129         block = hex!("f69f2445df4f9b17ad2b417be66c3710");
130         cipher.encrypt(&mut block);
131         let expected_ciphertext_3 = hex!("dfc9c58db67aada613c2dd08457941a6");
132         assert_eq!(expected_ciphertext_3, block);
133     }
134 
135     /// Test AES-256-CTR decryption
aes_256_ctr_test_decrypt<A: AesCtr<Key = Aes256Key>>(_marker: marker::PhantomData<A>)136     pub fn aes_256_ctr_test_decrypt<A: AesCtr<Key = Aes256Key>>(_marker: marker::PhantomData<A>) {
137         // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.5.6
138         let key: Aes256Key =
139             hex!("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").into();
140         let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
141         let mut block: [u8; 16];
142         let mut cipher = A::new(&key, iv);
143 
144         block = hex!("601ec313775789a5b7a7f504bbf3d228");
145         cipher.encrypt(&mut block);
146         let expected_plaintext_1 = hex!("6bc1bee22e409f96e93d7e117393172a");
147         assert_eq!(expected_plaintext_1, block);
148 
149         block = hex!("f443e3ca4d62b59aca84e990cacaf5c5");
150         cipher.encrypt(&mut block);
151         let expected_plaintext_2 = hex!("ae2d8a571e03ac9c9eb76fac45af8e51");
152         assert_eq!(expected_plaintext_2, block);
153 
154         block = hex!("2b0930daa23de94ce87017ba2d84988d");
155         cipher.encrypt(&mut block);
156         let expected_plaintext_3 = hex!("30c81c46a35ce411e5fbc1191a0a52ef");
157         assert_eq!(expected_plaintext_3, block);
158 
159         block = hex!("dfc9c58db67aada613c2dd08457941a6");
160         cipher.encrypt(&mut block);
161         let expected_plaintext_3 = hex!("f69f2445df4f9b17ad2b417be66c3710");
162         assert_eq!(expected_plaintext_3, block);
163     }
164 
165     /// Generates the test cases to validate the AES-128-CTR implementation.
166     /// For example, to test `MyAesCtr128Impl`:
167     ///
168     /// ```
169     /// use crypto_provider::aes::ctr::testing::*;
170     ///
171     /// mod tests {
172     ///     #[apply(aes_128_ctr_test_cases)]
173     ///     fn aes_128_ctr_tests(testcase: CryptoProviderTestCase<MyAesCtr128Impl>) {
174     ///         testcase(MyAesCtr128Impl);
175     ///     }
176     /// }
177     /// ```
178     #[template]
179     #[export]
180     #[rstest]
181     #[case::encrypt(aes_128_ctr_test_encrypt)]
182     #[case::decrypt(aes_128_ctr_test_decrypt)]
aes_128_ctr_test_cases<F: AesCtrFactory<Key = Aes128Key>>( #[case] testcase: CryptoProviderTestCase<F>, )183     fn aes_128_ctr_test_cases<F: AesCtrFactory<Key = Aes128Key>>(
184         #[case] testcase: CryptoProviderTestCase<F>,
185     ) {
186     }
187 
188     /// Generates the test cases to validate the AES-256-CTR implementation.
189     /// For example, to test `MyAesCtr256Impl`:
190     ///
191     /// ```
192     /// use crypto_provider::aes::ctr::testing::*;
193     ///
194     /// mod tests {
195     ///     #[apply(aes_256_ctr_test_cases_impl)]
196     ///     fn aes_256_ctr_tests(testcase: CryptoProviderTestCase<MyAesCtr256Impl>) {
197     ///         testcase(MyAesCtr256Impl);
198     ///     }
199     /// }
200     /// ```
201     #[template]
202     #[export]
203     #[rstest]
204     #[case::encrypt(aes_256_ctr_test_encrypt)]
205     #[case::decrypt(aes_256_ctr_test_decrypt)]
aes_256_ctr_test_cases<F: AesCtrFactory<Key = Aes256Key>>( #[case] testcase: CryptoProviderTestCase<F>, )206     fn aes_256_ctr_test_cases<F: AesCtrFactory<Key = Aes256Key>>(
207         #[case] testcase: CryptoProviderTestCase<F>,
208     ) {
209     }
210 }
211