• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! HwCryptoOperations tests.
18 
19 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
20     AesKey::AesKey, ExplicitKeyMaterial::ExplicitKeyMaterial, KeyType::KeyType, KeyLifetime::KeyLifetime,
21     KeyUse::KeyUse, OperationData::OperationData, HmacOperationParameters::HmacOperationParameters,
22     SymmetricOperationParameters::SymmetricOperationParameters, SymmetricOperation::SymmetricOperation,
23     HmacKey::HmacKey, CipherModeParameters::CipherModeParameters, AesCipherMode::AesCipherMode,
24     SymmetricCryptoParameters::SymmetricCryptoParameters,
25 };
26 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::{
27     KeyPolicy::KeyPolicy,CryptoOperation::CryptoOperation,CryptoOperationSet::CryptoOperationSet,
28     OperationParameters::OperationParameters, PatternParameters::PatternParameters,
29 };
30 use rdroidtest::{ignore_if, rdroidtest};
31 
32 #[rdroidtest]
33 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_key_operations_connection()34 fn test_hwcrypto_key_operations_connection() {
35     let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
36         .expect("Couldn't get back a hwcryptokey binder object");
37     let hw_crypto_operations = hw_crypto_key.getHwCryptoOperations();
38     assert!(hw_crypto_operations.is_ok(), "Couldn't get back a hwcrypto operations binder object");
39 }
40 
41 #[rdroidtest]
42 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_key_operations_simple_aes_test()43 fn test_hwcrypto_key_operations_simple_aes_test() {
44     let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
45         .expect("Couldn't get back a hwcryptokey binder object");
46     let hw_crypto_operations = hw_crypto_key
47         .getHwCryptoOperations()
48         .expect("Couldn't get back a hwcryptokey operations binder object");
49     let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
50     let policy = KeyPolicy {
51         usage: KeyUse::ENCRYPT_DECRYPT,
52         keyLifetime: KeyLifetime::PORTABLE,
53         keyPermissions: Vec::new(),
54         keyManagementKey: false,
55         keyType: KeyType::AES_128_CBC_PKCS7_PADDING,
56     };
57     let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
58 
59     let nonce = [0u8; 16];
60     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
61         nonce: nonce.into(),
62     }));
63     let direction = SymmetricOperation::ENCRYPT;
64     let sym_op_params =
65         SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
66     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
67     let mut cmd_list = Vec::<CryptoOperation>::new();
68     let data_output = OperationData::DataBuffer(Vec::new());
69     cmd_list.push(CryptoOperation::DataOutput(data_output));
70     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
71     let input_data = OperationData::DataBuffer("string to be encrypted".as_bytes().to_vec());
72     cmd_list.push(CryptoOperation::DataInput(input_data));
73     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
74     let mut crypto_sets = Vec::new();
75     crypto_sets.push(crypto_op_set);
76     let mut op_result = hw_crypto_operations
77         .processCommandList(&mut crypto_sets)
78         .expect("couldn't process commands");
79     // Extracting the vector from the command list because of ownership
80     let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
81         crypto_sets.remove(0).operations.remove(0)
82     else {
83         panic!("not reachable, we created this object above on the test");
84     };
85     let context = op_result.remove(0).context;
86     // Separating the finish call on a different command set to test the returned context
87     let mut cmd_list = Vec::<CryptoOperation>::new();
88     let data_output = OperationData::DataBuffer(encrypted_data);
89     cmd_list.push(CryptoOperation::DataOutput(data_output));
90     cmd_list.push(CryptoOperation::Finish(None));
91     let crypto_op_set = CryptoOperationSet { context, operations: cmd_list };
92     let mut crypto_sets = Vec::new();
93     crypto_sets.push(crypto_op_set);
94     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
95     let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
96         crypto_sets.remove(0).operations.remove(0)
97     else {
98         panic!("not reachable, we created this object above on the test");
99     };
100 
101     // Decrypting
102     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
103         nonce: nonce.into(),
104     }));
105     let direction = SymmetricOperation::DECRYPT;
106     let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
107     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
108     let mut cmd_list = Vec::<CryptoOperation>::new();
109     let data_output = OperationData::DataBuffer(Vec::new());
110     cmd_list.push(CryptoOperation::DataOutput(data_output));
111     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
112     cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
113     cmd_list.push(CryptoOperation::Finish(None));
114     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
115     let mut crypto_sets = Vec::new();
116     crypto_sets.push(crypto_op_set);
117     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
118     // Extracting the vector from the command list because of ownership
119     let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
120         crypto_sets.remove(0).operations.remove(0)
121     else {
122         panic!("not reachable, we created this object above on the test");
123     };
124     let decrypted_msg =
125         String::from_utf8(decrypted_data).expect("couldn't decode received message");
126     assert_eq!(decrypted_msg, "string to be encrypted", "couldn't retrieve original message");
127 }
128 
129 #[rdroidtest]
130 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_key_operations_simple_hmac_test()131 fn test_hwcrypto_key_operations_simple_hmac_test() {
132     let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
133         .expect("Couldn't get back a hwcryptokey binder object");
134     let hw_crypto_operations = hw_crypto_key
135         .getHwCryptoOperations()
136         .expect("Couldn't get back a hwcryptokey operations binder object");
137     let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
138     let policy = KeyPolicy {
139         usage: KeyUse::SIGN,
140         keyLifetime: KeyLifetime::PORTABLE,
141         keyPermissions: Vec::new(),
142         keyManagementKey: false,
143         keyType: KeyType::HMAC_SHA256,
144     };
145     let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
146 
147     let hmac_parameters = HmacOperationParameters { key: Some(key.clone()) };
148     let op_parameters = OperationParameters::Hmac(hmac_parameters);
149     let mut cmd_list = Vec::<CryptoOperation>::new();
150     let data_output = OperationData::DataBuffer(Vec::new());
151     cmd_list.push(CryptoOperation::DataOutput(data_output));
152     cmd_list.push(CryptoOperation::SetOperationParameters(op_parameters));
153     let input_data = OperationData::DataBuffer("text to be mac'ed".as_bytes().to_vec());
154     cmd_list.push(CryptoOperation::DataInput(input_data));
155     cmd_list.push(CryptoOperation::Finish(None));
156     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
157     let mut crypto_sets = Vec::new();
158     crypto_sets.push(crypto_op_set);
159     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
160     // Extracting the vector from the command list because of ownership
161     let CryptoOperation::DataOutput(OperationData::DataBuffer(mac)) =
162         crypto_sets.remove(0).operations.remove(0)
163     else {
164         panic!("not reachable, we created this object above on the test");
165     };
166 
167     //Getting a second mac to compare
168     let hmac_parameters = HmacOperationParameters { key: Some(key) };
169     let op_parameters = OperationParameters::Hmac(hmac_parameters);
170     let mut cmd_list = Vec::<CryptoOperation>::new();
171     let data_output = OperationData::DataBuffer(Vec::new());
172     cmd_list.push(CryptoOperation::DataOutput(data_output));
173     cmd_list.push(CryptoOperation::SetOperationParameters(op_parameters));
174     let input_data = OperationData::DataBuffer("text to be mac'ed".as_bytes().to_vec());
175     cmd_list.push(CryptoOperation::DataInput(input_data));
176     cmd_list.push(CryptoOperation::Finish(None));
177     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
178     let mut crypto_sets = Vec::new();
179     crypto_sets.push(crypto_op_set);
180     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
181     // Extracting the vector from the command list because of ownership
182     let CryptoOperation::DataOutput(OperationData::DataBuffer(mac2)) =
183         crypto_sets.remove(0).operations.remove(0)
184     else {
185         panic!("not reachable, we created this object above on the test");
186     };
187     assert_eq!(mac, mac2, "got a different mac");
188 }
189 
190 #[rdroidtest]
191 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_key_operations_aes_simple_cbcs_test_non_block_multiple()192 fn test_hwcrypto_key_operations_aes_simple_cbcs_test_non_block_multiple() {
193     let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
194         .expect("Couldn't get back a hwcryptokey binder object");
195     let hw_crypto_operations = hw_crypto_key
196         .getHwCryptoOperations()
197         .expect("Couldn't get back a hwcryptokey operations binder object");
198 
199     let usage = KeyUse::ENCRYPT_DECRYPT;
200     let key_type = KeyType::AES_128_CBC_NO_PADDING;
201     let policy = KeyPolicy {
202         usage,
203         keyLifetime: KeyLifetime::PORTABLE,
204         keyPermissions: Vec::new(),
205         keyType: key_type,
206         keyManagementKey: false,
207     };
208     let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
209     let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
210 
211     let nonce = [0u8; 16];
212     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
213         nonce: nonce.into(),
214     }));
215     let direction = SymmetricOperation::ENCRYPT;
216     let sym_op_params =
217         SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
218     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
219     let mut cmd_list = Vec::<CryptoOperation>::new();
220     let data_output = OperationData::DataBuffer(Vec::new());
221     cmd_list.push(CryptoOperation::DataOutput(data_output));
222     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
223     cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
224         numberBlocksProcess: 1,
225         numberBlocksCopy: 0,
226     }));
227     let input_data =
228         OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
229     cmd_list.push(CryptoOperation::DataInput(input_data));
230     let input_data =
231         OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
232     cmd_list.push(CryptoOperation::DataInput(input_data));
233     let input_data = OperationData::DataBuffer("unencrypted".as_bytes().to_vec());
234     cmd_list.push(CryptoOperation::DataInput(input_data));
235     cmd_list.push(CryptoOperation::Finish(None));
236     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
237     let mut crypto_sets = Vec::new();
238     crypto_sets.push(crypto_op_set);
239     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
240     let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
241         crypto_sets.remove(0).operations.remove(0)
242     else {
243         panic!("not reachable, we created this object above on the test");
244     };
245 
246     let clear_encrypted_msg =
247         String::from_utf8(encrypted_data[encrypted_data.len() - "unencrypted".len()..].to_vec())
248             .expect("couldn't decode message");
249     assert_eq!(clear_encrypted_msg, "unencrypted");
250 
251     // Decrypting
252     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
253         nonce: nonce.into(),
254     }));
255     let direction = SymmetricOperation::DECRYPT;
256     let sym_op_params =
257         SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
258     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
259     let mut cmd_list = Vec::<CryptoOperation>::new();
260     let data_output = OperationData::DataBuffer(Vec::new());
261     cmd_list.push(CryptoOperation::DataOutput(data_output));
262     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
263     cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
264         numberBlocksProcess: 1,
265         numberBlocksCopy: 0,
266     }));
267     cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
268     cmd_list.push(CryptoOperation::Finish(None));
269     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
270     let mut crypto_sets = Vec::new();
271     crypto_sets.push(crypto_op_set);
272     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
273     let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
274         crypto_sets.remove(0).operations.remove(0)
275     else {
276         panic!("not reachable, we created this object above on the test");
277     };
278     let decrypted_msg =
279         String::from_utf8(decrypted_data).expect("couldn't decode received message");
280     assert_eq!(
281         decrypted_msg,
282         "encryption data.0123456789abcdeffedcba9876543210\
283         0123456789abcdefunencrypted",
284         "couldn't retrieve original message"
285     );
286 }
287 
288 #[rdroidtest]
289 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_key_operations_aes_simple_all_encrypted_cbcs_test()290 fn test_hwcrypto_key_operations_aes_simple_all_encrypted_cbcs_test() {
291     let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
292         .expect("Couldn't get back a hwcryptokey binder object");
293     let hw_crypto_operations = hw_crypto_key
294         .getHwCryptoOperations()
295         .expect("Couldn't get back a hwcryptokey operations binder object");
296 
297     let usage = KeyUse::ENCRYPT_DECRYPT;
298     let key_type = KeyType::AES_128_CBC_NO_PADDING;
299     let policy = KeyPolicy {
300         usage,
301         keyLifetime: KeyLifetime::PORTABLE,
302         keyPermissions: Vec::new(),
303         keyType: key_type,
304         keyManagementKey: false,
305     };
306     let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
307     let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
308 
309     let nonce = [0u8; 16];
310     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
311         nonce: nonce.into(),
312     }));
313     let direction = SymmetricOperation::ENCRYPT;
314     let sym_op_params =
315         SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
316     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
317     let mut cmd_list = Vec::<CryptoOperation>::new();
318     let data_output = OperationData::DataBuffer(Vec::new());
319     cmd_list.push(CryptoOperation::DataOutput(data_output));
320     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
321     cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
322         numberBlocksProcess: 1,
323         numberBlocksCopy: 0,
324     }));
325     let input_data =
326         OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
327     cmd_list.push(CryptoOperation::DataInput(input_data));
328     let input_data =
329         OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
330     cmd_list.push(CryptoOperation::DataInput(input_data));
331     cmd_list.push(CryptoOperation::Finish(None));
332     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
333     let mut crypto_sets = Vec::new();
334     crypto_sets.push(crypto_op_set);
335     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
336 
337     let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
338         crypto_sets.remove(0).operations.remove(0)
339     else {
340         panic!("not reachable, we created this object above on the test");
341     };
342 
343     // Checking that encrypting with patter 0,0 is equivalent to pattern 1,0
344     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
345         nonce: nonce.into(),
346     }));
347     let direction = SymmetricOperation::ENCRYPT;
348     let sym_op_params =
349         SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
350     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
351     let mut cmd_list = Vec::<CryptoOperation>::new();
352     let data_output = OperationData::DataBuffer(Vec::new());
353     cmd_list.push(CryptoOperation::DataOutput(data_output));
354     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
355     cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
356         numberBlocksProcess: 0,
357         numberBlocksCopy: 0,
358     }));
359     let input_data =
360         OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
361     cmd_list.push(CryptoOperation::DataInput(input_data));
362     let input_data =
363         OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
364     cmd_list.push(CryptoOperation::DataInput(input_data));
365     cmd_list.push(CryptoOperation::Finish(None));
366     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
367     let mut crypto_sets = Vec::new();
368     crypto_sets.push(crypto_op_set);
369     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
370     let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data1)) =
371         crypto_sets.remove(0).operations.remove(0)
372     else {
373         panic!("not reachable, we created this object above on the test");
374     };
375     assert_eq!(encrypted_data, encrypted_data1, "encrypted data should match");
376 
377     // Decrypting
378     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
379         nonce: nonce.into(),
380     }));
381     let direction = SymmetricOperation::DECRYPT;
382     let sym_op_params =
383         SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
384     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
385     let mut cmd_list = Vec::<CryptoOperation>::new();
386     let data_output = OperationData::DataBuffer(Vec::new());
387     cmd_list.push(CryptoOperation::DataOutput(data_output));
388     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
389     cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
390     cmd_list.push(CryptoOperation::Finish(None));
391     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
392     let mut crypto_sets = Vec::new();
393     crypto_sets.push(crypto_op_set);
394     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
395 
396     let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
397         crypto_sets.remove(0).operations.remove(0)
398     else {
399         panic!("not reachable, we created this object above on the test");
400     };
401     let decrypted_msg =
402         String::from_utf8(decrypted_data).expect("couldn't decode received message");
403     assert_eq!(
404         decrypted_msg,
405         "encryption data.0123456789abcdeffedcba9876543210\
406         0123456789abcdef",
407         "couldn't retrieve original message"
408     );
409 }
410 
411 #[rdroidtest]
412 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
check_cbcs_wrong_key_types()413 fn check_cbcs_wrong_key_types() {
414     let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
415         .expect("Couldn't get back a hwcryptokey binder object");
416     let hw_crypto_operations = hw_crypto_key
417         .getHwCryptoOperations()
418         .expect("Couldn't get back a hwcryptokey operations binder object");
419 
420     let usage = KeyUse::ENCRYPT_DECRYPT;
421     let key_type = KeyType::AES_128_CBC_PKCS7_PADDING;
422     let policy = KeyPolicy {
423         usage,
424         keyLifetime: KeyLifetime::PORTABLE,
425         keyPermissions: Vec::new(),
426         keyType: key_type,
427         keyManagementKey: false,
428     };
429     let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
430     let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
431 
432     let nonce = [0u8; 16];
433     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
434         nonce: nonce.into(),
435     }));
436     let direction = SymmetricOperation::ENCRYPT;
437     let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
438     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
439     let mut cmd_list = Vec::<CryptoOperation>::new();
440     let data_output = OperationData::DataBuffer(Vec::new());
441     cmd_list.push(CryptoOperation::DataOutput(data_output));
442     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
443     cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
444         numberBlocksProcess: 1,
445         numberBlocksCopy: 9,
446     }));
447     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
448     let mut crypto_sets = Vec::new();
449     crypto_sets.push(crypto_op_set);
450     let process_result = hw_crypto_operations.processCommandList(&mut crypto_sets);
451     assert!(process_result.is_err(), "Should not be able to use cbcs mode with this key type");
452 
453     let policy = KeyPolicy {
454         usage,
455         keyLifetime: KeyLifetime::PORTABLE,
456         keyPermissions: Vec::new(),
457         keyType: KeyType::AES_256_CBC_NO_PADDING,
458         keyManagementKey: false,
459     };
460     let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes256([0; 32]));
461     let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
462     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
463         nonce: nonce.into(),
464     }));
465     let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
466     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
467     let mut cmd_list = Vec::<CryptoOperation>::new();
468     let data_output = OperationData::DataBuffer(Vec::new());
469     cmd_list.push(CryptoOperation::DataOutput(data_output));
470     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
471     cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
472         numberBlocksProcess: 1,
473         numberBlocksCopy: 9,
474     }));
475     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
476     let mut crypto_sets = Vec::new();
477     crypto_sets.push(crypto_op_set);
478     let process_result = hw_crypto_operations.processCommandList(&mut crypto_sets);
479 
480     assert!(process_result.is_err(), "Should not be able to use cbcs mode with this key type");
481 }
482 
483 #[rdroidtest]
484 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
aes_simple_cbcs_test()485 fn aes_simple_cbcs_test() {
486     let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
487         .expect("Couldn't get back a hwcryptokey binder object");
488     let hw_crypto_operations = hw_crypto_key
489         .getHwCryptoOperations()
490         .expect("Couldn't get back a hwcryptokey operations binder object");
491 
492     let usage = KeyUse::ENCRYPT_DECRYPT;
493     let key_type = KeyType::AES_128_CBC_NO_PADDING;
494     let policy = KeyPolicy {
495         usage,
496         keyLifetime: KeyLifetime::PORTABLE,
497         keyPermissions: Vec::new(),
498         keyType: key_type,
499         keyManagementKey: false,
500     };
501     let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
502     let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
503 
504     let nonce = [0u8; 16];
505     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
506         nonce: nonce.into(),
507     }));
508     let direction = SymmetricOperation::ENCRYPT;
509     let sym_op_params =
510         SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
511     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
512     let mut cmd_list = Vec::<CryptoOperation>::new();
513     let data_output = OperationData::DataBuffer(Vec::new());
514     cmd_list.push(CryptoOperation::DataOutput(data_output));
515     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
516     cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
517         numberBlocksProcess: 1,
518         numberBlocksCopy: 9,
519     }));
520     let input_data =
521         OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
522     cmd_list.push(CryptoOperation::DataInput(input_data));
523     let input_data =
524         OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
525     cmd_list.push(CryptoOperation::DataInput(input_data));
526     let input_data =
527         OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
528     cmd_list.push(CryptoOperation::DataInput(input_data));
529     let input_data =
530         OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
531     cmd_list.push(CryptoOperation::DataInput(input_data));
532     let input_data = OperationData::DataBuffer(
533         "fedcba98765432100123456789abcdefProtectedSection".as_bytes().to_vec(),
534     );
535     cmd_list.push(CryptoOperation::DataInput(input_data));
536     cmd_list.push(CryptoOperation::Finish(None));
537     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
538     let mut crypto_sets = Vec::new();
539     crypto_sets.push(crypto_op_set);
540     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
541 
542     let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
543         crypto_sets.remove(0).operations.remove(0)
544     else {
545         panic!("not reachable, we created this object above on the test");
546     };
547     let clear_encrypted_msg =
548         String::from_utf8(encrypted_data[16..encrypted_data.len() - 16].to_vec())
549             .expect("couldn't decode received message");
550     assert_eq!(
551         clear_encrypted_msg,
552         "0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210\
553         0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdef",
554         "couldn't retrieve clear portion"
555     );
556 
557     // Decrypting
558     let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
559         nonce: nonce.into(),
560     }));
561     let direction = SymmetricOperation::DECRYPT;
562     let sym_op_params =
563         SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
564     let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
565     let mut cmd_list = Vec::<CryptoOperation>::new();
566     let data_output = OperationData::DataBuffer(Vec::new());
567     cmd_list.push(CryptoOperation::DataOutput(data_output));
568     cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
569     cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
570         numberBlocksProcess: 1,
571         numberBlocksCopy: 9,
572     }));
573     cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
574     cmd_list.push(CryptoOperation::Finish(None));
575     let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
576     let mut crypto_sets = Vec::new();
577     crypto_sets.push(crypto_op_set);
578     hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
579 
580     let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
581         crypto_sets.remove(0).operations.remove(0)
582     else {
583         panic!("not reachable, we created this object above on the test");
584     };
585     let decrypted_msg =
586         String::from_utf8(decrypted_data).expect("couldn't decode received message");
587     assert_eq!(
588         decrypted_msg,
589         "encryption data.0123456789abcdeffedcba9876543210\
590         0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210\
591         0123456789abcdeffedcba98765432100123456789abcdefProtectedSection",
592         "couldn't retrieve original message"
593     );
594 }
595 
596 rdroidtest::test_main!();
597