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 15 extern crate alloc; 16 17 use crate::cipher::{ 18 BlockCipher, Cipher, CipherError, CipherInitPurpose, EvpAes128Cbc, EvpAes256Cbc, 19 }; 20 use alloc::vec::Vec; 21 22 /// AES-CBC-128 Cipher implementation. 23 pub struct Aes128Cbc(Cipher<EvpAes128Cbc>); 24 25 impl BlockCipher for Aes128Cbc { 26 type Key = [u8; 16]; 27 type Nonce = [u8; 16]; 28 new_encrypt(key: &Self::Key, nonce: &Self::Nonce) -> Self29 fn new_encrypt(key: &Self::Key, nonce: &Self::Nonce) -> Self { 30 Self(Cipher::new(key, nonce, CipherInitPurpose::Encrypt)) 31 } 32 new_decrypt(key: &Self::Key, nonce: &Self::Nonce) -> Self33 fn new_decrypt(key: &Self::Key, nonce: &Self::Nonce) -> Self { 34 Self(Cipher::new(key, nonce, CipherInitPurpose::Decrypt)) 35 } 36 encrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError>37 fn encrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError> { 38 // Note: Padding is enabled because we did not disable it with `EVP_CIPHER_CTX_set_padding` 39 self.0.encrypt(buffer) 40 } 41 decrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError>42 fn decrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError> { 43 // Note: Padding is enabled because we did not disable it with `EVP_CIPHER_CTX_set_padding` 44 self.0.decrypt(buffer) 45 } 46 } 47 48 /// AES-CBC-256 Cipher implementation. 49 pub struct Aes256Cbc(Cipher<EvpAes256Cbc>); 50 51 impl BlockCipher for Aes256Cbc { 52 type Key = [u8; 32]; 53 type Nonce = [u8; 16]; 54 new_encrypt(key: &Self::Key, nonce: &Self::Nonce) -> Self55 fn new_encrypt(key: &Self::Key, nonce: &Self::Nonce) -> Self { 56 Self(Cipher::new(key, nonce, CipherInitPurpose::Encrypt)) 57 } 58 new_decrypt(key: &Self::Key, nonce: &Self::Nonce) -> Self59 fn new_decrypt(key: &Self::Key, nonce: &Self::Nonce) -> Self { 60 Self(Cipher::new(key, nonce, CipherInitPurpose::Decrypt)) 61 } 62 encrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError>63 fn encrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError> { 64 // Note: Padding is enabled because we did not disable it with `EVP_CIPHER_CTX_set_padding` 65 self.0.encrypt(buffer) 66 } 67 decrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError>68 fn decrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError> { 69 // Note: Padding is enabled because we did not disable it with `EVP_CIPHER_CTX_set_padding` 70 self.0.decrypt(buffer) 71 } 72 } 73 74 #[allow(clippy::expect_used)] 75 #[cfg(test)] 76 mod test { 77 use super::*; 78 use crate::test_helpers::decode_hex; 79 80 #[test] aes_128_cbc_test_encrypt()81 fn aes_128_cbc_test_encrypt() { 82 // https://github.com/google/wycheproof/blob/master/testvectors/aes_cbc_pkcs5_test.json#L30 83 // tcId: 2 84 let iv = decode_hex("c9ee3cd746bf208c65ca9e72a266d54f"); 85 let key = decode_hex("e09eaa5a3f5e56d279d5e7a03373f6ea"); 86 87 let cipher = Aes128Cbc::new_encrypt(&key, &iv); 88 let msg: [u8; 16] = decode_hex("ef4eab37181f98423e53e947e7050fd0"); 89 90 let output = cipher.encrypt_padded(&msg).expect("Failed to encrypt"); 91 92 let expected_ciphertext: [u8; 32] = 93 decode_hex("d1fa697f3e2e04d64f1a0da203813ca5bc226a0b1d42287b2a5b994a66eaf14a"); 94 assert_eq!(expected_ciphertext, &output[..]); 95 } 96 97 #[test] aes_128_cbc_test_encrypt_more_than_one_block()98 fn aes_128_cbc_test_encrypt_more_than_one_block() { 99 // https://github.com/google/wycheproof/blob/master/testvectors/aes_cbc_pkcs5_test.json#L210 100 // tcId: 20 101 let iv = decode_hex("54f2459e40e002763144f4752cde2fb5"); 102 let key = decode_hex("831e664c9e3f0c3094c0b27b9d908eb2"); 103 104 let cipher = Aes128Cbc::new_encrypt(&key, &iv); 105 let msg: [u8; 17] = decode_hex("26603bb76dd0a0180791c4ed4d3b058807"); 106 107 let output = cipher.encrypt_padded(&msg).expect("Failed to encrypt"); 108 109 let expected_ciphertext: [u8; 32] = 110 decode_hex("8d55dc10584e243f55d2bdbb5758b7fabcd58c8d3785f01c7e3640b2a1dadcd9"); 111 assert_eq!(expected_ciphertext, &output[..]); 112 } 113 114 #[test] aes_128_cbc_test_decrypt()115 fn aes_128_cbc_test_decrypt() { 116 // https://github.com/google/wycheproof/blob/master/testvectors/aes_cbc_pkcs5_test.json#L30 117 // tcId: 2 118 let key = decode_hex("e09eaa5a3f5e56d279d5e7a03373f6ea"); 119 let iv = decode_hex("c9ee3cd746bf208c65ca9e72a266d54f"); 120 let cipher = Aes128Cbc::new_decrypt(&key, &iv); 121 let ciphertext: [u8; 32] = 122 decode_hex("d1fa697f3e2e04d64f1a0da203813ca5bc226a0b1d42287b2a5b994a66eaf14a"); 123 let decrypted = cipher 124 .decrypt_padded(&ciphertext) 125 .expect("Failed to decrypt"); 126 let expected_plaintext: [u8; 16] = decode_hex("ef4eab37181f98423e53e947e7050fd0"); 127 assert_eq!(expected_plaintext, &decrypted[..]); 128 } 129 130 #[test] aes_128_cbc_test_decrypt_empty_message()131 fn aes_128_cbc_test_decrypt_empty_message() { 132 // https://github.com/google/wycheproof/blob/master/testvectors/aes_cbc_pkcs5_test.json#L20 133 // tcId: 1 134 let key = decode_hex("e34f15c7bd819930fe9d66e0c166e61c"); 135 let iv = decode_hex("da9520f7d3520277035173299388bee2"); 136 let cipher = Aes128Cbc::new_decrypt(&key, &iv); 137 let ciphertext: [u8; 16] = decode_hex("b10ab60153276941361000414aed0a9d"); 138 let decrypted = cipher 139 .decrypt_padded(&ciphertext) 140 .expect("Failed to decrypt"); 141 let expected_plaintext: [u8; 0] = decode_hex(""); 142 assert_eq!(expected_plaintext, &decrypted[..]); 143 } 144 145 #[test] aes_256_cbc_test_encrypt()146 pub fn aes_256_cbc_test_encrypt() { 147 // https://github.com/google/wycheproof/blob/master/testvectors/aes_cbc_pkcs5_test.json#L1412 148 // tcId: 124 149 let iv = decode_hex("9ec7b863ac845cad5e4673da21f5b6a9"); 150 let key = decode_hex("612e837843ceae7f61d49625faa7e7494f9253e20cb3adcea686512b043936cd"); 151 152 let cipher = Aes256Cbc::new_encrypt(&key, &iv); 153 let msg: [u8; 16] = decode_hex("cc37fae15f745a2f40e2c8b192f2b38d"); 154 155 let output = cipher.encrypt_padded(&msg).expect("Failed to encrypt"); 156 157 let expected_ciphertext: [u8; 32] = 158 decode_hex("299295be47e9f5441fe83a7a811c4aeb2650333e681e69fa6b767d28a6ccf282"); 159 assert_eq!(expected_ciphertext, &output[..]); 160 } 161 162 #[test] aes_256_cbc_test_encrypt_more_than_one_block()163 pub fn aes_256_cbc_test_encrypt_more_than_one_block() { 164 // https://github.com/google/wycheproof/blob/master/testvectors/aes_cbc_pkcs5_test.json#L1582C24-L1582C24 165 // tcId: 141 166 let iv = decode_hex("4b74bd981ea9d074757c3e2ef515e5fb"); 167 let key = decode_hex("73216fafd0022d0d6ee27198b2272578fa8f04dd9f44467fbb6437aa45641bf7"); 168 169 let cipher = Aes256Cbc::new_encrypt(&key, &iv); 170 let msg: [u8; 17] = decode_hex("d5247b8f6c3edcbfb1d591d13ece23d2f5"); 171 172 let output = cipher.encrypt_padded(&msg).expect("Failed to encrypt"); 173 174 let expected_ciphertext: [u8; 32] = 175 decode_hex("fbea776fb1653635f88e2937ed2450ba4e9063e96d7cdba04928f01cb85492fe"); 176 assert_eq!(expected_ciphertext, &output[..]); 177 } 178 179 #[test] aes_256_cbc_test_decrypt()180 fn aes_256_cbc_test_decrypt() { 181 // https://github.com/google/wycheproof/blob/master/testvectors/aes_cbc_pkcs5_test.json#L1452 182 // tcId: 128 183 let key = decode_hex("ea3b016bdd387dd64d837c71683808f335dbdc53598a4ea8c5f952473fafaf5f"); 184 let iv = decode_hex("fae3e2054113f6b3b904aadbfe59655c"); 185 let cipher = Aes256Cbc::new_decrypt(&key, &iv); 186 let ciphertext: [u8; 16] = decode_hex("b90c326b72eb222ddb4dae47f2bc223c"); 187 let decrypted = cipher 188 .decrypt_padded(&ciphertext) 189 .expect("Failed to decrypt"); 190 let expected_plaintext: [u8; 2] = decode_hex("6601"); 191 assert_eq!(expected_plaintext, &decrypted[..]); 192 } 193 } 194