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