• 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 use crate::aes::Aes256Key;
16 pub use crate::prelude::*;
17 use core::marker::PhantomData;
18 use crypto_provider::{
19     aes::cbc::{AesCbcIv, AesCbcPkcs7Padded},
20     tinyvec::SliceVec,
21 };
22 use hex_literal::hex;
23 use rstest_reuse::template;
24 
25 /// Tests for AES-256-CBC encryption
aes_256_cbc_test_encrypt<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>)26 pub fn aes_256_cbc_test_encrypt<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>) {
27     // https://github.com/google/wycheproof/blob/b063b4a/testvectors/aes_cbc_pkcs5_test.json#L1492
28     // tcId: 132
29     let key: Aes256Key =
30         hex!("665a02bc265a66d01775091da56726b6668bfd903cb7af66fb1b78a8a062e43c").into();
31     let iv: AesCbcIv = hex!("3fb0d5ecd06c71150748b599595833cb");
32     let msg = hex!("3f56935def3f");
33     let expected_ciphertext = hex!("3f3f39697bd7e88d85a14132be1cbc48");
34     assert_eq!(A::encrypt(&key, &iv, &msg), expected_ciphertext);
35 }
36 
37 /// Tests for AES-256-CBC in-place encryption
aes_256_cbc_test_encrypt_in_place<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>)38 pub fn aes_256_cbc_test_encrypt_in_place<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>) {
39     // https://github.com/google/wycheproof/blob/b063b4a/testvectors/aes_cbc_pkcs5_test.json#L1492
40     // tcId: 132
41     let key: Aes256Key =
42         hex!("665a02bc265a66d01775091da56726b6668bfd903cb7af66fb1b78a8a062e43c").into();
43     let iv: AesCbcIv = hex!("3fb0d5ecd06c71150748b599595833cb");
44     let msg = hex!("3f56935def3f");
45     let expected_ciphertext = hex!("3f3f39697bd7e88d85a14132be1cbc48");
46     let mut msg_buffer_backing = [0_u8; 16];
47     let mut msg_buffer = SliceVec::from_slice_len(&mut msg_buffer_backing, 0);
48     msg_buffer.extend_from_slice(&msg);
49     A::encrypt_in_place(&key, &iv, &mut msg_buffer).unwrap();
50     assert_eq!(msg_buffer.as_slice(), &expected_ciphertext);
51 }
52 
53 /// Tests for AES-256-CBC encryption, where the given buffer `SliceVec` is too short to contain the
54 /// output.
aes_256_cbc_test_encrypt_in_place_too_short<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>)55 pub fn aes_256_cbc_test_encrypt_in_place_too_short<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>) {
56     // https://github.com/google/wycheproof/blob/b063b4a/testvectors/aes_cbc_pkcs5_test.json#L1612
57     // tcId: 144
58     let key: Aes256Key =
59         hex!("4f097858a1aec62cf18f0966b2b120783aa4ae9149d3213109740506ae47adfe").into();
60     let iv: AesCbcIv = hex!("400aab92803bcbb44a96ef789655b34e");
61     let msg = hex!("ee53d8e5039e82d9fcca114e375a014febfea117a7e709d9008d43858e3660");
62     let mut msg_buffer_backing = [0_u8; 31];
63     let mut msg_buffer = SliceVec::from_slice_len(&mut msg_buffer_backing, 0);
64     msg_buffer.extend_from_slice(&msg);
65     A::encrypt_in_place(&key, &iv, &mut msg_buffer)
66         .expect_err("Encrypting AES with 15-byte buffer should fail");
67     // Buffer content is undefined, but test to make sure it doesn't contain half-decrypted data
68     assert!(
69         msg_buffer.as_slice() == [0_u8; 32] || msg_buffer.as_slice() == msg,
70         "Unrecognized content in buffer after decryption failure"
71     )
72 }
73 
74 /// Tests for AES-256-CBC decryption
aes_256_cbc_test_decrypt<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>)75 pub fn aes_256_cbc_test_decrypt<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>) {
76     // https://github.com/google/wycheproof/blob/b063b4a/testvectors/aes_cbc_pkcs5_test.json#L1492
77     // tcId: 132
78     let key: Aes256Key =
79         hex!("665a02bc265a66d01775091da56726b6668bfd903cb7af66fb1b78a8a062e43c").into();
80     let iv: AesCbcIv = hex!("3fb0d5ecd06c71150748b599595833cb");
81     let ciphertext = hex!("3f3f39697bd7e88d85a14132be1cbc48");
82     let expected_msg = hex!("3f56935def3f");
83     assert_eq!(A::decrypt(&key, &iv, &ciphertext).unwrap(), expected_msg);
84 }
85 
86 /// Tests for AES-256-CBC decryption with bad padding
aes_256_cbc_test_decrypt_bad_padding<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>)87 pub fn aes_256_cbc_test_decrypt_bad_padding<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>) {
88     // https://github.com/google/wycheproof/blob/b063b4a/testvectors/aes_cbc_pkcs5_test.json#L1690
89     // tcId: 151
90     let key: Aes256Key =
91         hex!("7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a").into();
92     let iv: AesCbcIv = hex!("f010f61c31c9aa8fa0d5be5f6b0f2f70");
93     let ciphertext = hex!("8881e9e02fa9e3037b397957ba1fb7ce64679a46621b792f643542a735f0bbbf");
94     A::decrypt(&key, &iv, &ciphertext).expect_err("Decryption with bad padding should fail");
95 }
96 
97 /// Tests for AES-256-CBC in-place decryption
aes_256_cbc_test_decrypt_in_place<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>)98 pub fn aes_256_cbc_test_decrypt_in_place<A: AesCbcPkcs7Padded>(_marker: PhantomData<A>) {
99     // https://github.com/google/wycheproof/blob/b063b4a/testvectors/aes_cbc_pkcs5_test.json#L1492
100     // tcId: 132
101     let key: Aes256Key =
102         hex!("665a02bc265a66d01775091da56726b6668bfd903cb7af66fb1b78a8a062e43c").into();
103     let iv: AesCbcIv = hex!("3fb0d5ecd06c71150748b599595833cb");
104     let mut ciphertext = hex!("3f3f39697bd7e88d85a14132be1cbc48");
105     let expected_msg = hex!("3f56935def3f");
106     let mut msg_buffer = SliceVec::from(&mut ciphertext);
107     A::decrypt_in_place(&key, &iv, &mut msg_buffer).unwrap();
108     assert_eq!(msg_buffer.as_slice(), expected_msg);
109 }
110 
111 /// Tests for AES-256-CBC in-place decryption with bad padding
aes_256_cbc_test_decrypt_in_place_bad_padding<A: AesCbcPkcs7Padded>( _marker: PhantomData<A>, )112 pub fn aes_256_cbc_test_decrypt_in_place_bad_padding<A: AesCbcPkcs7Padded>(
113     _marker: PhantomData<A>,
114 ) {
115     // https://github.com/google/wycheproof/blob/b063b4a/testvectors/aes_cbc_pkcs5_test.json#L1690
116     // tcId: 151
117     let key: Aes256Key =
118         hex!("7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a").into();
119     let iv: AesCbcIv = hex!("f010f61c31c9aa8fa0d5be5f6b0f2f70");
120     let ciphertext = hex!("8881e9e02fa9e3037b397957ba1fb7ce64679a46621b792f643542a735f0bbbf");
121     let mut msg_buffer_backing = ciphertext;
122     let mut msg_buffer = SliceVec::from(&mut msg_buffer_backing);
123     A::decrypt_in_place(&key, &iv, &mut msg_buffer)
124         .expect_err("Decryption with bad padding should fail");
125     // Buffer content is undefined, but test to make sure it doesn't contain half-decrypted data
126     assert!(
127         msg_buffer.as_slice() == [0_u8; 32] || msg_buffer.as_slice() == ciphertext,
128         "Unrecognized content in buffer after decryption failure"
129     )
130 }
131 
132 /// Generates the test cases to validate the AES-256-CBC implementation.
133 /// For example, to test `MyAesCbc256Impl`:
134 ///
135 /// ```
136 /// use crypto_provider::aes::cbc::testing::*;
137 ///
138 /// mod tests {
139 ///     #[apply(aes_256_cbc_test_cases)]
140 ///     fn aes_256_cbc_tests(
141 ///             testcase: CryptoProviderTestCases<PhantomData<MyAesCbc256Impl>>) {
142 ///         testcase(PhantomData);
143 ///     }
144 /// }
145 /// ```
146 #[template]
147 #[export]
148 #[rstest]
149 #[case::encrypt(aes_256_cbc_test_encrypt)]
150 #[case::encrypt_in_place(aes_256_cbc_test_encrypt_in_place)]
151 #[case::encrypt_in_place_too_short(aes_256_cbc_test_encrypt_in_place_too_short)]
152 #[case::decrypt(aes_256_cbc_test_decrypt)]
153 #[case::decrypt_bad_padding(aes_256_cbc_test_decrypt_bad_padding)]
154 #[case::decrypt_in_place_bad_padding(aes_256_cbc_test_decrypt_in_place_bad_padding)]
aes_256_cbc_test_cases<A: AesCbcPkcs7Padded>(#[case] testcase: CryptoProviderTestCases<F>)155 fn aes_256_cbc_test_cases<A: AesCbcPkcs7Padded>(#[case] testcase: CryptoProviderTestCases<F>) {}
156