1 // Copyright 2022, 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, device_id_attestation_check_acceptable_error,
17 device_id_attestation_feature_exists, get_attest_id_value,
18 is_second_imei_id_attestation_required, skip_device_id_attest_tests,
19 };
20 use crate::{
21 skip_device_id_attestation_tests, skip_test_if_no_app_attest_key_feature,
22 skip_test_if_no_device_id_attestation_feature,
23 };
24 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
25 Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
26 ErrorCode::ErrorCode, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
27 SecurityLevel::SecurityLevel, Tag::Tag,
28 };
29 use android_system_keystore2::aidl::android::system::keystore2::{
30 Domain::Domain, IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor,
31 ResponseCode::ResponseCode,
32 };
33 use keystore2_test_utils::ffi_test_utils::{get_value_from_attest_record, validate_certchain};
34 use keystore2_test_utils::{
35 authorizations, key_generations, key_generations::Error, run_as, SecLevel,
36 };
37 use nix::unistd::getuid;
38 use rustutils::users::AID_USER_OFFSET;
39
40 /// Generate RSA and EC attestation keys and use them for signing RSA-signing keys.
41 /// Test should be able to generate attestation keys and use them successfully.
42 #[test]
keystore2_attest_rsa_signing_key_success()43 fn keystore2_attest_rsa_signing_key_success() {
44 skip_test_if_no_app_attest_key_feature!();
45
46 let sl = SecLevel::tee();
47 let att_challenge: &[u8] = b"foo";
48
49 for algo in [Algorithm::RSA, Algorithm::EC] {
50 // Create attestation key.
51 let Some(attestation_key_metadata) = key_generations::map_ks_error(
52 key_generations::generate_attestation_key(&sl, algo, att_challenge),
53 )
54 .unwrap() else {
55 return;
56 };
57
58 let mut cert_chain: Vec<u8> = Vec::new();
59 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
60 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
61 validate_certchain(&cert_chain).expect("Error while validating cert chain.");
62
63 // Create RSA signing key and use attestation key to sign it.
64 let sign_key_alias = format!("ks_attest_rsa_signing_key_{}", getuid());
65 let Some(sign_key_metadata) = key_generations::generate_rsa_key(
66 &sl,
67 Domain::APP,
68 -1,
69 Some(sign_key_alias),
70 &key_generations::KeyParams {
71 key_size: 2048,
72 purpose: vec![KeyPurpose::SIGN, KeyPurpose::VERIFY],
73 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
74 digest: Some(Digest::SHA_2_256),
75 mgf_digest: None,
76 block_mode: None,
77 att_challenge: Some(att_challenge.to_vec()),
78 },
79 Some(&attestation_key_metadata.key),
80 )
81 .unwrap() else {
82 return;
83 };
84
85 let mut cert_chain: Vec<u8> = Vec::new();
86 cert_chain.extend(sign_key_metadata.certificate.as_ref().unwrap());
87 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
88 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
89 validate_certchain(&cert_chain).expect("Error while validating cert chain");
90 }
91 }
92
93 /// Generate RSA and EC attestation keys and use them for signing RSA encrypt/decrypt keys.
94 /// Test should be able to generate attestation keys and use them successfully.
95 #[test]
keystore2_attest_rsa_encrypt_key_success()96 fn keystore2_attest_rsa_encrypt_key_success() {
97 skip_test_if_no_app_attest_key_feature!();
98
99 let sl = SecLevel::tee();
100 let att_challenge: &[u8] = b"foo";
101
102 for algo in [Algorithm::RSA, Algorithm::EC] {
103 // Create attestation key.
104 let Some(attestation_key_metadata) = key_generations::map_ks_error(
105 key_generations::generate_attestation_key(&sl, algo, att_challenge),
106 )
107 .unwrap() else {
108 return;
109 };
110
111 let mut cert_chain: Vec<u8> = Vec::new();
112 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
113 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
114 validate_certchain(&cert_chain).expect("Error while validating cert chain.");
115
116 // Create RSA encrypt/decrypt key and use attestation key to sign it.
117 let decrypt_key_alias = format!("ks_attest_rsa_encrypt_key_{}", getuid());
118 let Some(decrypt_key_metadata) = key_generations::generate_rsa_key(
119 &sl,
120 Domain::APP,
121 -1,
122 Some(decrypt_key_alias),
123 &key_generations::KeyParams {
124 key_size: 2048,
125 purpose: vec![KeyPurpose::ENCRYPT, KeyPurpose::DECRYPT],
126 padding: Some(PaddingMode::RSA_PKCS1_1_5_ENCRYPT),
127 digest: Some(Digest::SHA_2_256),
128 mgf_digest: None,
129 block_mode: None,
130 att_challenge: Some(att_challenge.to_vec()),
131 },
132 Some(&attestation_key_metadata.key),
133 )
134 .unwrap() else {
135 return;
136 };
137
138 let mut cert_chain: Vec<u8> = Vec::new();
139 cert_chain.extend(decrypt_key_metadata.certificate.as_ref().unwrap());
140 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
141 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
142
143 validate_certchain(&cert_chain).expect("Error while validating cert chain.");
144 }
145 }
146
147 /// Generate RSA and EC attestation keys and use them for signing EC keys.
148 /// Test should be able to generate attestation keys and use them successfully.
149 #[test]
keystore2_attest_ec_key_success()150 fn keystore2_attest_ec_key_success() {
151 skip_test_if_no_app_attest_key_feature!();
152
153 let sl = SecLevel::tee();
154 let att_challenge: &[u8] = b"foo";
155
156 for algo in [Algorithm::RSA, Algorithm::EC] {
157 // Create attestation key.
158 let Some(attestation_key_metadata) = key_generations::map_ks_error(
159 key_generations::generate_attestation_key(&sl, algo, att_challenge),
160 )
161 .unwrap() else {
162 return;
163 };
164
165 let mut cert_chain: Vec<u8> = Vec::new();
166 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
167 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
168 validate_certchain(&cert_chain).expect("Error while validating cert chain.");
169
170 // Create EC key and use attestation key to sign it.
171 let ec_key_alias = format!("ks_ec_attested_test_key_{}", getuid());
172 let ec_key_metadata = key_generations::generate_ec_256_attested_key(
173 &sl,
174 Some(ec_key_alias),
175 att_challenge,
176 &attestation_key_metadata.key,
177 )
178 .unwrap();
179
180 let mut cert_chain: Vec<u8> = Vec::new();
181 cert_chain.extend(ec_key_metadata.certificate.as_ref().unwrap());
182 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
183 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
184
185 validate_certchain(&cert_chain).expect("Error while validating cert chain.");
186 }
187 }
188
189 /// Generate EC-CURVE_25519 attestation key and use it for signing RSA-signing keys.
190 /// Test should be able to generate RSA signing key with EC-CURVE_25519 as attestation key
191 /// successfully.
192 #[test]
keystore2_attest_rsa_signing_key_with_ec_25519_key_success()193 fn keystore2_attest_rsa_signing_key_with_ec_25519_key_success() {
194 skip_test_if_no_app_attest_key_feature!();
195
196 let sl = SecLevel::tee();
197 if sl.get_keymint_version() < 2 {
198 // Curve 25519 was included in version 2 of the KeyMint interface.
199 // For device with KeyMint-V1 or Keymaster in backend, emulated Ed25519 key can't attest
200 // to a "real" RSA key.
201 return;
202 }
203
204 let att_challenge: &[u8] = b"foo";
205
206 // Create EcCurve::CURVE_25519 attestation key.
207 let Some(attestation_key_metadata) =
208 key_generations::map_ks_error(key_generations::generate_ec_attestation_key(
209 &sl,
210 att_challenge,
211 Digest::NONE,
212 EcCurve::CURVE_25519,
213 ))
214 .unwrap()
215 else {
216 return;
217 };
218
219 let mut cert_chain: Vec<u8> = Vec::new();
220 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
221 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
222 validate_certchain(&cert_chain).expect("Error while validating cert chain.");
223
224 // Create RSA signing key and use attestation key to sign it.
225 let sign_key_alias = format!("ksrsa_attested_sign_test_key_{}", getuid());
226 let Some(sign_key_metadata) = key_generations::generate_rsa_key(
227 &sl,
228 Domain::APP,
229 -1,
230 Some(sign_key_alias),
231 &key_generations::KeyParams {
232 key_size: 2048,
233 purpose: vec![KeyPurpose::SIGN, KeyPurpose::VERIFY],
234 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
235 digest: Some(Digest::SHA_2_256),
236 mgf_digest: None,
237 block_mode: None,
238 att_challenge: Some(att_challenge.to_vec()),
239 },
240 Some(&attestation_key_metadata.key),
241 )
242 .unwrap() else {
243 return;
244 };
245
246 let mut cert_chain: Vec<u8> = Vec::new();
247 cert_chain.extend(sign_key_metadata.certificate.as_ref().unwrap());
248 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
249 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
250 validate_certchain(&cert_chain).expect("Error while validating cert chain");
251 }
252
253 /// Try to generate RSA attestation key with multiple purposes. Test should fail with error code
254 /// `INCOMPATIBLE_PURPOSE` to generate an attestation key.
255 #[test]
keystore2_generate_rsa_attest_key_with_multi_purpose_fail()256 fn keystore2_generate_rsa_attest_key_with_multi_purpose_fail() {
257 skip_test_if_no_app_attest_key_feature!();
258 let sl = SecLevel::tee();
259 if sl.get_keymint_version() < 2 {
260 // The KeyMint v1 spec required that KeyPurpose::ATTEST_KEY not be combined
261 // with other key purposes. However, this was not checked at the time
262 // so we can only be strict about checking this for implementations of KeyMint
263 // version 2 and above.
264 return;
265 }
266
267 let digest = Digest::SHA_2_256;
268 let padding = PaddingMode::RSA_PKCS1_1_5_SIGN;
269 let key_size = 2048;
270
271 let attest_key_alias =
272 format!("ksrsa_attest_multipurpose_key_{}{}{}", getuid(), key_size, digest.0);
273
274 let attest_gen_params = authorizations::AuthSetBuilder::new()
275 .no_auth_required()
276 .algorithm(Algorithm::RSA)
277 .purpose(KeyPurpose::ATTEST_KEY)
278 .purpose(KeyPurpose::SIGN)
279 .purpose(KeyPurpose::VERIFY)
280 .digest(digest)
281 .key_size(key_size)
282 .rsa_public_exponent(65537)
283 .padding_mode(padding);
284
285 let result = key_generations::map_ks_error(sl.binder.generateKey(
286 &KeyDescriptor {
287 domain: Domain::APP,
288 nspace: -1,
289 alias: Some(attest_key_alias),
290 blob: None,
291 },
292 None,
293 &attest_gen_params,
294 0,
295 b"entropy",
296 ));
297 assert!(result.is_err());
298 assert_eq!(Error::Km(ErrorCode::INCOMPATIBLE_PURPOSE), result.unwrap_err());
299 }
300
301 /// Try to generate EC attestation key with multiple purposes. Test should fail with error code
302 /// `INCOMPATIBLE_PURPOSE` to generate an attestation key.
303 #[test]
keystore2_ec_attest_key_with_multi_purpose_fail()304 fn keystore2_ec_attest_key_with_multi_purpose_fail() {
305 skip_test_if_no_app_attest_key_feature!();
306 let sl = SecLevel::tee();
307 if sl.get_keymint_version() < 2 {
308 // The KeyMint v1 spec required that KeyPurpose::ATTEST_KEY not be combined
309 // with other key purposes. However, this was not checked at the time
310 // so we can only be strict about checking this for implementations of KeyMint
311 // version 2 and above.
312 return;
313 }
314
315 let attest_key_alias = format!("ks_ec_attest_multipurpose_key_{}", getuid());
316
317 let attest_gen_params = authorizations::AuthSetBuilder::new()
318 .no_auth_required()
319 .algorithm(Algorithm::EC)
320 .purpose(KeyPurpose::ATTEST_KEY)
321 .purpose(KeyPurpose::SIGN)
322 .purpose(KeyPurpose::VERIFY)
323 .digest(Digest::SHA_2_256)
324 .ec_curve(EcCurve::P_256);
325
326 let result = key_generations::map_ks_error(sl.binder.generateKey(
327 &KeyDescriptor {
328 domain: Domain::APP,
329 nspace: -1,
330 alias: Some(attest_key_alias),
331 blob: None,
332 },
333 None,
334 &attest_gen_params,
335 0,
336 b"entropy",
337 ));
338 assert!(result.is_err());
339 assert_eq!(Error::Km(ErrorCode::INCOMPATIBLE_PURPOSE), result.unwrap_err());
340 }
341
342 /// Generate RSA attestation key and try to use it for signing RSA key without providing
343 /// attestation challenge. Test should fail to generate a key with error code
344 /// `ATTESTATION_CHALLENGE_MISSING`.
345 #[test]
keystore2_attest_key_fails_missing_challenge()346 fn keystore2_attest_key_fails_missing_challenge() {
347 skip_test_if_no_app_attest_key_feature!();
348
349 let sl = SecLevel::tee();
350 let att_challenge: &[u8] = b"foo";
351
352 // Create RSA attestation key.
353 let Some(attestation_key_metadata) = key_generations::map_ks_error(
354 key_generations::generate_attestation_key(&sl, Algorithm::RSA, att_challenge),
355 )
356 .unwrap() else {
357 return;
358 };
359
360 let mut cert_chain: Vec<u8> = Vec::new();
361 cert_chain.extend(attestation_key_metadata.certificate.as_ref().unwrap());
362 cert_chain.extend(attestation_key_metadata.certificateChain.as_ref().unwrap());
363 validate_certchain(&cert_chain).expect("Error while validating cert chain.");
364
365 // Try to attest RSA signing key without providing attestation challenge.
366 let sign_key_alias = format!("ksrsa_attested_test_key_missing_challenge{}", getuid());
367 let result = key_generations::map_ks_error(key_generations::generate_rsa_key(
368 &sl,
369 Domain::APP,
370 -1,
371 Some(sign_key_alias),
372 &key_generations::KeyParams {
373 key_size: 2048,
374 purpose: vec![KeyPurpose::SIGN, KeyPurpose::VERIFY],
375 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
376 digest: Some(Digest::SHA_2_256),
377 mgf_digest: None,
378 block_mode: None,
379 att_challenge: None,
380 },
381 Some(&attestation_key_metadata.key),
382 ));
383 assert!(result.is_err());
384 assert_eq!(Error::Km(ErrorCode::ATTESTATION_CHALLENGE_MISSING), result.unwrap_err());
385 }
386
387 /// Generate an asymmetric key which doesn't possess ATTEST_KEY purpose. Try to use this key as
388 /// attestation key while generating RSA key. Test should fail to generate a key with error
389 /// code `INCOMPATIBLE_PURPOSE`.
390 #[test]
keystore2_attest_rsa_key_with_non_attest_key_fails_incompat_purpose_error()391 fn keystore2_attest_rsa_key_with_non_attest_key_fails_incompat_purpose_error() {
392 skip_test_if_no_app_attest_key_feature!();
393
394 let sl = SecLevel::tee();
395 let att_challenge: &[u8] = b"foo";
396
397 let alias = format!("non_attest_key_{}", getuid());
398 let non_attest_key_metadata =
399 key_generations::generate_ec_p256_signing_key(&sl, Domain::APP, -1, Some(alias), None)
400 .unwrap();
401
402 // Try to generate RSA signing key with non-attestation key to sign it.
403 let sign_key_alias = format!("ksrsa_attested_sign_test_key_non_attest_{}", getuid());
404 let result = key_generations::map_ks_error(key_generations::generate_rsa_key(
405 &sl,
406 Domain::APP,
407 -1,
408 Some(sign_key_alias),
409 &key_generations::KeyParams {
410 key_size: 2048,
411 purpose: vec![KeyPurpose::SIGN, KeyPurpose::VERIFY],
412 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
413 digest: Some(Digest::SHA_2_256),
414 mgf_digest: None,
415 block_mode: None,
416 att_challenge: Some(att_challenge.to_vec()),
417 },
418 Some(&non_attest_key_metadata.key),
419 ));
420 assert!(result.is_err());
421 assert_eq!(Error::Km(ErrorCode::INCOMPATIBLE_PURPOSE), result.unwrap_err());
422 }
423
424 /// Generate a symmetric key. Try to use this symmetric key as attestation key while generating RSA
425 /// key. Test should fail to generate a key with response code `INVALID_ARGUMENT`.
426 #[test]
keystore2_attest_rsa_key_with_symmetric_key_fails_sys_error()427 fn keystore2_attest_rsa_key_with_symmetric_key_fails_sys_error() {
428 skip_test_if_no_app_attest_key_feature!();
429
430 let sl = SecLevel::tee();
431 let att_challenge: &[u8] = b"foo";
432
433 let alias = "aes_attest_key";
434 let sym_key_metadata = key_generations::generate_sym_key(
435 &sl,
436 Algorithm::AES,
437 128,
438 alias,
439 &PaddingMode::NONE,
440 &BlockMode::ECB,
441 None,
442 )
443 .unwrap();
444
445 // Try to generate RSA signing key with symmetric key as attestation key.
446 let sign_key_alias = format!("ksrsa_attested_sign_test_key_sym_attest_{}", getuid());
447 let result = key_generations::map_ks_error(key_generations::generate_rsa_key(
448 &sl,
449 Domain::APP,
450 -1,
451 Some(sign_key_alias),
452 &key_generations::KeyParams {
453 key_size: 2048,
454 purpose: vec![KeyPurpose::SIGN, KeyPurpose::VERIFY],
455 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
456 digest: Some(Digest::SHA_2_256),
457 mgf_digest: None,
458 block_mode: None,
459 att_challenge: Some(att_challenge.to_vec()),
460 },
461 Some(&sym_key_metadata.key),
462 ));
463 assert!(result.is_err());
464 assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
465 }
466
get_attestation_ids(keystore2: &binder::Strong<dyn IKeystoreService>) -> Vec<(Tag, Vec<u8>)>467 fn get_attestation_ids(keystore2: &binder::Strong<dyn IKeystoreService>) -> Vec<(Tag, Vec<u8>)> {
468 let attest_ids = vec![
469 (Tag::ATTESTATION_ID_BRAND, "brand"),
470 (Tag::ATTESTATION_ID_DEVICE, "device"),
471 (Tag::ATTESTATION_ID_PRODUCT, "name"),
472 (Tag::ATTESTATION_ID_SERIAL, "serialno"),
473 (Tag::ATTESTATION_ID_MANUFACTURER, "manufacturer"),
474 (Tag::ATTESTATION_ID_MODEL, "model"),
475 (Tag::ATTESTATION_ID_IMEI, ""), //Get this value from Telephony service.
476 (Tag::ATTESTATION_ID_SECOND_IMEI, ""), //Get this value from Telephony service.
477 ];
478
479 let mut attest_id_params: Vec<(Tag, Vec<u8>)> = vec![];
480 for (attest_id, prop_name) in attest_ids {
481 if attest_id == Tag::ATTESTATION_ID_SECOND_IMEI
482 && !is_second_imei_id_attestation_required(keystore2)
483 {
484 continue;
485 }
486
487 if let Some(value) = get_attest_id_value(attest_id, prop_name) {
488 if !value.is_empty() {
489 attest_id_params.push((attest_id, value));
490 }
491 }
492 }
493
494 attest_id_params
495 }
496
497 /// Generate an attested key with attestation of the device's identifiers. Test should succeed in
498 /// generating a attested key with attestation of device identifiers. Test might fail on devices
499 /// which don't support device id attestation with error response code `CANNOT_ATTEST_IDS or
500 /// INVALID_TAG`
generate_attested_key_with_device_attest_ids(algorithm: Algorithm)501 fn generate_attested_key_with_device_attest_ids(algorithm: Algorithm) {
502 skip_test_if_no_device_id_attestation_feature!();
503 skip_device_id_attestation_tests!();
504 skip_test_if_no_app_attest_key_feature!();
505 let sl = SecLevel::tee();
506
507 let att_challenge: &[u8] = b"foo";
508 let Some(attest_key_metadata) = key_generations::map_ks_error(
509 key_generations::generate_attestation_key(&sl, algorithm, att_challenge),
510 )
511 .unwrap() else {
512 return;
513 };
514
515 let attest_id_params = get_attestation_ids(&sl.keystore2);
516
517 for (attest_id, value) in attest_id_params {
518 // Create RSA/EC key and use attestation key to sign it.
519 let key_alias = format!("ks_attested_test_key_{}", getuid());
520 let key_metadata =
521 key_generations::map_ks_error(key_generations::generate_key_with_attest_id(
522 &sl,
523 algorithm,
524 Some(key_alias),
525 att_challenge,
526 &attest_key_metadata.key,
527 attest_id,
528 value.clone(),
529 ))
530 .unwrap();
531
532 assert!(key_metadata.certificate.is_some());
533 assert!(key_metadata.certificateChain.is_none());
534
535 let mut cert_chain: Vec<u8> = Vec::new();
536 cert_chain.extend(key_metadata.certificate.as_ref().unwrap());
537 cert_chain.extend(attest_key_metadata.certificate.as_ref().unwrap());
538 cert_chain.extend(attest_key_metadata.certificateChain.as_ref().unwrap());
539
540 validate_certchain(&cert_chain).expect("Error while validating cert chain");
541 let attest_id_value = get_value_from_attest_record(
542 key_metadata.certificate.as_ref().unwrap(),
543 attest_id,
544 SecurityLevel::TRUSTED_ENVIRONMENT,
545 )
546 .expect("Attest id verification failed.");
547 assert_eq!(attest_id_value, value);
548 }
549 }
550
551 #[test]
keystore2_attest_ecdsa_attestation_id()552 fn keystore2_attest_ecdsa_attestation_id() {
553 generate_attested_key_with_device_attest_ids(Algorithm::EC);
554 }
555
556 #[test]
keystore2_attest_rsa_attestation_id()557 fn keystore2_attest_rsa_attestation_id() {
558 generate_attested_key_with_device_attest_ids(Algorithm::RSA);
559 }
560
561 /// Try to generate an attested key with attestation of invalid device's identifiers. Test should
562 /// fail to generate a key with proper error code.
563 #[test]
keystore2_attest_key_fails_with_invalid_attestation_id()564 fn keystore2_attest_key_fails_with_invalid_attestation_id() {
565 skip_test_if_no_device_id_attestation_feature!();
566 skip_device_id_attestation_tests!();
567 skip_test_if_no_app_attest_key_feature!();
568
569 let sl = SecLevel::tee();
570
571 let digest = Digest::SHA_2_256;
572 let att_challenge: &[u8] = b"foo";
573
574 // Create EC-Attestation key.
575 let Some(attest_key_metadata) = key_generations::map_ks_error(
576 key_generations::generate_ec_attestation_key(&sl, att_challenge, digest, EcCurve::P_256),
577 )
578 .unwrap() else {
579 return;
580 };
581
582 let attest_id_params = vec![
583 (Tag::ATTESTATION_ID_BRAND, b"invalid-brand".to_vec()),
584 (Tag::ATTESTATION_ID_DEVICE, b"invalid-device-name".to_vec()),
585 (Tag::ATTESTATION_ID_PRODUCT, b"invalid-product-name".to_vec()),
586 (Tag::ATTESTATION_ID_SERIAL, b"invalid-ro-serial".to_vec()),
587 (Tag::ATTESTATION_ID_MANUFACTURER, b"invalid-ro-product-manufacturer".to_vec()),
588 (Tag::ATTESTATION_ID_MODEL, b"invalid-ro-product-model".to_vec()),
589 (Tag::ATTESTATION_ID_IMEI, b"invalid-imei".to_vec()),
590 ];
591
592 for (attest_id, value) in attest_id_params {
593 // Create EC key and use attestation key to sign it.
594 let ec_key_alias = format!("ks_ec_attested_test_key_fail_{}{}", getuid(), digest.0);
595 let result = key_generations::map_ks_error(key_generations::generate_key_with_attest_id(
596 &sl,
597 Algorithm::EC,
598 Some(ec_key_alias),
599 att_challenge,
600 &attest_key_metadata.key,
601 attest_id,
602 value,
603 ));
604
605 assert!(result.is_err());
606 device_id_attestation_check_acceptable_error(attest_id, result.unwrap_err());
607 }
608 }
609
610 /// If `DEVICE_ID_ATTESTATION_FEATURE` is not supported then test tries to generate an attested
611 /// key with attestation of valid device's identifiers. Test should fail to generate key with
612 /// error code `CANNOT_ATTEST_IDS`.
613 #[test]
keystore2_attest_key_without_attestation_id_support_fails_with_cannot_attest_id()614 fn keystore2_attest_key_without_attestation_id_support_fails_with_cannot_attest_id() {
615 if device_id_attestation_feature_exists() {
616 // Skip this test on device supporting `DEVICE_ID_ATTESTATION_FEATURE`.
617 return;
618 }
619 skip_device_id_attestation_tests!();
620 skip_test_if_no_app_attest_key_feature!();
621
622 let sl = SecLevel::tee();
623
624 let att_challenge: &[u8] = b"foo";
625 let Some(attest_key_metadata) = key_generations::map_ks_error(
626 key_generations::generate_attestation_key(&sl, Algorithm::RSA, att_challenge),
627 )
628 .unwrap() else {
629 return;
630 };
631
632 let attest_id_params = get_attestation_ids(&sl.keystore2);
633 for (attest_id, value) in attest_id_params {
634 // Create RSA/EC key and use attestation key to sign it.
635 let key_alias = format!("ks_attested_test_key_{}", getuid());
636 let result = key_generations::map_ks_error(key_generations::generate_key_with_attest_id(
637 &sl,
638 Algorithm::RSA,
639 Some(key_alias),
640 att_challenge,
641 &attest_key_metadata.key,
642 attest_id,
643 value.clone(),
644 ));
645 assert!(
646 result.is_err(),
647 "Expected to fail as FEATURE_DEVICE_ID_ATTESTATION is not supported."
648 );
649 assert_eq!(result.unwrap_err(), Error::Km(ErrorCode::CANNOT_ATTEST_IDS));
650 }
651 }
652
653 /// Try to generate an attestation key from user context with UID other than AID_SYSTEM or AID_ROOT
654 /// and also there is no package name associated with it. In such case key generation should fail
655 /// while collecting Attestation Application ID (AAID) from AAID provider service and keystore
656 /// should return error response code - `GET_ATTESTATION_APPLICATION_ID_FAILED`.
657 #[test]
keystore2_generate_attested_key_fail_to_get_aaid()658 fn keystore2_generate_attested_key_fail_to_get_aaid() {
659 const USER_ID: u32 = 99;
660 const APPLICATION_ID: u32 = 19901;
661 static APP_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
662 static APP_GID: u32 = APP_UID;
663
664 let gen_key_fn = || {
665 skip_test_if_no_app_attest_key_feature!();
666 let sl = SecLevel::tee();
667 if sl.keystore2.getInterfaceVersion().unwrap() < 4 {
668 // `GET_ATTESTATION_APPLICATION_ID_FAILED` is supported on devices with
669 // `IKeystoreService` version >= 4.
670 return;
671 }
672 let att_challenge: &[u8] = b"foo";
673 let alias = format!("ks_attest_rsa_encrypt_key_aaid_fail{}", getuid());
674
675 let result = key_generations::map_ks_error(key_generations::generate_rsa_key(
676 &sl,
677 Domain::APP,
678 -1,
679 Some(alias),
680 &key_generations::KeyParams {
681 key_size: 2048,
682 purpose: vec![KeyPurpose::ATTEST_KEY],
683 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
684 digest: Some(Digest::SHA_2_256),
685 mgf_digest: None,
686 block_mode: None,
687 att_challenge: Some(att_challenge.to_vec()),
688 },
689 None,
690 ));
691
692 assert!(result.is_err());
693 assert_eq!(
694 result.unwrap_err(),
695 Error::Rc(ResponseCode::GET_ATTESTATION_APPLICATION_ID_FAILED)
696 );
697 };
698
699 // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
700 // `--test-threads=1`), and nothing yet done with binder.
701 unsafe { run_as::run_as_app(APP_UID, APP_GID, gen_key_fn) };
702 }
703