• 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 //! An abstraction layer around AES implementations.
16 //!
17 //! The design is an attempt to make it easy to provide implementations that are both idiomatic
18 //! Rust (e.g. RustCrypto) as well as FFI-backed (e.g. openssl and other C impls).
19 #![forbid(unsafe_code)]
20 #![deny(missing_docs)]
21 
22 use core::{array, fmt};
23 
24 pub mod ctr;
25 
26 #[cfg(feature = "alloc")]
27 pub mod cbc;
28 #[cfg(feature = "gcm_siv")]
29 pub mod gcm_siv;
30 
31 /// Block size in bytes for AES (and XTS-AES)
32 pub const BLOCK_SIZE: usize = 16;
33 
34 /// A single AES block.
35 pub type AesBlock = [u8; BLOCK_SIZE];
36 
37 /// Helper trait to enforce encryption and decryption with the same size key
38 pub trait Aes {
39     /// The AES key containing the raw bytes used to for key scheduling
40     type Key: AesKey;
41 
42     /// The cipher used for encryption
43     type EncryptCipher: AesEncryptCipher<Key = Self::Key>;
44 
45     /// the cipher used for decryption
46     type DecryptCipher: AesDecryptCipher<Key = Self::Key>;
47 }
48 
49 /// The base AesCipher trait which describes common operations to both encryption and decryption ciphers
50 pub trait AesCipher {
51     /// The type of the key used which holds the raw bytes used in key scheduling
52     type Key: AesKey;
53 
54     /// Creates a new cipher from the AesKey
new(key: &Self::Key) -> Self55     fn new(key: &Self::Key) -> Self;
56 }
57 
58 /// An AES cipher used for encrypting blocks
59 pub trait AesEncryptCipher: AesCipher {
60     /// Encrypt `block` in place.
encrypt(&self, block: &mut AesBlock)61     fn encrypt(&self, block: &mut AesBlock);
62 }
63 
64 /// An AES cipher used for decrypting blocks
65 pub trait AesDecryptCipher: AesCipher {
66     /// Decrypt `block` in place.
decrypt(&self, block: &mut AesBlock)67     fn decrypt(&self, block: &mut AesBlock);
68 }
69 
70 /// An appropriately sized `[u8; N]` array that the key can be constructed from, e.g. `[u8; 16]`
71 /// for AES-128.
72 pub trait AesKey: for<'a> TryFrom<&'a [u8], Error = Self::TryFromError> {
73     /// The error used by the `TryFrom` implementation used to construct `Self::Array` from a
74     /// slice. For the typical case of `Self::Array` being an `[u8; N]`, this would be
75     /// `core::array::TryFromSliceError`.
76     ///
77     /// This is broken out as a separate type to allow the `fmt::Debug` requirement needed for
78     /// `expect()`.
79     type TryFromError: fmt::Debug;
80 
81     /// The byte array type the key can be represented with
82     type Array;
83 
84     /// Key size in bytes -- must match the length of `Self::KeyBytes`.`
85     ///
86     /// Unfortunately `KeyBytes` can't reference this const in the type declaration, so it must be
87     /// specified separately.
88     const KEY_SIZE: usize;
89 
90     /// Returns the key material as a slice
as_slice(&self) -> &[u8]91     fn as_slice(&self) -> &[u8];
92 
93     /// Returns the key material as an array
as_array(&self) -> &Self::Array94     fn as_array(&self) -> &Self::Array;
95 }
96 
97 /// An AES-128 key.
98 #[derive(Clone)]
99 pub struct Aes128Key {
100     key: [u8; 16],
101 }
102 
103 impl AesKey for Aes128Key {
104     type TryFromError = array::TryFromSliceError;
105     type Array = [u8; 16];
106     const KEY_SIZE: usize = 16;
107 
as_slice(&self) -> &[u8]108     fn as_slice(&self) -> &[u8] {
109         &self.key
110     }
111 
as_array(&self) -> &Self::Array112     fn as_array(&self) -> &Self::Array {
113         &self.key
114     }
115 }
116 
117 impl TryFrom<&[u8]> for Aes128Key {
118     type Error = array::TryFromSliceError;
119 
try_from(value: &[u8]) -> Result<Self, Self::Error>120     fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
121         value.try_into().map(|arr| Self { key: arr })
122     }
123 }
124 
125 impl From<[u8; 16]> for Aes128Key {
from(arr: [u8; 16]) -> Self126     fn from(arr: [u8; 16]) -> Self {
127         Self { key: arr }
128     }
129 }
130 
131 /// An AES-256 key.
132 #[derive(Clone)]
133 pub struct Aes256Key {
134     key: [u8; 32],
135 }
136 
137 impl AesKey for Aes256Key {
138     type TryFromError = array::TryFromSliceError;
139     type Array = [u8; 32];
140     const KEY_SIZE: usize = 32;
141 
as_slice(&self) -> &[u8]142     fn as_slice(&self) -> &[u8] {
143         &self.key
144     }
145 
as_array(&self) -> &Self::Array146     fn as_array(&self) -> &Self::Array {
147         &self.key
148     }
149 }
150 
151 impl TryFrom<&[u8]> for Aes256Key {
152     type Error = array::TryFromSliceError;
153 
try_from(value: &[u8]) -> Result<Self, Self::Error>154     fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
155         value.try_into().map(|arr| Self { key: arr })
156     }
157 }
158 
159 impl From<[u8; 32]> for Aes256Key {
from(arr: [u8; 32]) -> Self160     fn from(arr: [u8; 32]) -> Self {
161         Self { key: arr }
162     }
163 }
164 
165 /// Module for testing implementations of this crate.
166 #[cfg(feature = "testing")]
167 pub mod testing {
168     use super::*;
169     pub use crate::testing::prelude::*;
170     use core::marker;
171     use hex_literal::hex;
172     use rstest_reuse::template;
173 
174     /// Test encryption with AES-128
aes_128_test_encrypt<A: AesEncryptCipher<Key = Aes128Key>>( _marker: marker::PhantomData<A>, )175     pub fn aes_128_test_encrypt<A: AesEncryptCipher<Key = Aes128Key>>(
176         _marker: marker::PhantomData<A>,
177     ) {
178         // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.1.1
179         let key: Aes128Key = hex!("2b7e151628aed2a6abf7158809cf4f3c").into();
180         let mut block = [0_u8; 16];
181         let enc_cipher = A::new(&key);
182 
183         block.copy_from_slice(&hex!("6bc1bee22e409f96e93d7e117393172a"));
184         enc_cipher.encrypt(&mut block);
185         assert_eq!(hex!("3ad77bb40d7a3660a89ecaf32466ef97"), block);
186 
187         block.copy_from_slice(&hex!("ae2d8a571e03ac9c9eb76fac45af8e51"));
188         enc_cipher.encrypt(&mut block);
189         assert_eq!(hex!("f5d3d58503b9699de785895a96fdbaaf"), block);
190 
191         block.copy_from_slice(&hex!("30c81c46a35ce411e5fbc1191a0a52ef"));
192         enc_cipher.encrypt(&mut block);
193         assert_eq!(hex!("43b1cd7f598ece23881b00e3ed030688"), block);
194 
195         block.copy_from_slice(&hex!("f69f2445df4f9b17ad2b417be66c3710"));
196         enc_cipher.encrypt(&mut block);
197         assert_eq!(hex!("7b0c785e27e8ad3f8223207104725dd4"), block);
198     }
199 
200     /// Test decryption with AES-128
aes_128_test_decrypt<A: AesDecryptCipher<Key = Aes128Key>>( _marker: marker::PhantomData<A>, )201     pub fn aes_128_test_decrypt<A: AesDecryptCipher<Key = Aes128Key>>(
202         _marker: marker::PhantomData<A>,
203     ) {
204         // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.1.2
205         let key: Aes128Key = hex!("2b7e151628aed2a6abf7158809cf4f3c").into();
206         let mut block = [0_u8; 16];
207         let dec_cipher = A::new(&key);
208 
209         block.copy_from_slice(&hex!("3ad77bb40d7a3660a89ecaf32466ef97"));
210         dec_cipher.decrypt(&mut block);
211         assert_eq!(hex!("6bc1bee22e409f96e93d7e117393172a"), block);
212 
213         block.copy_from_slice(&hex!("f5d3d58503b9699de785895a96fdbaaf"));
214         dec_cipher.decrypt(&mut block);
215         assert_eq!(hex!("ae2d8a571e03ac9c9eb76fac45af8e51"), block);
216 
217         block.copy_from_slice(&hex!("43b1cd7f598ece23881b00e3ed030688"));
218         dec_cipher.decrypt(&mut block);
219         assert_eq!(hex!("30c81c46a35ce411e5fbc1191a0a52ef"), block);
220 
221         block.copy_from_slice(&hex!("7b0c785e27e8ad3f8223207104725dd4"));
222         dec_cipher.decrypt(&mut block);
223         assert_eq!(hex!("f69f2445df4f9b17ad2b417be66c3710"), block);
224     }
225 
226     /// Test encryption with AES-256
aes_256_test_encrypt<A: AesEncryptCipher<Key = Aes256Key>>( _marker: marker::PhantomData<A>, )227     pub fn aes_256_test_encrypt<A: AesEncryptCipher<Key = Aes256Key>>(
228         _marker: marker::PhantomData<A>,
229     ) {
230         // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.1.5
231         let key: Aes256Key =
232             hex!("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").into();
233         let mut block: [u8; 16];
234         let enc_cipher = A::new(&key);
235 
236         block = hex!("6bc1bee22e409f96e93d7e117393172a");
237         enc_cipher.encrypt(&mut block);
238         assert_eq!(hex!("f3eed1bdb5d2a03c064b5a7e3db181f8"), block);
239 
240         block = hex!("ae2d8a571e03ac9c9eb76fac45af8e51");
241         enc_cipher.encrypt(&mut block);
242         assert_eq!(hex!("591ccb10d410ed26dc5ba74a31362870"), block);
243 
244         block = hex!("30c81c46a35ce411e5fbc1191a0a52ef");
245         enc_cipher.encrypt(&mut block);
246         assert_eq!(hex!("b6ed21b99ca6f4f9f153e7b1beafed1d"), block);
247 
248         block = hex!("f69f2445df4f9b17ad2b417be66c3710");
249         enc_cipher.encrypt(&mut block);
250         assert_eq!(hex!("23304b7a39f9f3ff067d8d8f9e24ecc7"), block);
251     }
252 
253     /// Test decryption with AES-256
aes_256_test_decrypt<A: AesDecryptCipher<Key = Aes256Key>>( _marker: marker::PhantomData<A>, )254     pub fn aes_256_test_decrypt<A: AesDecryptCipher<Key = Aes256Key>>(
255         _marker: marker::PhantomData<A>,
256     ) {
257         // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf F.1.6
258         let key: Aes256Key =
259             hex!("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").into();
260         let mut block: [u8; 16];
261         let dec_cipher = A::new(&key);
262 
263         block = hex!("f3eed1bdb5d2a03c064b5a7e3db181f8");
264         dec_cipher.decrypt(&mut block);
265         assert_eq!(hex!("6bc1bee22e409f96e93d7e117393172a"), block);
266 
267         block = hex!("591ccb10d410ed26dc5ba74a31362870");
268         dec_cipher.decrypt(&mut block);
269         assert_eq!(hex!("ae2d8a571e03ac9c9eb76fac45af8e51"), block);
270 
271         block = hex!("b6ed21b99ca6f4f9f153e7b1beafed1d");
272         dec_cipher.decrypt(&mut block);
273         assert_eq!(hex!("30c81c46a35ce411e5fbc1191a0a52ef"), block);
274 
275         block = hex!("23304b7a39f9f3ff067d8d8f9e24ecc7");
276         dec_cipher.decrypt(&mut block);
277         assert_eq!(hex!("f69f2445df4f9b17ad2b417be66c3710"), block);
278     }
279 
280     /// Generates the test cases to validate the AES-128 implementation.
281     /// For example, to test `MyAes128Impl`:
282     ///
283     /// ```
284     /// use crypto_provider::aes::testing::*;
285     ///
286     /// mod tests {
287     ///     #[apply(aes_128_encrypt_test_cases)]
288     ///     fn aes_128_tests(f: CryptoProviderTestCase<MyAes128Impl>) {
289     ///         f(MyAes128Impl);
290     ///     }
291     /// }
292     /// ```
293     #[template]
294     #[export]
295     #[rstest]
296     #[case::encrypt(aes_128_test_encrypt)]
aes_128_encrypt_test_cases<A: AesFactory<Key = Aes128Key>>( #[case] testcase: CryptoProviderTestCase<F>, )297     fn aes_128_encrypt_test_cases<A: AesFactory<Key = Aes128Key>>(
298         #[case] testcase: CryptoProviderTestCase<F>,
299     ) {
300     }
301 
302     /// Generates the test cases to validate the AES-128 implementation.
303     /// For example, to test `MyAes128Impl`:
304     ///
305     /// ```
306     /// use crypto_provider::aes::testing::*;
307     ///
308     /// mod tests {
309     ///     #[apply(aes_128_decrypt_test_cases)]
310     ///     fn aes_128_tests(f: CryptoProviderTestCase<MyAes128Impl>) {
311     ///         f(MyAes128Impl);
312     ///     }
313     /// }
314     /// ```
315     #[template]
316     #[export]
317     #[rstest]
318     #[case::decrypt(aes_128_test_decrypt)]
aes_128_decrypt_test_cases<F: AesFactory<Key = Aes128Key>>( #[case] testcase: CryptoProviderTestCase<F>, )319     fn aes_128_decrypt_test_cases<F: AesFactory<Key = Aes128Key>>(
320         #[case] testcase: CryptoProviderTestCase<F>,
321     ) {
322     }
323 
324     /// Generates the test cases to validate the AES-256 implementation.
325     /// For example, to test `MyAes256Impl`:
326     ///
327     /// ```
328     /// use crypto_provider::aes::testing::*;
329     ///
330     /// mod tests {
331     ///     #[apply(aes_256_encrypt_test_cases)]
332     ///     fn aes_256_tests(f: CryptoProviderTestCase<MyAes256Impl>) {
333     ///         f(MyAes256Impl);
334     ///     }
335     /// }
336     /// ```
337     #[template]
338     #[export]
339     #[rstest]
340     #[case::encrypt(aes_256_test_encrypt)]
aes_256_encrypt_test_cases<F: AesFactory<Key = Aes256Key>>( #[case] testcase: CryptoProviderTestCase<F>, )341     fn aes_256_encrypt_test_cases<F: AesFactory<Key = Aes256Key>>(
342         #[case] testcase: CryptoProviderTestCase<F>,
343     ) {
344     }
345 
346     /// Generates the test cases to validate the AES-256 implementation.
347     /// For example, to test `MyAes256Impl`:
348     ///
349     /// ```
350     /// use crypto_provider::aes::testing::*;
351     ///
352     /// mod tests {
353     ///     #[apply(aes_256_decrypt_test_cases)]
354     ///     fn aes_256_tests(f: CryptoProviderTestCase<MyAes256Impl>) {
355     ///         f(MyAes256Impl);
356     ///     }
357     /// }
358     /// ```
359     #[template]
360     #[export]
361     #[rstest]
362     #[case::decrypt(aes_256_test_decrypt)]
aes_256_decrypt_test_cases<F: AesFactory<Key = Aes256Key>>( #[case] testcase: CryptoProviderTestCase<F>, )363     fn aes_256_decrypt_test_cases<F: AesFactory<Key = Aes256Key>>(
364         #[case] testcase: CryptoProviderTestCase<F>,
365     ) {
366     }
367 }
368