• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023, The Android Open Source Project
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::keystore2_client_test_utils::{
16     app_attest_key_feature_exists, delete_app_key, get_vsr_api_level,
17     perform_sample_asym_sign_verify_op, perform_sample_hmac_sign_verify_op,
18     perform_sample_sym_key_decrypt_op, perform_sample_sym_key_encrypt_op,
19     verify_certificate_serial_num, verify_certificate_subject_name, SAMPLE_PLAIN_TEXT,
20 };
21 use crate::{require_keymint, skip_test_if_no_app_attest_key_feature};
22 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
23     Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
24     ErrorCode::ErrorCode, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
25     SecurityLevel::SecurityLevel, Tag::Tag,
26 };
27 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
28     HardwareAuthToken::HardwareAuthToken, HardwareAuthenticatorType::HardwareAuthenticatorType,
29     KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue,
30 };
31 use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
32     Timestamp::Timestamp
33 };
34 use android_system_keystore2::aidl::android::system::keystore2::{
35     Domain::Domain, KeyDescriptor::KeyDescriptor, KeyMetadata::KeyMetadata,
36     ResponseCode::ResponseCode,
37 };
38 use bssl_crypto::digest;
39 use keystore_attestation::{AttestationExtension, ATTESTATION_EXTENSION_OID};
40 use keystore2_test_utils::ffi_test_utils::get_value_from_attest_record;
41 use keystore2_test_utils::{
42     authorizations, get_keystore_auth_service, key_generations,
43     key_generations::Error, SecLevel,
44 };
45 use openssl::bn::{BigNum, MsbOption};
46 use openssl::x509::X509NameBuilder;
47 use std::time::SystemTime;
48 use x509_cert::{certificate::Certificate, der::Decode};
49 
gen_key_including_unique_id(sl: &SecLevel, alias: &str) -> Option<Vec<u8>>50 fn gen_key_including_unique_id(sl: &SecLevel, alias: &str) -> Option<Vec<u8>> {
51     let gen_params = authorizations::AuthSetBuilder::new()
52         .no_auth_required()
53         .algorithm(Algorithm::EC)
54         .purpose(KeyPurpose::SIGN)
55         .purpose(KeyPurpose::VERIFY)
56         .digest(Digest::SHA_2_256)
57         .ec_curve(EcCurve::P_256)
58         .attestation_challenge(b"foo".to_vec())
59         .include_unique_id();
60 
61     let key_metadata =
62         key_generations::map_ks_error(key_generations::generate_key(sl, &gen_params, alias))
63             .unwrap()?;
64 
65     let unique_id = get_value_from_attest_record(
66         key_metadata.certificate.as_ref().unwrap(),
67         Tag::UNIQUE_ID,
68         key_metadata.keySecurityLevel,
69     )
70     .expect("Unique id not found.");
71     assert!(!unique_id.is_empty());
72     Some(unique_id)
73 }
74 
generate_key_and_perform_sign_verify_op_max_times( sl: &SecLevel, gen_params: &authorizations::AuthSetBuilder, alias: &str, max_usage_count: i32, ) -> binder::Result<Option<KeyMetadata>>75 fn generate_key_and_perform_sign_verify_op_max_times(
76     sl: &SecLevel,
77     gen_params: &authorizations::AuthSetBuilder,
78     alias: &str,
79     max_usage_count: i32,
80 ) -> binder::Result<Option<KeyMetadata>> {
81     let Some(key_metadata) = key_generations::generate_key(sl, gen_params, alias)? else {
82         return Ok(None);
83     };
84 
85     // Use above generated key `max_usage_count` times.
86     for _ in 0..max_usage_count {
87         perform_sample_asym_sign_verify_op(
88             &sl.binder,
89             &key_metadata,
90             None,
91             Some(Digest::SHA_2_256),
92         );
93     }
94 
95     Ok(Some(key_metadata))
96 }
97 
98 /// Generate a key with `USAGE_COUNT_LIMIT` and verify the key characteristics. Test should be able
99 /// to use the key successfully `max_usage_count` times. After exceeding key usage `max_usage_count`
100 /// times subsequent attempts to use the key in test should fail with response code `KEY_NOT_FOUND`.
101 /// Test should also verify that the attest record includes `USAGE_COUNT_LIMIT` for attested keys.
generate_key_and_perform_op_with_max_usage_limit( sl: &SecLevel, gen_params: &authorizations::AuthSetBuilder, alias: &str, max_usage_count: i32, check_attestation: bool, )102 fn generate_key_and_perform_op_with_max_usage_limit(
103     sl: &SecLevel,
104     gen_params: &authorizations::AuthSetBuilder,
105     alias: &str,
106     max_usage_count: i32,
107     check_attestation: bool,
108 ) {
109     // Generate a key and use the key for `max_usage_count` times.
110     let Some(key_metadata) =
111         generate_key_and_perform_sign_verify_op_max_times(sl, gen_params, alias, max_usage_count)
112             .unwrap()
113     else {
114         return;
115     };
116 
117     let auth = key_generations::get_key_auth(&key_metadata.authorizations, Tag::USAGE_COUNT_LIMIT)
118         .unwrap();
119     if check_attestation && sl.is_keymint() {
120         // Check usage-count-limit is included in attest-record.
121         // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
122         assert_ne!(
123             gen_params.iter().filter(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE).count(),
124             0,
125             "Attestation challenge is missing in generated key parameters."
126         );
127         let result = get_value_from_attest_record(
128             key_metadata.certificate.as_ref().unwrap(),
129             Tag::USAGE_COUNT_LIMIT,
130             auth.securityLevel,
131         )
132         .expect("Attest id verification failed.");
133         let usage_count: i32 = std::str::from_utf8(&result).unwrap().parse().unwrap();
134         assert_eq!(usage_count, max_usage_count);
135     }
136     if max_usage_count == 1 {
137         assert!(matches!(
138             auth.securityLevel,
139             SecurityLevel::KEYSTORE | SecurityLevel::TRUSTED_ENVIRONMENT
140         ));
141     } else {
142         assert_eq!(auth.securityLevel, SecurityLevel::KEYSTORE);
143     }
144 
145     // Try to use the key one more time.
146     let result = key_generations::map_ks_error(sl.binder.createOperation(
147         &key_metadata.key,
148         &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
149         false,
150     ));
151     assert!(result.is_err());
152     assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
153 }
154 
155 /// Generate a key with `ACTIVE_DATETIME` set to current time. Test should successfully generate
156 /// a key and verify the key characteristics. Test should be able to create a sign operation using
157 /// the generated key successfully.
158 #[test]
keystore2_gen_key_auth_active_datetime_test_success()159 fn keystore2_gen_key_auth_active_datetime_test_success() {
160     let sl = SecLevel::tee();
161 
162     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
163     let active_datetime = duration_since_epoch.as_millis();
164     let gen_params = authorizations::AuthSetBuilder::new()
165         .no_auth_required()
166         .algorithm(Algorithm::EC)
167         .purpose(KeyPurpose::SIGN)
168         .purpose(KeyPurpose::VERIFY)
169         .digest(Digest::SHA_2_256)
170         .ec_curve(EcCurve::P_256)
171         .active_date_time(active_datetime.try_into().unwrap());
172 
173     let alias = "ks_test_auth_tags_test";
174     let result = key_generations::create_key_and_operation(
175         &sl,
176         &gen_params,
177         &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
178         alias,
179     );
180     assert!(result.is_ok());
181     delete_app_key(&sl.keystore2, alias).unwrap();
182 }
183 
184 /// Generate a key with `ACTIVE_DATETIME` set to future date and time. Test should successfully
185 /// generate a key and verify the key characteristics. Try to create a sign operation
186 /// using the generated key, test should fail to create an operation with error code
187 /// `KEY_NOT_YET_VALID`.
188 #[test]
keystore2_gen_key_auth_future_active_datetime_test_op_fail()189 fn keystore2_gen_key_auth_future_active_datetime_test_op_fail() {
190     let sl = SecLevel::tee();
191 
192     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
193     let future_active_datetime = duration_since_epoch.as_millis() + (24 * 60 * 60 * 1000);
194     let gen_params = authorizations::AuthSetBuilder::new()
195         .no_auth_required()
196         .algorithm(Algorithm::EC)
197         .purpose(KeyPurpose::SIGN)
198         .purpose(KeyPurpose::VERIFY)
199         .digest(Digest::SHA_2_256)
200         .ec_curve(EcCurve::P_256)
201         .active_date_time(future_active_datetime.try_into().unwrap());
202 
203     let alias = "ks_test_auth_tags_test";
204     let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
205         &sl,
206         &gen_params,
207         &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
208         alias,
209     ));
210     assert!(result.is_err());
211     assert_eq!(Error::Km(ErrorCode::KEY_NOT_YET_VALID), result.unwrap_err());
212     delete_app_key(&sl.keystore2, alias).unwrap();
213 }
214 
215 /// Generate a key with `ORIGINATION_EXPIRE_DATETIME` set to future date and time. Test should
216 /// successfully generate a key and verify the key characteristics. Test should be able to create
217 /// sign operation using the generated key successfully.
218 #[test]
keystore2_gen_key_auth_future_origination_expire_datetime_test_success()219 fn keystore2_gen_key_auth_future_origination_expire_datetime_test_success() {
220     let sl = SecLevel::tee();
221 
222     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
223     let origination_expire_datetime = duration_since_epoch.as_millis() + (24 * 60 * 60 * 1000);
224     let gen_params = authorizations::AuthSetBuilder::new()
225         .no_auth_required()
226         .algorithm(Algorithm::EC)
227         .purpose(KeyPurpose::SIGN)
228         .purpose(KeyPurpose::VERIFY)
229         .digest(Digest::SHA_2_256)
230         .ec_curve(EcCurve::P_256)
231         .origination_expire_date_time(origination_expire_datetime.try_into().unwrap());
232 
233     let alias = "ks_test_auth_tags_test";
234     let result = key_generations::create_key_and_operation(
235         &sl,
236         &gen_params,
237         &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
238         alias,
239     );
240     assert!(result.is_ok());
241     delete_app_key(&sl.keystore2, alias).unwrap();
242 }
243 
244 /// Generate a key with `ORIGINATION_EXPIRE_DATETIME` set to current date and time. Test should
245 /// successfully generate a key and verify the key characteristics. Try to create a sign operation
246 /// using the generated key, test should fail to create an operation with error code
247 /// `KEY_EXPIRED`.
248 #[test]
keystore2_gen_key_auth_origination_expire_datetime_test_op_fail()249 fn keystore2_gen_key_auth_origination_expire_datetime_test_op_fail() {
250     let sl = SecLevel::tee();
251 
252     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
253     let origination_expire_datetime = duration_since_epoch.as_millis();
254     let gen_params = authorizations::AuthSetBuilder::new()
255         .no_auth_required()
256         .algorithm(Algorithm::EC)
257         .purpose(KeyPurpose::SIGN)
258         .purpose(KeyPurpose::VERIFY)
259         .digest(Digest::SHA_2_256)
260         .ec_curve(EcCurve::P_256)
261         .origination_expire_date_time(origination_expire_datetime.try_into().unwrap());
262 
263     let alias = "ks_test_auth_tags_test";
264     let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
265         &sl,
266         &gen_params,
267         &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
268         alias,
269     ));
270     assert!(result.is_err());
271     assert_eq!(Error::Km(ErrorCode::KEY_EXPIRED), result.unwrap_err());
272     delete_app_key(&sl.keystore2, alias).unwrap();
273 }
274 
275 /// Generate a HMAC key with `USAGE_EXPIRE_DATETIME` set to future date and time. Test should
276 /// successfully generate a key and verify the key characteristics. Test should be able to create
277 /// sign and verify operations using the generated key successfully.
278 #[test]
keystore2_gen_key_auth_future_usage_expire_datetime_hmac_verify_op_success()279 fn keystore2_gen_key_auth_future_usage_expire_datetime_hmac_verify_op_success() {
280     let sl = SecLevel::tee();
281 
282     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
283     let usage_expire_datetime = duration_since_epoch.as_millis() + (24 * 60 * 60 * 1000);
284     let gen_params = authorizations::AuthSetBuilder::new()
285         .no_auth_required()
286         .algorithm(Algorithm::HMAC)
287         .purpose(KeyPurpose::SIGN)
288         .purpose(KeyPurpose::VERIFY)
289         .key_size(128)
290         .min_mac_length(256)
291         .digest(Digest::SHA_2_256)
292         .usage_expire_date_time(usage_expire_datetime.try_into().unwrap());
293 
294     let alias = "ks_test_auth_tags_hmac_verify_success";
295     let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
296         return;
297     };
298 
299     perform_sample_hmac_sign_verify_op(&sl.binder, &key_metadata.key);
300     delete_app_key(&sl.keystore2, alias).unwrap();
301 }
302 
303 /// Generate a key with `USAGE_EXPIRE_DATETIME` set to current date and time. Test should
304 /// successfully generate a key and verify the key characteristics. Test should be able to create
305 /// sign operation successfully and fail while performing verify operation with error code
306 /// `KEY_EXPIRED`.
307 #[test]
keystore2_gen_key_auth_usage_expire_datetime_hmac_verify_op_fail()308 fn keystore2_gen_key_auth_usage_expire_datetime_hmac_verify_op_fail() {
309     let sl = SecLevel::tee();
310 
311     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
312     let usage_expire_datetime = duration_since_epoch.as_millis();
313     let gen_params = authorizations::AuthSetBuilder::new()
314         .no_auth_required()
315         .algorithm(Algorithm::HMAC)
316         .purpose(KeyPurpose::SIGN)
317         .purpose(KeyPurpose::VERIFY)
318         .key_size(128)
319         .min_mac_length(256)
320         .digest(Digest::SHA_2_256)
321         .usage_expire_date_time(usage_expire_datetime.try_into().unwrap());
322 
323     let alias = "ks_test_auth_tags_hamc_verify_fail";
324     let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
325         return;
326     };
327 
328     let result = key_generations::map_ks_error(
329         sl.binder.createOperation(
330             &key_metadata.key,
331             &authorizations::AuthSetBuilder::new()
332                 .purpose(KeyPurpose::VERIFY)
333                 .digest(Digest::SHA_2_256),
334             false,
335         ),
336     );
337     assert!(result.is_err());
338     assert_eq!(Error::Km(ErrorCode::KEY_EXPIRED), result.unwrap_err());
339     delete_app_key(&sl.keystore2, alias).unwrap();
340 }
341 
342 /// Generate AES key with `USAGE_EXPIRE_DATETIME` set to future date and time. Test should
343 /// successfully generate a key and verify the key characteristics. Test should be able to create
344 /// Encrypt and Decrypt operations successfully.
345 #[test]
keystore2_gen_key_auth_usage_future_expire_datetime_decrypt_op_success()346 fn keystore2_gen_key_auth_usage_future_expire_datetime_decrypt_op_success() {
347     let sl = SecLevel::tee();
348 
349     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
350     let usage_expire_datetime = duration_since_epoch.as_millis() + (24 * 60 * 60 * 1000);
351     let gen_params = authorizations::AuthSetBuilder::new()
352         .no_auth_required()
353         .algorithm(Algorithm::AES)
354         .purpose(KeyPurpose::ENCRYPT)
355         .purpose(KeyPurpose::DECRYPT)
356         .key_size(128)
357         .padding_mode(PaddingMode::PKCS7)
358         .block_mode(BlockMode::ECB)
359         .usage_expire_date_time(usage_expire_datetime.try_into().unwrap());
360 
361     let alias = "ks_test_auth_tags_test";
362     let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
363         return;
364     };
365     let cipher_text = perform_sample_sym_key_encrypt_op(
366         &sl.binder,
367         PaddingMode::PKCS7,
368         BlockMode::ECB,
369         &mut None,
370         None,
371         &key_metadata.key,
372     )
373     .unwrap();
374 
375     assert!(cipher_text.is_some());
376 
377     let plain_text = perform_sample_sym_key_decrypt_op(
378         &sl.binder,
379         &cipher_text.unwrap(),
380         PaddingMode::PKCS7,
381         BlockMode::ECB,
382         &mut None,
383         None,
384         &key_metadata.key,
385     )
386     .unwrap();
387     assert!(plain_text.is_some());
388     assert_eq!(plain_text.unwrap(), SAMPLE_PLAIN_TEXT.to_vec());
389     delete_app_key(&sl.keystore2, alias).unwrap();
390 }
391 
392 /// Generate AES key with `USAGE_EXPIRE_DATETIME` set to current date and time. Test should
393 /// successfully generate a key and verify the key characteristics. Test should be able to create
394 /// Encrypt operation successfully and fail while performing decrypt operation with error code
395 /// `KEY_EXPIRED`.
396 #[test]
keystore2_gen_key_auth_usage_expire_datetime_decrypt_op_fail()397 fn keystore2_gen_key_auth_usage_expire_datetime_decrypt_op_fail() {
398     let sl = SecLevel::tee();
399 
400     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
401     let usage_expire_datetime = duration_since_epoch.as_millis();
402     let gen_params = authorizations::AuthSetBuilder::new()
403         .no_auth_required()
404         .algorithm(Algorithm::AES)
405         .purpose(KeyPurpose::ENCRYPT)
406         .purpose(KeyPurpose::DECRYPT)
407         .key_size(128)
408         .padding_mode(PaddingMode::PKCS7)
409         .block_mode(BlockMode::ECB)
410         .usage_expire_date_time(usage_expire_datetime.try_into().unwrap());
411 
412     let alias = "ks_test_auth_tags_test";
413     let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
414         return;
415     };
416     let cipher_text = perform_sample_sym_key_encrypt_op(
417         &sl.binder,
418         PaddingMode::PKCS7,
419         BlockMode::ECB,
420         &mut None,
421         None,
422         &key_metadata.key,
423     )
424     .unwrap();
425 
426     assert!(cipher_text.is_some());
427 
428     let result = key_generations::map_ks_error(perform_sample_sym_key_decrypt_op(
429         &sl.binder,
430         &cipher_text.unwrap(),
431         PaddingMode::PKCS7,
432         BlockMode::ECB,
433         &mut None,
434         None,
435         &key_metadata.key,
436     ));
437     assert!(result.is_err());
438     assert_eq!(Error::Km(ErrorCode::KEY_EXPIRED), result.unwrap_err());
439     delete_app_key(&sl.keystore2, alias).unwrap();
440 }
441 
442 /// Generate a key with `EARLY_BOOT_ONLY`. Test should successfully generate
443 /// a key and verify the key characteristics. Test should fail with error code `EARLY_BOOT_ENDED`
444 /// during creation of an operation using this key.
445 #[test]
keystore2_gen_key_auth_early_boot_only_op_fail()446 fn keystore2_gen_key_auth_early_boot_only_op_fail() {
447     let sl = SecLevel::tee();
448     require_keymint!(sl);
449 
450     let gen_params = authorizations::AuthSetBuilder::new()
451         .no_auth_required()
452         .algorithm(Algorithm::EC)
453         .purpose(KeyPurpose::SIGN)
454         .purpose(KeyPurpose::VERIFY)
455         .digest(Digest::SHA_2_256)
456         .ec_curve(EcCurve::P_256)
457         .early_boot_only();
458 
459     let alias = "ks_test_auth_tags_test";
460     let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
461         &sl,
462         &gen_params,
463         &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
464         alias,
465     ));
466     assert!(result.is_err());
467     assert_eq!(Error::Km(ErrorCode::EARLY_BOOT_ENDED), result.unwrap_err());
468     delete_app_key(&sl.keystore2, alias).unwrap();
469 }
470 
471 /// Generate a key with `MAX_USES_PER_BOOT`. Test should successfully generate
472 /// a key and verify the key characteristics. Test should be able to use the key successfully
473 /// `MAX_USES_COUNT` times. After exceeding key usage `MAX_USES_COUNT` times
474 /// subsequent attempts to use the key in test should fail with error code MAX_OPS_EXCEEDED.
475 #[test]
keystore2_gen_key_auth_max_uses_per_boot()476 fn keystore2_gen_key_auth_max_uses_per_boot() {
477     let sl = SecLevel::tee();
478     if sl.is_keymaster() {
479         // Older devices with Keymaster implementation may use the key during generateKey to export
480         // the generated public key (EC Key), leading to an unnecessary increment of the
481         // key-associated counter. This can cause the test to fail, so skipping this test on older
482         // devices to avoid test failure.
483         return;
484     }
485     const MAX_USES_COUNT: i32 = 3;
486 
487     let gen_params = authorizations::AuthSetBuilder::new()
488         .no_auth_required()
489         .algorithm(Algorithm::EC)
490         .purpose(KeyPurpose::SIGN)
491         .purpose(KeyPurpose::VERIFY)
492         .digest(Digest::SHA_2_256)
493         .ec_curve(EcCurve::P_256)
494         .max_uses_per_boot(MAX_USES_COUNT);
495 
496     let alias = "ks_test_auth_tags_test";
497     // Generate a key and use the key for `MAX_USES_COUNT` times.
498     let Some(key_metadata) =
499         generate_key_and_perform_sign_verify_op_max_times(&sl, &gen_params, alias, MAX_USES_COUNT)
500             .unwrap()
501     else {
502         return;
503     };
504 
505     // Try to use the key one more time.
506     let result = key_generations::map_ks_error(sl.binder.createOperation(
507         &key_metadata.key,
508         &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
509         false,
510     ));
511     assert!(result.is_err());
512     assert_eq!(Error::Km(ErrorCode::KEY_MAX_OPS_EXCEEDED), result.unwrap_err());
513     delete_app_key(&sl.keystore2, alias).unwrap();
514 }
515 
516 /// Generate a key with `USAGE_COUNT_LIMIT`. Test should successfully generate
517 /// a key and verify the key characteristics. Test should be able to use the key successfully
518 /// `MAX_USES_COUNT` times. After exceeding key usage `MAX_USES_COUNT` times
519 /// subsequent attempts to use the key in test should fail with response code `KEY_NOT_FOUND`.
520 /// Test should also verify that the attest record includes `USAGE_COUNT_LIMIT`.
521 #[test]
keystore2_gen_key_auth_usage_count_limit()522 fn keystore2_gen_key_auth_usage_count_limit() {
523     let sl = SecLevel::tee();
524     if sl.is_keymaster() {
525         // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
526         return;
527     }
528     const MAX_USES_COUNT: i32 = 3;
529 
530     let gen_params = authorizations::AuthSetBuilder::new()
531         .no_auth_required()
532         .algorithm(Algorithm::EC)
533         .purpose(KeyPurpose::SIGN)
534         .purpose(KeyPurpose::VERIFY)
535         .digest(Digest::SHA_2_256)
536         .ec_curve(EcCurve::P_256)
537         .attestation_challenge(b"foo".to_vec())
538         .usage_count_limit(MAX_USES_COUNT);
539 
540     let alias = "ks_test_auth_tags_test";
541     generate_key_and_perform_op_with_max_usage_limit(&sl, &gen_params, alias, MAX_USES_COUNT, true);
542 }
543 
544 /// Generate a key with `USAGE_COUNT_LIMIT`. Test should successfully generate
545 /// a key and verify the key characteristics. Test should be able to use the key successfully
546 /// `MAX_USES_COUNT` times. After exceeding key usage `MAX_USES_COUNT` times
547 /// subsequent attempts to use the key in test should fail with response code `KEY_NOT_FOUND`.
548 /// Test should also verify that the attest record includes `USAGE_COUNT_LIMIT`.
549 #[test]
keystore2_gen_key_auth_usage_count_limit_one()550 fn keystore2_gen_key_auth_usage_count_limit_one() {
551     let sl = SecLevel::tee();
552     if sl.is_keymaster() {
553         // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
554         return;
555     }
556     const MAX_USES_COUNT: i32 = 1;
557 
558     let gen_params = authorizations::AuthSetBuilder::new()
559         .no_auth_required()
560         .algorithm(Algorithm::EC)
561         .purpose(KeyPurpose::SIGN)
562         .purpose(KeyPurpose::VERIFY)
563         .digest(Digest::SHA_2_256)
564         .ec_curve(EcCurve::P_256)
565         .attestation_challenge(b"foo".to_vec())
566         .usage_count_limit(MAX_USES_COUNT);
567 
568     let alias = "ks_test_auth_tags_test";
569     generate_key_and_perform_op_with_max_usage_limit(&sl, &gen_params, alias, MAX_USES_COUNT, true);
570 }
571 
572 /// Generate a non-attested key with `USAGE_COUNT_LIMIT`. Test should successfully generate
573 /// a key and verify the key characteristics. Test should be able to use the key successfully
574 /// `MAX_USES_COUNT` times. After exceeding key usage `MAX_USES_COUNT` times
575 /// subsequent attempts to use the key in test should fail with response code `KEY_NOT_FOUND`.
576 #[test]
keystore2_gen_non_attested_key_auth_usage_count_limit()577 fn keystore2_gen_non_attested_key_auth_usage_count_limit() {
578     let sl = SecLevel::tee();
579     if sl.is_keymaster() {
580         // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
581         return;
582     }
583     const MAX_USES_COUNT: i32 = 2;
584 
585     let gen_params = authorizations::AuthSetBuilder::new()
586         .no_auth_required()
587         .algorithm(Algorithm::EC)
588         .purpose(KeyPurpose::SIGN)
589         .purpose(KeyPurpose::VERIFY)
590         .digest(Digest::SHA_2_256)
591         .ec_curve(EcCurve::P_256)
592         .usage_count_limit(MAX_USES_COUNT);
593 
594     let alias = "ks_test_auth_tags_test";
595     generate_key_and_perform_op_with_max_usage_limit(
596         &sl,
597         &gen_params,
598         alias,
599         MAX_USES_COUNT,
600         false,
601     );
602 }
603 
604 /// Try to generate a key with `Tag::CREATION_DATETIME` set to valid value. Test should fail
605 /// to generate a key with `INVALID_ARGUMENT` error as Keystore2 backend doesn't allow user to
606 /// specify `CREATION_DATETIME`.
607 #[test]
keystore2_gen_key_auth_creation_date_time_test_fail_with_invalid_arg_error()608 fn keystore2_gen_key_auth_creation_date_time_test_fail_with_invalid_arg_error() {
609     let sl = SecLevel::tee();
610 
611     let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
612     let creation_datetime = duration_since_epoch.as_millis();
613     let gen_params = authorizations::AuthSetBuilder::new()
614         .no_auth_required()
615         .algorithm(Algorithm::EC)
616         .purpose(KeyPurpose::SIGN)
617         .purpose(KeyPurpose::VERIFY)
618         .digest(Digest::SHA_2_256)
619         .ec_curve(EcCurve::P_256)
620         .creation_date_time(creation_datetime.try_into().unwrap());
621 
622     let alias = "ks_test_auth_tags_test";
623     let result = key_generations::map_ks_error(sl.binder.generateKey(
624         &KeyDescriptor {
625             domain: Domain::APP,
626             nspace: -1,
627             alias: Some(alias.to_string()),
628             blob: None,
629         },
630         None,
631         &gen_params,
632         0,
633         b"entropy",
634     ));
635 
636     assert!(result.is_err());
637     assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
638 }
639 
640 /// Generate a key with `Tag::INCLUDE_UNIQUE_ID` set. Test should verify that `Tag::UNIQUE_ID` is
641 /// included in attest record and it remains the same for new keys generated.
642 #[test]
keystore2_gen_key_auth_include_unique_id_success()643 fn keystore2_gen_key_auth_include_unique_id_success() {
644     let sl = SecLevel::tee();
645     if sl.is_keymaster() {
646         // b/387208956 - Some older devices with Keymaster implementations fail to generate an
647         // attestation key with `INCLUDE_UNIQUE_ID`, but this was not previously tested. Skip this
648         // test on devices with Keymaster implementation.
649         return;
650     }
651 
652     let alias_first = "ks_test_auth_tags_test_1";
653     if let Some(unique_id_first) = gen_key_including_unique_id(&sl, alias_first) {
654         let alias_second = "ks_test_auth_tags_test_2";
655         let unique_id_second = gen_key_including_unique_id(&sl, alias_second).unwrap();
656 
657         assert_eq!(unique_id_first, unique_id_second);
658 
659         delete_app_key(&sl.keystore2, alias_first).unwrap();
660         delete_app_key(&sl.keystore2, alias_second).unwrap();
661     }
662 }
663 
664 /// Generate a key with `APPLICATION_DATA` and `APPLICATION_ID`. Test should create an operation
665 /// successfully using the same `APPLICATION_DATA` and `APPLICATION_ID`.
666 #[test]
keystore2_gen_key_auth_app_data_app_id_test_success()667 fn keystore2_gen_key_auth_app_data_app_id_test_success() {
668     let sl = SecLevel::tee();
669     if sl.is_keymaster() && get_vsr_api_level() < 35 {
670         // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
671         // test to run on older devices.
672         return;
673     }
674 
675     let gen_params = authorizations::AuthSetBuilder::new()
676         .no_auth_required()
677         .algorithm(Algorithm::EC)
678         .purpose(KeyPurpose::SIGN)
679         .purpose(KeyPurpose::VERIFY)
680         .digest(Digest::NONE)
681         .ec_curve(EcCurve::P_256)
682         .app_data(b"app-data".to_vec())
683         .app_id(b"app-id".to_vec());
684 
685     let alias = "ks_test_auth_tags_test";
686     let result = key_generations::create_key_and_operation(
687         &sl,
688         &gen_params,
689         &authorizations::AuthSetBuilder::new()
690             .purpose(KeyPurpose::SIGN)
691             .digest(Digest::NONE)
692             .app_data(b"app-data".to_vec())
693             .app_id(b"app-id".to_vec()),
694         alias,
695     );
696     assert!(result.is_ok());
697     delete_app_key(&sl.keystore2, alias).unwrap();
698 }
699 
700 /// Generate a key with `APPLICATION_DATA` and `APPLICATION_ID`. Try to create an operation using
701 /// the different `APPLICATION_DATA` and `APPLICATION_ID`, test should fail to create an operation.
702 #[test]
keystore2_op_auth_invalid_app_data_app_id_test_fail()703 fn keystore2_op_auth_invalid_app_data_app_id_test_fail() {
704     let sl = SecLevel::tee();
705     if sl.is_keymaster() && get_vsr_api_level() < 35 {
706         // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
707         // test to run on older devices.
708         return;
709     }
710 
711     let gen_params = authorizations::AuthSetBuilder::new()
712         .no_auth_required()
713         .algorithm(Algorithm::EC)
714         .purpose(KeyPurpose::SIGN)
715         .purpose(KeyPurpose::VERIFY)
716         .digest(Digest::NONE)
717         .ec_curve(EcCurve::P_256)
718         .app_data(b"app-data".to_vec())
719         .app_id(b"app-id".to_vec());
720 
721     let alias = "ks_test_auth_tags_test";
722     let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
723         &sl,
724         &gen_params,
725         &authorizations::AuthSetBuilder::new()
726             .purpose(KeyPurpose::SIGN)
727             .digest(Digest::NONE)
728             .app_data(b"invalid-app-data".to_vec())
729             .app_id(b"invalid-app-id".to_vec()),
730         alias,
731     ));
732     assert!(result.is_err());
733     assert_eq!(Error::Km(ErrorCode::INVALID_KEY_BLOB), result.unwrap_err());
734     delete_app_key(&sl.keystore2, alias).unwrap();
735 }
736 
737 /// Generate a key with `APPLICATION_DATA` and `APPLICATION_ID`. Try to create an operation using
738 /// only `APPLICATION_ID`, test should fail to create an operation.
739 #[test]
keystore2_op_auth_missing_app_data_test_fail()740 fn keystore2_op_auth_missing_app_data_test_fail() {
741     let sl = SecLevel::tee();
742     if sl.is_keymaster() && get_vsr_api_level() < 35 {
743         // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
744         // test to run on older devices.
745         return;
746     }
747 
748     let gen_params = authorizations::AuthSetBuilder::new()
749         .no_auth_required()
750         .algorithm(Algorithm::EC)
751         .purpose(KeyPurpose::SIGN)
752         .purpose(KeyPurpose::VERIFY)
753         .digest(Digest::NONE)
754         .ec_curve(EcCurve::P_256)
755         .app_id(b"app-id".to_vec())
756         .app_data(b"app-data".to_vec());
757 
758     let alias = "ks_test_auth_tags_test";
759     let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
760         &sl,
761         &gen_params,
762         &authorizations::AuthSetBuilder::new()
763             .purpose(KeyPurpose::SIGN)
764             .digest(Digest::NONE)
765             .app_id(b"app-id".to_vec()),
766         alias,
767     ));
768 
769     assert!(result.is_err());
770     assert_eq!(Error::Km(ErrorCode::INVALID_KEY_BLOB), result.unwrap_err());
771     delete_app_key(&sl.keystore2, alias).unwrap();
772 }
773 
774 /// Generate a key with `APPLICATION_DATA` and `APPLICATION_ID`. Try to create an operation using
775 /// only `APPLICATION_DATA`, test should fail to create an operation.
776 #[test]
keystore2_op_auth_missing_app_id_test_fail()777 fn keystore2_op_auth_missing_app_id_test_fail() {
778     let sl = SecLevel::tee();
779     if sl.is_keymaster() && get_vsr_api_level() < 35 {
780         // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
781         // test to run on older devices.
782         return;
783     }
784 
785     let gen_params = authorizations::AuthSetBuilder::new()
786         .no_auth_required()
787         .algorithm(Algorithm::EC)
788         .purpose(KeyPurpose::SIGN)
789         .purpose(KeyPurpose::VERIFY)
790         .digest(Digest::NONE)
791         .ec_curve(EcCurve::P_256)
792         .app_data(b"app-data".to_vec())
793         .app_id(b"app-id".to_vec());
794 
795     let alias = "ks_test_auth_tags_test";
796     let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
797         &sl,
798         &gen_params,
799         &authorizations::AuthSetBuilder::new()
800             .purpose(KeyPurpose::SIGN)
801             .digest(Digest::NONE)
802             .app_data(b"app-data".to_vec()),
803         alias,
804     ));
805     assert!(result.is_err());
806     assert_eq!(Error::Km(ErrorCode::INVALID_KEY_BLOB), result.unwrap_err());
807     delete_app_key(&sl.keystore2, alias).unwrap();
808 }
809 
810 /// Generate an attestation-key without specifying `APPLICATION_ID` and `APPLICATION_DATA`.
811 /// Test should be able to generate a new key with specifying app-id and app-data using previously
812 /// generated attestation-key.
813 #[test]
keystore2_gen_attested_key_auth_app_id_app_data_test_success()814 fn keystore2_gen_attested_key_auth_app_id_app_data_test_success() {
815     skip_test_if_no_app_attest_key_feature!();
816     let sl = SecLevel::tee();
817     if sl.is_keymaster() && get_vsr_api_level() < 35 {
818         // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
819         // test to run on older devices.
820         return;
821     }
822 
823     // Generate attestation key.
824     let attest_gen_params = authorizations::AuthSetBuilder::new()
825         .no_auth_required()
826         .algorithm(Algorithm::EC)
827         .purpose(KeyPurpose::ATTEST_KEY)
828         .digest(Digest::SHA_2_256)
829         .ec_curve(EcCurve::P_256)
830         .attestation_challenge(b"foo".to_vec());
831     let attest_alias = "ks_test_auth_tags_attest_key";
832     let Some(attest_key_metadata) =
833         key_generations::generate_key(&sl, &attest_gen_params, attest_alias).unwrap()
834     else {
835         return;
836     };
837 
838     // Generate attested key.
839     let alias = "ks_test_auth_tags_attested_key";
840     let gen_params = authorizations::AuthSetBuilder::new()
841         .no_auth_required()
842         .algorithm(Algorithm::EC)
843         .purpose(KeyPurpose::SIGN)
844         .purpose(KeyPurpose::VERIFY)
845         .digest(Digest::SHA_2_256)
846         .ec_curve(EcCurve::P_256)
847         .attestation_challenge(b"bar".to_vec())
848         .app_id(b"app-id".to_vec())
849         .app_data(b"app-data".to_vec());
850 
851     let result = sl.binder.generateKey(
852         &KeyDescriptor {
853             domain: Domain::APP,
854             nspace: -1,
855             alias: Some(alias.to_string()),
856             blob: None,
857         },
858         Some(&attest_key_metadata.key),
859         &gen_params,
860         0,
861         b"entropy",
862     );
863 
864     assert!(result.is_ok());
865     delete_app_key(&sl.keystore2, alias).unwrap();
866     delete_app_key(&sl.keystore2, attest_alias).unwrap();
867 }
868 
869 /// Generate an attestation-key with specifying `APPLICATION_ID` and `APPLICATION_DATA`.
870 /// Test should try to generate an attested key using previously generated attestation-key without
871 /// specifying app-id and app-data. Test should fail to generate a new key.
872 /// It is an oversight of the Keystore API that `APPLICATION_ID` and `APPLICATION_DATA` tags cannot
873 /// be provided to generateKey for an attestation key that was generated with them.
874 #[test]
keystore2_gen_attestation_key_with_auth_app_id_app_data_test_fail()875 fn keystore2_gen_attestation_key_with_auth_app_id_app_data_test_fail() {
876     skip_test_if_no_app_attest_key_feature!();
877     let sl = SecLevel::tee();
878     if sl.is_keymaster() && get_vsr_api_level() < 35 {
879         // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
880         // test to run on older devices.
881         return;
882     }
883 
884     // Generate attestation key.
885     let attest_gen_params = authorizations::AuthSetBuilder::new()
886         .no_auth_required()
887         .algorithm(Algorithm::EC)
888         .purpose(KeyPurpose::ATTEST_KEY)
889         .digest(Digest::SHA_2_256)
890         .ec_curve(EcCurve::P_256)
891         .attestation_challenge(b"foo".to_vec())
892         .app_id(b"app-id".to_vec())
893         .app_data(b"app-data".to_vec());
894     let attest_alias = "ks_test_auth_tags_attest_key";
895     let Some(attest_key_metadata) =
896         key_generations::generate_key(&sl, &attest_gen_params, attest_alias).unwrap()
897     else {
898         return;
899     };
900 
901     // Generate new key using above generated attestation key without providing app-id and app-data.
902     let alias = "ks_test_auth_tags_attested_key";
903     let gen_params = authorizations::AuthSetBuilder::new()
904         .no_auth_required()
905         .algorithm(Algorithm::EC)
906         .purpose(KeyPurpose::SIGN)
907         .purpose(KeyPurpose::VERIFY)
908         .digest(Digest::SHA_2_256)
909         .ec_curve(EcCurve::P_256)
910         .attestation_challenge(b"foo".to_vec());
911 
912     let result = key_generations::map_ks_error(sl.binder.generateKey(
913         &KeyDescriptor {
914             domain: Domain::APP,
915             nspace: -1,
916             alias: Some(alias.to_string()),
917             blob: None,
918         },
919         Some(&attest_key_metadata.key),
920         &gen_params,
921         0,
922         b"entropy",
923     ));
924 
925     assert!(result.is_err());
926     assert_eq!(Error::Km(ErrorCode::INVALID_KEY_BLOB), result.unwrap_err());
927     delete_app_key(&sl.keystore2, attest_alias).unwrap();
928 }
929 
add_hardware_token(auth_type: HardwareAuthenticatorType)930 fn add_hardware_token(auth_type: HardwareAuthenticatorType) {
931     let keystore_auth = get_keystore_auth_service();
932 
933     let token = HardwareAuthToken {
934         challenge: 0,
935         userId: 0,
936         authenticatorId: 0,
937         authenticatorType: auth_type,
938         timestamp: Timestamp { milliSeconds: 500 },
939         mac: vec![],
940     };
941     keystore_auth.addAuthToken(&token).unwrap();
942 }
943 
944 #[test]
keystore2_get_last_auth_password_success()945 fn keystore2_get_last_auth_password_success() {
946     let keystore_auth = get_keystore_auth_service();
947 
948     add_hardware_token(HardwareAuthenticatorType::PASSWORD);
949     assert!(keystore_auth.getLastAuthTime(0, &[HardwareAuthenticatorType::PASSWORD]).unwrap() > 0);
950 }
951 
952 #[test]
keystore2_get_last_auth_fingerprint_success()953 fn keystore2_get_last_auth_fingerprint_success() {
954     let keystore_auth = get_keystore_auth_service();
955 
956     add_hardware_token(HardwareAuthenticatorType::FINGERPRINT);
957     assert!(
958         keystore_auth.getLastAuthTime(0, &[HardwareAuthenticatorType::FINGERPRINT]).unwrap() > 0
959     );
960 }
961 
962 /// Generate a key with specifying `CERTIFICATE_SUBJECT and CERTIFICATE_SERIAL`. Test should
963 /// generate a key successfully and verify the specified key parameters.
964 #[test]
keystore2_gen_key_auth_serial_number_subject_test_success()965 fn keystore2_gen_key_auth_serial_number_subject_test_success() {
966     let sl = SecLevel::tee();
967     require_keymint!(sl);
968 
969     let cert_subject = "test cert subject";
970     let mut x509_name = X509NameBuilder::new().unwrap();
971     x509_name.append_entry_by_text("CN", cert_subject).unwrap();
972     let x509_name = x509_name.build().to_der().unwrap();
973 
974     let mut serial = BigNum::new().unwrap();
975     serial.rand(159, MsbOption::MAYBE_ZERO, false).unwrap();
976 
977     let gen_params = authorizations::AuthSetBuilder::new()
978         .no_auth_required()
979         .algorithm(Algorithm::EC)
980         .purpose(KeyPurpose::SIGN)
981         .purpose(KeyPurpose::VERIFY)
982         .digest(Digest::SHA_2_256)
983         .ec_curve(EcCurve::P_256)
984         .cert_subject_name(x509_name)
985         .cert_serial(serial.to_vec());
986 
987     let alias = "ks_test_auth_tags_test";
988     let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
989         return;
990     };
991     verify_certificate_subject_name(
992         key_metadata.certificate.as_ref().unwrap(),
993         cert_subject.as_bytes(),
994     );
995     verify_certificate_serial_num(key_metadata.certificate.as_ref().unwrap(), &serial);
996     delete_app_key(&sl.keystore2, alias).unwrap();
997 }
998 
999 #[test]
test_supplementary_attestation_info()1000 fn test_supplementary_attestation_info() {
1001     if !keystore2_flags::attest_modules() {
1002         // Module info is only populated if the flag is set.
1003         return;
1004     }
1005 
1006     // Test should not run before MODULE_HASH supplementary info is populated.
1007     assert!(rustutils::system_properties::read_bool("keystore.module_hash.sent", false)
1008         .unwrap_or(false));
1009 
1010     let sl = SecLevel::tee();
1011 
1012     // Retrieve the input value that gets hashed into the attestation.
1013     let module_info = sl
1014         .keystore2
1015         .getSupplementaryAttestationInfo(Tag::MODULE_HASH)
1016         .expect("supplementary info for MODULE_HASH should be populated during startup");
1017     let again = sl.keystore2.getSupplementaryAttestationInfo(Tag::MODULE_HASH).unwrap();
1018     assert_eq!(again, module_info);
1019     let want_hash = digest::Sha256::hash(&module_info).to_vec();
1020 
1021     // Requesting other types of information should fail.
1022     let result = key_generations::map_ks_error(
1023         sl.keystore2.getSupplementaryAttestationInfo(Tag::BLOCK_MODE),
1024     );
1025     assert!(result.is_err());
1026     assert_eq!(result.unwrap_err(), Error::Rc(ResponseCode::INVALID_ARGUMENT));
1027 
1028     if sl.get_keymint_version() < 400 {
1029         // Module hash will only be populated in KeyMint if the underlying device is KeyMint V4+.
1030         return;
1031     }
1032 
1033     // Generate an attestation.
1034     let alias = "ks_module_info_test";
1035     let params = authorizations::AuthSetBuilder::new()
1036         .no_auth_required()
1037         .algorithm(Algorithm::EC)
1038         .purpose(KeyPurpose::SIGN)
1039         .purpose(KeyPurpose::VERIFY)
1040         .digest(Digest::SHA_2_256)
1041         .ec_curve(EcCurve::P_256)
1042         .attestation_challenge(b"froop".to_vec());
1043     let metadata = key_generations::generate_key(&sl, &params, alias)
1044         .expect("failed key generation")
1045         .expect("no metadata");
1046     let cert_data = metadata.certificate.as_ref().unwrap();
1047     let cert = Certificate::from_der(cert_data).expect("failed to parse X509 cert");
1048     let exts = cert.tbs_certificate.extensions.expect("no X.509 extensions");
1049     let ext = exts
1050         .iter()
1051         .find(|ext| ext.extn_id == ATTESTATION_EXTENSION_OID)
1052         .expect("no attestation extension");
1053     let ext = AttestationExtension::from_der(ext.extn_value.as_bytes())
1054         .expect("failed to parse attestation extension");
1055 
1056     // Find the attested module hash value.
1057     let mut got_hash = None;
1058     for auth in ext.sw_enforced.auths.into_owned().iter() {
1059         if let KeyParameter { tag: Tag::MODULE_HASH, value: KeyParameterValue::Blob(hash) } = auth {
1060             got_hash = Some(hash.clone());
1061         }
1062     }
1063     let got_hash = got_hash.expect("no MODULE_HASH in sw_enforced");
1064     assert_eq!(hex::encode(got_hash), hex::encode(want_hash));
1065 }
1066