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