blob: 13f77607313d0935af584f42fa531331f1279e57 [file] [log] [blame]
Joel Galensonde386b42020-09-30 10:53:05 -07001// Copyright 2020, 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
Paul Crowleyd5653e52021-03-25 09:46:31 -070015//! Export into Rust a function to create a KeyMintDevice and add it as a service.
Joel Galensonde386b42020-09-30 10:53:05 -070016
Paul Crowleyd5653e52021-03-25 09:46:31 -070017#[allow(missing_docs)] // TODO remove this
Joel Galensonde386b42020-09-30 10:53:05 -070018extern "C" {
19 fn addKeyMintDeviceService() -> i32;
20}
21
Paul Crowleyd5653e52021-03-25 09:46:31 -070022#[allow(missing_docs)] // TODO remove this
Joel Galensonde386b42020-09-30 10:53:05 -070023pub fn add_keymint_device_service() -> i32 {
24 unsafe { addKeyMintDeviceService() }
25}
26
27#[cfg(test)]
28mod tests {
29
30 use super::*;
31 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Shawn Willdendbdac602021-01-12 22:35:16 -070032 Algorithm::Algorithm, BeginResult::BeginResult, BlockMode::BlockMode, Digest::Digest,
David Drysdalef5c1ab02021-04-19 19:08:14 +010033 ErrorCode::ErrorCode, IKeyMintDevice::IKeyMintDevice, KeyCreationResult::KeyCreationResult,
Janis Danisevskis67f30562021-05-21 13:20:22 -070034 KeyFormat::KeyFormat, KeyOrigin::KeyOrigin, KeyParameter::KeyParameter,
35 KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
36 SecurityLevel::SecurityLevel, Tag::Tag,
Joel Galensonde386b42020-09-30 10:53:05 -070037 };
Stephen Crane221bbb52020-12-16 15:52:10 -080038 use android_hardware_security_keymint::binder::{self, Strong};
Joel Galensonde386b42020-09-30 10:53:05 -070039 use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
40
Joel Galensonf21c0022020-12-11 14:37:52 -080041 static COMPAT_NAME: &str = "android.security.compat";
42
Stephen Crane221bbb52020-12-16 15:52:10 -080043 fn get_device() -> Option<Strong<dyn IKeyMintDevice>> {
Joel Galensonde386b42020-09-30 10:53:05 -070044 add_keymint_device_service();
Stephen Crane221bbb52020-12-16 15:52:10 -080045 let compat_service: Strong<dyn IKeystoreCompatService> =
Janis Danisevskis12913842021-02-01 13:49:25 -080046 binder::get_interface(COMPAT_NAME).ok()?;
47 compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).ok()
48 }
49
50 macro_rules! get_device_or_skip_test {
51 () => {
52 match get_device() {
53 Some(dev) => dev,
54 None => return,
55 }
56 };
Joel Galensonde386b42020-09-30 10:53:05 -070057 }
58
59 #[test]
60 fn test_get_hardware_info() {
Janis Danisevskis12913842021-02-01 13:49:25 -080061 let legacy = get_device_or_skip_test!();
Joel Galensond4dbfd52021-01-25 09:45:33 -080062 let hinfo = legacy.getHardwareInfo();
63 assert!(hinfo.is_ok());
Joel Galensonde386b42020-09-30 10:53:05 -070064 }
65
66 #[test]
Joel Galensonde386b42020-09-30 10:53:05 -070067 fn test_add_rng_entropy() {
Janis Danisevskis12913842021-02-01 13:49:25 -080068 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -070069 let result = legacy.addRngEntropy(&[42; 16]);
70 assert!(result.is_ok(), "{:?}", result);
71 }
72
73 // TODO: If I only need the key itself, don't return the other things.
Shawn Willdendbdac602021-01-12 22:35:16 -070074 fn generate_key(legacy: &dyn IKeyMintDevice, kps: Vec<KeyParameter>) -> KeyCreationResult {
Shawn Willdenc2f3acf2021-02-03 07:07:17 -070075 let creation_result =
76 legacy.generateKey(&kps, None /* attest_key */).expect("Failed to generate key");
Shawn Willdendbdac602021-01-12 22:35:16 -070077 assert_ne!(creation_result.keyBlob.len(), 0);
78 creation_result
Joel Galensonde386b42020-09-30 10:53:05 -070079 }
80
Janis Danisevskis2c084012021-01-31 22:23:17 -080081 // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to GeneralizedTime
82 // 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
83 const UNDEFINED_NOT_AFTER: i64 = 253402300799000i64;
84
Joel Galensonde386b42020-09-30 10:53:05 -070085 fn generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8> {
86 let mut kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -080087 KeyParameter {
88 tag: Tag::ALGORITHM,
89 value: KeyParameterValue::Algorithm(Algorithm::RSA),
90 },
91 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) },
Joel Galensonde386b42020-09-30 10:53:05 -070092 KeyParameter {
93 tag: Tag::RSA_PUBLIC_EXPONENT,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080094 value: KeyParameterValue::LongInteger(65537),
Joel Galensonde386b42020-09-30 10:53:05 -070095 },
Janis Danisevskisb60c0042020-12-17 00:11:21 -080096 KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) },
Joel Galensonde386b42020-09-30 10:53:05 -070097 KeyParameter {
98 tag: Tag::PADDING,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080099 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
Joel Galensonde386b42020-09-30 10:53:05 -0700100 },
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800101 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
102 KeyParameter {
103 tag: Tag::PURPOSE,
104 value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
105 },
Janis Danisevskis2c084012021-01-31 22:23:17 -0800106 KeyParameter {
107 tag: Tag::CERTIFICATE_NOT_BEFORE,
108 value: KeyParameterValue::DateTime(0),
109 },
110 KeyParameter {
111 tag: Tag::CERTIFICATE_NOT_AFTER,
112 value: KeyParameterValue::DateTime(UNDEFINED_NOT_AFTER),
113 },
Joel Galensonde386b42020-09-30 10:53:05 -0700114 ];
115 if encrypt {
116 kps.push(KeyParameter {
117 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800118 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700119 });
120 }
121 if attest {
122 kps.push(KeyParameter {
123 tag: Tag::ATTESTATION_CHALLENGE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800124 value: KeyParameterValue::Blob(vec![42; 8]),
Joel Galensonde386b42020-09-30 10:53:05 -0700125 });
126 kps.push(KeyParameter {
127 tag: Tag::ATTESTATION_APPLICATION_ID,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800128 value: KeyParameterValue::Blob(vec![42; 8]),
Joel Galensonde386b42020-09-30 10:53:05 -0700129 });
130 }
Shawn Willdendbdac602021-01-12 22:35:16 -0700131 let creation_result = generate_key(legacy, kps);
Joel Galensonde386b42020-09-30 10:53:05 -0700132 if attest {
133 // TODO: Will this always be greater than 1?
Shawn Willdendbdac602021-01-12 22:35:16 -0700134 assert!(creation_result.certificateChain.len() > 1);
Joel Galensonde386b42020-09-30 10:53:05 -0700135 } else {
Shawn Willdendbdac602021-01-12 22:35:16 -0700136 assert_eq!(creation_result.certificateChain.len(), 1);
Joel Galensonde386b42020-09-30 10:53:05 -0700137 }
Shawn Willdendbdac602021-01-12 22:35:16 -0700138 creation_result.keyBlob
Joel Galensonde386b42020-09-30 10:53:05 -0700139 }
140
141 #[test]
142 fn test_generate_key_no_encrypt() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800143 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700144 generate_rsa_key(legacy.as_ref(), false, false);
145 }
146
147 #[test]
148 fn test_generate_key_encrypt() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800149 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700150 generate_rsa_key(legacy.as_ref(), true, false);
151 }
152
153 #[test]
154 fn test_generate_key_attested() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800155 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700156 generate_rsa_key(legacy.as_ref(), false, true);
157 }
158
159 #[test]
160 fn test_import_key() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800161 let legacy = get_device_or_skip_test!();
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800162 let kps = [KeyParameter {
163 tag: Tag::ALGORITHM,
164 value: KeyParameterValue::Algorithm(Algorithm::AES),
165 }];
Joel Galensonde386b42020-09-30 10:53:05 -0700166 let kf = KeyFormat::RAW;
167 let kd = [0; 16];
Shawn Willdenc2f3acf2021-02-03 07:07:17 -0700168 let creation_result =
169 legacy.importKey(&kps, kf, &kd, None /* attest_key */).expect("Failed to import key");
Shawn Willdendbdac602021-01-12 22:35:16 -0700170 assert_ne!(creation_result.keyBlob.len(), 0);
171 assert_eq!(creation_result.certificateChain.len(), 0);
Joel Galensonde386b42020-09-30 10:53:05 -0700172 }
173
174 #[test]
175 fn test_import_wrapped_key() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800176 let legacy = get_device_or_skip_test!();
Shawn Willdendbdac602021-01-12 22:35:16 -0700177 let result = legacy.importWrappedKey(&[], &[], &[], &[], 0, 0);
Joel Galensond4dbfd52021-01-25 09:45:33 -0800178 // For this test we only care that there was no crash.
179 assert!(result.is_ok() || result.is_err());
Joel Galensonde386b42020-09-30 10:53:05 -0700180 }
181
182 #[test]
183 fn test_upgrade_key() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800184 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700185 let blob = generate_rsa_key(legacy.as_ref(), false, false);
186 let result = legacy.upgradeKey(&blob, &[]);
Joel Galensond4dbfd52021-01-25 09:45:33 -0800187 // For this test we only care that there was no crash.
188 assert!(result.is_ok() || result.is_err());
Joel Galensonde386b42020-09-30 10:53:05 -0700189 }
190
191 #[test]
192 fn test_delete_key() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800193 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700194 let blob = generate_rsa_key(legacy.as_ref(), false, false);
195 let result = legacy.deleteKey(&blob);
196 assert!(result.is_ok(), "{:?}", result);
197 }
198
199 #[test]
200 fn test_delete_all_keys() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800201 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700202 let result = legacy.deleteAllKeys();
203 assert!(result.is_ok(), "{:?}", result);
204 }
205
206 #[test]
207 fn test_destroy_attestation_ids() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800208 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700209 let result = legacy.destroyAttestationIds();
210 assert!(result.is_err());
211 assert_eq!(result.unwrap_err().service_specific_error(), ErrorCode::UNIMPLEMENTED.0,);
212 }
213
214 fn generate_aes_key(legacy: &dyn IKeyMintDevice) -> Vec<u8> {
215 let kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800216 KeyParameter {
217 tag: Tag::ALGORITHM,
218 value: KeyParameterValue::Algorithm(Algorithm::AES),
219 },
220 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
221 KeyParameter {
222 tag: Tag::BLOCK_MODE,
223 value: KeyParameterValue::BlockMode(BlockMode::CBC),
224 },
225 KeyParameter {
226 tag: Tag::PADDING,
227 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
228 },
229 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
Joel Galensonde386b42020-09-30 10:53:05 -0700230 KeyParameter {
231 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800232 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700233 },
234 KeyParameter {
235 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800236 value: KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700237 },
238 ];
Shawn Willdendbdac602021-01-12 22:35:16 -0700239 let creation_result = generate_key(legacy, kps);
240 assert_eq!(creation_result.certificateChain.len(), 0);
241 creation_result.keyBlob
Joel Galensonde386b42020-09-30 10:53:05 -0700242 }
243
244 fn begin(
245 legacy: &dyn IKeyMintDevice,
246 blob: &[u8],
247 purpose: KeyPurpose,
248 extra_params: Option<Vec<KeyParameter>>,
249 ) -> BeginResult {
250 let mut kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800251 KeyParameter {
252 tag: Tag::BLOCK_MODE,
253 value: KeyParameterValue::BlockMode(BlockMode::CBC),
254 },
255 KeyParameter {
256 tag: Tag::PADDING,
257 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
258 },
Joel Galensonde386b42020-09-30 10:53:05 -0700259 ];
260 if let Some(mut extras) = extra_params {
261 kps.append(&mut extras);
262 }
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700263 let result = legacy.begin(purpose, blob, &kps, None);
Joel Galensonde386b42020-09-30 10:53:05 -0700264 assert!(result.is_ok(), "{:?}", result);
265 result.unwrap()
266 }
267
268 #[test]
269 fn test_begin_abort() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800270 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700271 let blob = generate_aes_key(legacy.as_ref());
272 let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
273 let operation = begin_result.operation.unwrap();
274 let result = operation.abort();
275 assert!(result.is_ok(), "{:?}", result);
276 let result = operation.abort();
277 assert!(result.is_err());
278 }
279
280 #[test]
281 fn test_begin_update_finish() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800282 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700283 let blob = generate_aes_key(legacy.as_ref());
284
285 let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
286 let operation = begin_result.operation.unwrap();
Shawn Willden44cc03d2021-02-19 10:53:49 -0700287
288 let update_aad_result = operation.updateAad(
Chariseea1e1c482022-02-26 01:26:35 +0000289 b"foobar".as_ref(),
Shawn Willden44cc03d2021-02-19 10:53:49 -0700290 None, /* authToken */
291 None, /* timestampToken */
292 );
293 assert!(update_aad_result.is_ok(), "{:?}", update_aad_result);
294
Joel Galensonde386b42020-09-30 10:53:05 -0700295 let message = [42; 128];
Shawn Willden44cc03d2021-02-19 10:53:49 -0700296 let result = operation.finish(
297 Some(&message),
298 None, /* signature */
299 None, /* authToken */
300 None, /* timestampToken */
301 None, /* confirmationToken */
302 );
Joel Galensonde386b42020-09-30 10:53:05 -0700303 assert!(result.is_ok(), "{:?}", result);
304 let ciphertext = result.unwrap();
305 assert!(!ciphertext.is_empty());
Joel Galensonde386b42020-09-30 10:53:05 -0700306
307 let begin_result =
308 begin(legacy.as_ref(), &blob, KeyPurpose::DECRYPT, Some(begin_result.params));
Shawn Willden44cc03d2021-02-19 10:53:49 -0700309
Joel Galensonde386b42020-09-30 10:53:05 -0700310 let operation = begin_result.operation.unwrap();
Shawn Willden44cc03d2021-02-19 10:53:49 -0700311
312 let update_aad_result = operation.updateAad(
Chariseea1e1c482022-02-26 01:26:35 +0000313 b"foobar".as_ref(),
Shawn Willden44cc03d2021-02-19 10:53:49 -0700314 None, /* authToken */
315 None, /* timestampToken */
316 );
317 assert!(update_aad_result.is_ok(), "{:?}", update_aad_result);
318
Joel Galensonde386b42020-09-30 10:53:05 -0700319 let result = operation.update(
Shawn Willden44cc03d2021-02-19 10:53:49 -0700320 &ciphertext,
321 None, /* authToken */
322 None, /* timestampToken */
Joel Galensonde386b42020-09-30 10:53:05 -0700323 );
324 assert!(result.is_ok(), "{:?}", result);
Shawn Willden44cc03d2021-02-19 10:53:49 -0700325 assert_eq!(result.unwrap(), message);
326 let result = operation.finish(
327 None, /* input */
328 None, /* signature */
329 None, /* authToken */
330 None, /* timestampToken */
331 None, /* confirmationToken */
332 );
Joel Galensonde386b42020-09-30 10:53:05 -0700333 assert!(result.is_ok(), "{:?}", result);
Joel Galensonde386b42020-09-30 10:53:05 -0700334 }
Joel Galensonf21c0022020-12-11 14:37:52 -0800335
336 #[test]
337 fn test_secure_clock() {
338 add_keymint_device_service();
Stephen Crane221bbb52020-12-16 15:52:10 -0800339 let compat_service: binder::Strong<dyn IKeystoreCompatService> =
Joel Galenson9978cd42021-02-23 09:11:10 -0800340 match binder::get_interface(COMPAT_NAME) {
341 Ok(cs) => cs,
342 _ => return,
343 };
344 let secure_clock = match compat_service.getSecureClock() {
345 Ok(sc) => sc,
346 _ => return,
347 };
Joel Galensonf21c0022020-12-11 14:37:52 -0800348
349 let challenge = 42;
350 let result = secure_clock.generateTimeStamp(challenge);
351 assert!(result.is_ok(), "{:?}", result);
352 let result = result.unwrap();
353 assert_eq!(result.challenge, challenge);
354 assert_eq!(result.mac.len(), 32);
355 }
356
357 #[test]
358 fn test_shared_secret() {
359 add_keymint_device_service();
Stephen Crane221bbb52020-12-16 15:52:10 -0800360 let compat_service: binder::Strong<dyn IKeystoreCompatService> =
Joel Galenson9978cd42021-02-23 09:11:10 -0800361 match binder::get_interface(COMPAT_NAME) {
362 Ok(cs) => cs,
363 _ => return,
364 };
365 let shared_secret = match compat_service.getSharedSecret(SecurityLevel::TRUSTED_ENVIRONMENT)
366 {
367 Ok(ss) => ss,
368 _ => return,
369 };
Joel Galensonf21c0022020-12-11 14:37:52 -0800370
371 let result = shared_secret.getSharedSecretParameters();
372 assert!(result.is_ok(), "{:?}", result);
373 let params = result.unwrap();
374
375 let result = shared_secret.computeSharedSecret(&[params]);
376 assert!(result.is_ok(), "{:?}", result);
377 assert_ne!(result.unwrap().len(), 0);
378 }
Janis Danisevskis67f30562021-05-21 13:20:22 -0700379
380 #[test]
381 fn test_get_key_characteristics() {
382 let legacy = get_device_or_skip_test!();
383 let hw_info = legacy.getHardwareInfo().expect("GetHardwareInfo");
384
385 let blob = generate_rsa_key(legacy.as_ref(), false, false);
386 let characteristics =
387 legacy.getKeyCharacteristics(&blob, &[], &[]).expect("GetKeyCharacteristics.");
388
389 assert!(characteristics.iter().any(|kc| kc.securityLevel == hw_info.securityLevel));
390 let sec_level_enforced = &characteristics
391 .iter()
392 .find(|kc| kc.securityLevel == hw_info.securityLevel)
393 .expect("There should be characteristics matching the device's security level.")
394 .authorizations;
395
396 assert!(sec_level_enforced.iter().any(|kp| matches!(
397 kp,
398 KeyParameter {
399 tag: Tag::PURPOSE,
400 value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN)
401 }
402 )));
403 assert!(sec_level_enforced.iter().any(|kp| matches!(
404 kp,
405 KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
406 )));
407 assert!(sec_level_enforced.iter().any(|kp| matches!(
408 kp,
409 KeyParameter {
410 tag: Tag::PADDING,
411 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS)
412 }
413 )));
414 assert!(sec_level_enforced.iter().any(|kp| matches!(
415 kp,
416 KeyParameter {
417 tag: Tag::ALGORITHM,
418 value: KeyParameterValue::Algorithm(Algorithm::RSA)
419 }
420 )));
421 assert!(sec_level_enforced.iter().any(|kp| matches!(
422 kp,
423 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) }
424 )));
425 assert!(sec_level_enforced.iter().any(|kp| matches!(
426 kp,
427 KeyParameter {
428 tag: Tag::RSA_PUBLIC_EXPONENT,
429 value: KeyParameterValue::LongInteger(65537)
430 }
431 )));
432 assert!(sec_level_enforced.iter().any(|kp| matches!(
433 kp,
434 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) }
435 )));
436 assert!(sec_level_enforced.iter().any(|kp| matches!(
437 kp,
438 KeyParameter {
439 tag: Tag::ORIGIN,
440 value: KeyParameterValue::Origin(KeyOrigin::GENERATED)
441 }
442 )));
443 assert!(sec_level_enforced.iter().any(|kp| matches!(
444 kp,
445 KeyParameter { tag: Tag::OS_VERSION, value: KeyParameterValue::Integer(_) }
446 )));
447 assert!(sec_level_enforced.iter().any(|kp| matches!(
448 kp,
449 KeyParameter { tag: Tag::OS_PATCHLEVEL, value: KeyParameterValue::Integer(_) }
450 )));
451 assert!(sec_level_enforced.iter().any(|kp| matches!(
452 kp,
Janis Danisevskis67f30562021-05-21 13:20:22 -0700453 KeyParameter { tag: Tag::BOOT_PATCHLEVEL, value: KeyParameterValue::Integer(_) }
454 )));
455 }
Joel Galensonde386b42020-09-30 10:53:05 -0700456}