• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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