• 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     generate_ec_key_and_grant_to_users, perform_sample_sign_operation,
17 };
18 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
19     Digest::Digest, KeyPurpose::KeyPurpose,
20 };
21 use android_security_maintenance::aidl::android::security::maintenance::IKeystoreMaintenance::IKeystoreMaintenance;
22 use android_system_keystore2::aidl::android::system::keystore2::{
23     Domain::Domain, IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor,
24     KeyEntryResponse::KeyEntryResponse, KeyPermission::KeyPermission, ResponseCode::ResponseCode,
25 };
26 use keystore2_test_utils::{
27     authorizations, get_keystore_service, key_generations,
28     key_generations::{map_ks_error, Error},
29     run_as, SecLevel,
30 };
31 use nix::unistd::getuid;
32 use rustutils::users::AID_USER_OFFSET;
33 
34 static USER_MANAGER_SERVICE_NAME: &str = "android.security.maintenance";
35 
36 /// Produce a [`KeyDescriptor`] for a granted key.
granted_key_descriptor(nspace: i64) -> KeyDescriptor37 fn granted_key_descriptor(nspace: i64) -> KeyDescriptor {
38     KeyDescriptor { domain: Domain::GRANT, nspace, alias: None, blob: None }
39 }
40 
get_granted_key( ks2: &binder::Strong<dyn IKeystoreService>, nspace: i64, ) -> Result<KeyEntryResponse, Error>41 fn get_granted_key(
42     ks2: &binder::Strong<dyn IKeystoreService>,
43     nspace: i64,
44 ) -> Result<KeyEntryResponse, Error> {
45     map_ks_error(ks2.getKeyEntry(&granted_key_descriptor(nspace)))
46 }
47 
48 /// Generate an EC signing key in the SELINUX domain and grant it to the user with given access
49 /// vector.
generate_and_grant_selinux_key( grantee_uid: u32, access_vector: i32, ) -> Result<KeyDescriptor, Error>50 fn generate_and_grant_selinux_key(
51     grantee_uid: u32,
52     access_vector: i32,
53 ) -> Result<KeyDescriptor, Error> {
54     let sl = SecLevel::tee();
55     let alias = format!("{}{}", "ks_grant_test_key_1", getuid());
56 
57     let key_metadata = key_generations::generate_ec_p256_signing_key(
58         &sl,
59         Domain::SELINUX,
60         key_generations::SELINUX_SHELL_NAMESPACE,
61         Some(alias),
62         None,
63     )
64     .unwrap();
65 
66     map_ks_error(sl.keystore2.grant(
67         &key_metadata.key,
68         grantee_uid.try_into().unwrap(),
69         access_vector,
70     ))
71 }
72 
73 /// Use a granted key to perform a signing operation.
sign_with_granted_key(grant_key_nspace: i64) -> Result<(), Error>74 fn sign_with_granted_key(grant_key_nspace: i64) -> Result<(), Error> {
75     let sl = SecLevel::tee();
76     let key_entry_response = get_granted_key(&sl.keystore2, grant_key_nspace)?;
77 
78     // Perform sample crypto operation using granted key.
79     let op_response = map_ks_error(sl.binder.createOperation(
80         &key_entry_response.metadata.key,
81         &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
82         false,
83     ))?;
84 
85     assert!(op_response.iOperation.is_some());
86     assert_eq!(
87         Ok(()),
88         map_ks_error(perform_sample_sign_operation(&op_response.iOperation.unwrap()))
89     );
90 
91     Ok(())
92 }
93 
get_maintenance() -> binder::Strong<dyn IKeystoreMaintenance>94 fn get_maintenance() -> binder::Strong<dyn IKeystoreMaintenance> {
95     binder::get_interface(USER_MANAGER_SERVICE_NAME).unwrap()
96 }
97 
98 /// Try to grant an SELINUX key with permission that does not map to any of the `KeyPermission`
99 /// values.  An error is expected with values that does not map to set of permissions listed in
100 /// `KeyPermission`.
101 #[test]
grant_selinux_key_with_invalid_perm()102 fn grant_selinux_key_with_invalid_perm() {
103     const USER_ID: u32 = 99;
104     const APPLICATION_ID: u32 = 10001;
105     let grantee_uid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
106     let invalid_access_vector = KeyPermission::CONVERT_STORAGE_KEY_TO_EPHEMERAL.0 << 19;
107 
108     let result = generate_and_grant_selinux_key(grantee_uid, invalid_access_vector);
109     assert!(result.is_err());
110     assert_eq!(Error::Rc(ResponseCode::SYSTEM_ERROR), result.unwrap_err());
111 }
112 
113 /// Try to grant an SELINUX key with empty access vector `KeyPermission::NONE`, should be able to
114 /// grant a key with empty access vector successfully. In grantee context try to use the granted
115 /// key, it should fail to load the key with permission denied error.
116 #[test]
grant_selinux_key_with_perm_none()117 fn grant_selinux_key_with_perm_none() {
118     const USER_ID: u32 = 99;
119     const APPLICATION_ID: u32 = 10001;
120     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
121     static GRANTEE_GID: u32 = GRANTEE_UID;
122 
123     let grantor_fn = || {
124         let empty_access_vector = KeyPermission::NONE.0;
125 
126         let grant_key = generate_and_grant_selinux_key(GRANTEE_UID, empty_access_vector).unwrap();
127 
128         assert_eq!(grant_key.domain, Domain::GRANT);
129 
130         grant_key.nspace
131     };
132 
133     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
134     // `--test-threads=1`), and nothing yet done with binder.
135     let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
136 
137     // In grantee context try to load the key, it should fail to load the granted key as it is
138     // granted with empty access vector.
139     let grantee_fn = move || {
140         let keystore2 = get_keystore_service();
141 
142         let result = get_granted_key(&keystore2, grant_key_nspace);
143         assert!(result.is_err());
144         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
145     };
146 
147     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
148     // `--test-threads=1`), and nothing yet done with binder.
149     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
150 }
151 
152 /// Grant an SELINUX key to the user (grantee) with `GET_INFO|USE` key permissions. Verify whether
153 /// grantee can succeed in loading the granted key and try to perform simple operation using this
154 /// granted key. Grantee should be able to load the key and use the key to perform crypto operation
155 /// successfully. Try to delete the granted key in grantee context where it is expected to fail to
156 /// delete it as `DELETE` permission is not granted.
157 #[test]
grant_selinux_key_get_info_use_perms()158 fn grant_selinux_key_get_info_use_perms() {
159     const USER_ID: u32 = 99;
160     const APPLICATION_ID: u32 = 10001;
161     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
162     static GRANTEE_GID: u32 = GRANTEE_UID;
163 
164     // Generate a key and grant it to a user with GET_INFO|USE key permissions.
165     let grantor_fn = || {
166         let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0;
167         let grant_key = generate_and_grant_selinux_key(GRANTEE_UID, access_vector).unwrap();
168 
169         assert_eq!(grant_key.domain, Domain::GRANT);
170 
171         grant_key.nspace
172     };
173 
174     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
175     // `--test-threads=1`), and nothing yet done with binder.
176     let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
177 
178     // In grantee context load the key and try to perform crypto operation.
179     let grantee_fn = move || {
180         let sl = SecLevel::tee();
181 
182         // Load the granted key.
183         let key_entry_response = get_granted_key(&sl.keystore2, grant_key_nspace).unwrap();
184 
185         // Perform sample crypto operation using granted key.
186         let op_response = sl
187             .binder
188             .createOperation(
189                 &key_entry_response.metadata.key,
190                 &authorizations::AuthSetBuilder::new()
191                     .purpose(KeyPurpose::SIGN)
192                     .digest(Digest::SHA_2_256),
193                 false,
194             )
195             .unwrap();
196         assert!(op_response.iOperation.is_some());
197         assert_eq!(
198             Ok(()),
199             map_ks_error(perform_sample_sign_operation(&op_response.iOperation.unwrap()))
200         );
201 
202         // Try to delete the key, it is expected to be fail with permission denied error.
203         let result =
204             map_ks_error(sl.keystore2.deleteKey(&granted_key_descriptor(grant_key_nspace)));
205         assert!(result.is_err());
206         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
207     };
208 
209     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
210     // `--test-threads=1`), and nothing yet done with binder.
211     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
212 }
213 
214 /// Grant an SELINUX key to the user (grantee) with just `GET_INFO` key permissions. Verify whether
215 /// grantee can succeed in loading the granted key and try to perform simple operation using this
216 /// granted key.
217 #[test]
grant_selinux_key_get_info_only()218 fn grant_selinux_key_get_info_only() {
219     const USER_ID: u32 = 99;
220     const APPLICATION_ID: u32 = 10001;
221     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
222     static GRANTEE_GID: u32 = GRANTEE_UID;
223 
224     // Generate a key and grant it to a user with (just) GET_INFO key permissions.
225     let grantor_fn = || {
226         let access_vector = KeyPermission::GET_INFO.0;
227         let grant_key = generate_and_grant_selinux_key(GRANTEE_UID, access_vector).unwrap();
228 
229         assert_eq!(grant_key.domain, Domain::GRANT);
230 
231         grant_key.nspace
232     };
233 
234     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
235     // `--test-threads=1`), and nothing yet done with binder on the main thread.
236     let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
237 
238     // In grantee context load the key and try to perform crypto operation.
239     let grantee_fn = move || {
240         let sl = SecLevel::tee();
241 
242         // Load the granted key.
243         let key_entry_response = get_granted_key(&sl.keystore2, grant_key_nspace)
244             .expect("failed to get info for granted key");
245 
246         // Attempt to perform sample crypto operation using granted key, now identified by <KEY_ID,
247         // key_id>.
248         let result = map_ks_error(
249             sl.binder.createOperation(
250                 &key_entry_response.metadata.key,
251                 &authorizations::AuthSetBuilder::new()
252                     .purpose(KeyPurpose::SIGN)
253                     .digest(Digest::SHA_2_256),
254                 false,
255             ),
256         );
257         assert!(result.is_err());
258         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
259 
260         // Try to delete the key using a <GRANT, grant_id> descriptor.
261         let result =
262             map_ks_error(sl.keystore2.deleteKey(&granted_key_descriptor(grant_key_nspace)));
263         assert!(result.is_err());
264         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
265 
266         // Try to delete the key using a <KEY_ID, key_id> descriptor.
267         let result = map_ks_error(sl.keystore2.deleteKey(&key_entry_response.metadata.key));
268         assert!(result.is_err());
269         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
270     };
271 
272     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
273     // `--test-threads=1`), and nothing yet done with binder on the main thread.
274     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
275 }
276 
277 /// Grant an APP key to the user (grantee) with just `GET_INFO` key permissions. Verify whether
278 /// grantee can succeed in loading the granted key and try to perform simple operation using this
279 /// granted key.
280 #[test]
grant_app_key_get_info_only()281 fn grant_app_key_get_info_only() {
282     const USER_ID: u32 = 99;
283     const APPLICATION_ID: u32 = 10001;
284     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
285     static GRANTEE_GID: u32 = GRANTEE_UID;
286     static ALIAS: &str = "ks_grant_key_info_only";
287 
288     // Generate a key and grant it to a user with (just) GET_INFO key permissions.
289     let grantor_fn = || {
290         let sl = SecLevel::tee();
291         let access_vector = KeyPermission::GET_INFO.0;
292         let mut grant_keys = generate_ec_key_and_grant_to_users(
293             &sl,
294             Some(ALIAS.to_string()),
295             vec![GRANTEE_UID.try_into().unwrap()],
296             access_vector,
297         )
298         .unwrap();
299 
300         grant_keys.remove(0)
301     };
302 
303     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
304     // `--test-threads=1`), and nothing yet done with binder on the main thread.
305     let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
306 
307     // In grantee context load the key and try to perform crypto operation.
308     let grantee_fn = move || {
309         let sl = SecLevel::tee();
310 
311         // Load the granted key.
312         let key_entry_response = get_granted_key(&sl.keystore2, grant_key_nspace)
313             .expect("failed to get info for granted key");
314 
315         // Attempt to perform sample crypto operation using granted key, now identified by <KEY_ID,
316         // key_id>.
317         let result = map_ks_error(
318             sl.binder.createOperation(
319                 &key_entry_response.metadata.key,
320                 &authorizations::AuthSetBuilder::new()
321                     .purpose(KeyPurpose::SIGN)
322                     .digest(Digest::SHA_2_256),
323                 false,
324             ),
325         );
326         assert!(result.is_err());
327         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
328 
329         // Try to delete the key using a <GRANT, grant_id> descriptor.
330         let result =
331             map_ks_error(sl.keystore2.deleteKey(&granted_key_descriptor(grant_key_nspace)));
332         assert!(result.is_err());
333         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
334 
335         // Try to delete the key using a <KEY_ID, key_id> descriptor.
336         let result = map_ks_error(sl.keystore2.deleteKey(&key_entry_response.metadata.key));
337         assert!(result.is_err());
338         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
339     };
340 
341     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
342     // `--test-threads=1`), and nothing yet done with binder on the main thread.
343     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
344 }
345 
346 /// Grant an APP key to the user with DELETE access. In grantee context load the key and delete it.
347 /// Verify that grantee should succeed in deleting the granted key and in grantor context test
348 /// should fail to find the key with error response `KEY_NOT_FOUND`.
349 #[test]
grant_app_key_delete_success()350 fn grant_app_key_delete_success() {
351     const USER_ID: u32 = 99;
352     const APPLICATION_ID: u32 = 10001;
353     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
354     static GRANTEE_GID: u32 = GRANTEE_UID;
355     static ALIAS: &str = "ks_grant_key_delete_success";
356 
357     // Generate a key and grant it to a user with DELETE permission.
358     let grantor_fn = || {
359         let sl = SecLevel::tee();
360         let access_vector = KeyPermission::DELETE.0;
361         let mut grant_keys = generate_ec_key_and_grant_to_users(
362             &sl,
363             Some(ALIAS.to_string()),
364             vec![GRANTEE_UID.try_into().unwrap()],
365             access_vector,
366         )
367         .unwrap();
368 
369         grant_keys.remove(0)
370     };
371 
372     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
373     // `--test-threads=1`), and nothing yet done with binder.
374     let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
375 
376     // Grantee context, delete the key.
377     let grantee_fn = move || {
378         let keystore2 = get_keystore_service();
379         keystore2.deleteKey(&granted_key_descriptor(grant_key_nspace)).unwrap();
380     };
381 
382     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
383     // `--test-threads=1`), and nothing yet done with binder.
384     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
385 
386     // Verify whether key got deleted in grantor's context.
387     let grantor_fn = move || {
388         let keystore2_inst = get_keystore_service();
389         let result = map_ks_error(keystore2_inst.getKeyEntry(&KeyDescriptor {
390             domain: Domain::APP,
391             nspace: -1,
392             alias: Some(ALIAS.to_string()),
393             blob: None,
394         }));
395         assert!(result.is_err());
396         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
397     };
398 
399     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
400     // `--test-threads=1`), and nothing yet done with binder.
401     unsafe { run_as::run_as_root(grantor_fn) };
402 }
403 
404 /// Grant an APP key to the user. In grantee context load the granted key and try to grant it to
405 /// second user. Test should fail with a response code `PERMISSION_DENIED` to grant a key to second
406 /// user from grantee context. Test should make sure second grantee should not have a access to
407 /// granted key.
408 #[test]
grant_granted_app_key_fails()409 fn grant_granted_app_key_fails() {
410     const GRANTOR_USER_ID: u32 = 97;
411     const GRANTOR_APPLICATION_ID: u32 = 10003;
412     static GRANTOR_UID: u32 = GRANTOR_USER_ID * AID_USER_OFFSET + GRANTOR_APPLICATION_ID;
413     static GRANTOR_GID: u32 = GRANTOR_UID;
414 
415     const USER_ID: u32 = 99;
416     const APPLICATION_ID: u32 = 10001;
417     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
418     static GRANTEE_GID: u32 = GRANTEE_UID;
419 
420     const SEC_USER_ID: u32 = 98;
421     const SEC_APPLICATION_ID: u32 = 10001;
422     static SEC_GRANTEE_UID: u32 = SEC_USER_ID * AID_USER_OFFSET + SEC_APPLICATION_ID;
423     static SEC_GRANTEE_GID: u32 = SEC_GRANTEE_UID;
424 
425     // Generate a key and grant it to a user with GET_INFO permission.
426     let grantor_fn = || {
427         let sl = SecLevel::tee();
428         let access_vector = KeyPermission::GET_INFO.0;
429         let alias = format!("ks_grant_perm_denied_key_{}", getuid());
430         let mut grant_keys = generate_ec_key_and_grant_to_users(
431             &sl,
432             Some(alias),
433             vec![GRANTEE_UID.try_into().unwrap()],
434             access_vector,
435         )
436         .unwrap();
437 
438         grant_keys.remove(0)
439     };
440     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
441     // `--test-threads=1`), and nothing yet done with binder.
442     let grant_key_nspace = unsafe { run_as::run_as_app(GRANTOR_UID, GRANTOR_GID, grantor_fn) };
443 
444     // Grantee context, load the granted key and try to grant it to `SEC_GRANTEE_UID` grantee.
445     let grantee_fn = move || {
446         let keystore2 = get_keystore_service();
447         let access_vector = KeyPermission::GET_INFO.0;
448 
449         // Try to grant when identifying the key with <GRANT, grant_nspace>.
450         let result = map_ks_error(keystore2.grant(
451             &granted_key_descriptor(grant_key_nspace),
452             SEC_GRANTEE_UID.try_into().unwrap(),
453             access_vector,
454         ));
455         assert!(result.is_err());
456         assert_eq!(Error::Rc(ResponseCode::SYSTEM_ERROR), result.unwrap_err());
457 
458         // Load the key info and try to grant when identifying the key with <KEY_ID, keyid>.
459         let key_entry_response = get_granted_key(&keystore2, grant_key_nspace).unwrap();
460         let result = map_ks_error(keystore2.grant(
461             &key_entry_response.metadata.key,
462             SEC_GRANTEE_UID.try_into().unwrap(),
463             access_vector,
464         ));
465         assert!(result.is_err());
466         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
467     };
468 
469     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
470     // `--test-threads=1`), and nothing yet done with binder.
471     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
472 
473     // Make sure second grantee shouldn't have access to the above granted key.
474     let grantee2_fn = move || {
475         let keystore2 = get_keystore_service();
476         let result = get_granted_key(&keystore2, grant_key_nspace);
477         assert!(result.is_err());
478         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
479     };
480 
481     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
482     // `--test-threads=1`), and nothing yet done with binder.
483     unsafe { run_as::run_as_app(SEC_GRANTEE_UID, SEC_GRANTEE_GID, grantee2_fn) };
484 }
485 
486 /// Grant an APP key to one user, from a normal user. Check that grantee context can load the
487 /// granted key, but that a second unrelated context cannot.
488 #[test]
grant_app_key_only_to_grantee()489 fn grant_app_key_only_to_grantee() {
490     const GRANTOR_USER_ID: u32 = 97;
491     const GRANTOR_APPLICATION_ID: u32 = 10003;
492     static GRANTOR_UID: u32 = GRANTOR_USER_ID * AID_USER_OFFSET + GRANTOR_APPLICATION_ID;
493     static GRANTOR_GID: u32 = GRANTOR_UID;
494 
495     const USER_ID: u32 = 99;
496     const APPLICATION_ID: u32 = 10001;
497     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
498     static GRANTEE_GID: u32 = GRANTEE_UID;
499 
500     const SEC_USER_ID: u32 = 98;
501     const SEC_APPLICATION_ID: u32 = 10001;
502     static SEC_GRANTEE_UID: u32 = SEC_USER_ID * AID_USER_OFFSET + SEC_APPLICATION_ID;
503     static SEC_GRANTEE_GID: u32 = SEC_GRANTEE_UID;
504 
505     // Child function to generate a key and grant it to a user with `GET_INFO` permission.
506     let grantor_fn = || {
507         let sl = SecLevel::tee();
508         let access_vector = KeyPermission::GET_INFO.0;
509         let alias = format!("ks_grant_single_{}", getuid());
510         let mut grant_keys = generate_ec_key_and_grant_to_users(
511             &sl,
512             Some(alias),
513             vec![GRANTEE_UID.try_into().unwrap()],
514             access_vector,
515         )
516         .unwrap();
517 
518         grant_keys.remove(0)
519     };
520 
521     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
522     // `--test-threads=1`), and nothing yet done with binder on the main thread.
523     let grant_key_nspace = unsafe { run_as::run_as_app(GRANTOR_UID, GRANTOR_GID, grantor_fn) };
524 
525     // Child function for the grantee context: can load the granted key.
526     let grantee_fn = move || {
527         let keystore2 = get_keystore_service();
528         let rsp = get_granted_key(&keystore2, grant_key_nspace).expect("failed to get granted key");
529 
530         // Return the underlying key ID to simulate an ID leak.
531         assert_eq!(rsp.metadata.key.domain, Domain::KEY_ID);
532         rsp.metadata.key.nspace
533     };
534 
535     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
536     // `--test-threads=1`), and nothing yet done with binder on the main thread.
537     let key_id = unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
538 
539     // Second context does not have access to the above granted key, because it's identified
540     // by <uid, grant_nspace> and the implicit uid value is different.  Also, even if the
541     // second context gets hold of the key ID somehow, that also doesn't work.
542     let non_grantee_fn = move || {
543         let keystore2 = get_keystore_service();
544         let result = get_granted_key(&keystore2, grant_key_nspace);
545         assert!(result.is_err());
546         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
547 
548         let result = map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
549             domain: Domain::KEY_ID,
550             nspace: key_id,
551             alias: None,
552             blob: None,
553         }));
554         assert!(result.is_err());
555         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
556     };
557 
558     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
559     // `--test-threads=1`), and nothing yet done with binder on the main thread.
560     unsafe { run_as::run_as_app(SEC_GRANTEE_UID, SEC_GRANTEE_GID, non_grantee_fn) };
561 }
562 
563 /// Try to grant an APP key with `GRANT` access. Keystore2 system shouldn't allow to grant a key
564 /// with `GRANT` access. Test should fail to grant a key with `PERMISSION_DENIED` error response
565 /// code.
566 #[test]
grant_app_key_with_grant_perm_fails()567 fn grant_app_key_with_grant_perm_fails() {
568     let sl = SecLevel::tee();
569     let access_vector = KeyPermission::GRANT.0;
570     let alias = format!("ks_grant_access_vec_key_{}", getuid());
571     let user_id = 98;
572     let application_id = 10001;
573     let grantee_uid = user_id * AID_USER_OFFSET + application_id;
574 
575     let result = map_ks_error(generate_ec_key_and_grant_to_users(
576         &sl,
577         Some(alias),
578         vec![grantee_uid.try_into().unwrap()],
579         access_vector,
580     ));
581     assert!(result.is_err());
582     assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
583 }
584 
585 /// Try to grant a non-existing SELINUX key to the user. Test should fail with `KEY_NOT_FOUND` error
586 /// response.
587 #[test]
grant_fails_with_non_existing_selinux_key()588 fn grant_fails_with_non_existing_selinux_key() {
589     let keystore2 = get_keystore_service();
590     let alias = format!("ks_grant_test_non_existing_key_5_{}", getuid());
591     let user_id = 98;
592     let application_id = 10001;
593     let grantee_uid = user_id * AID_USER_OFFSET + application_id;
594     let access_vector = KeyPermission::GET_INFO.0;
595 
596     let result = map_ks_error(keystore2.grant(
597         &KeyDescriptor {
598             domain: Domain::SELINUX,
599             nspace: key_generations::SELINUX_SHELL_NAMESPACE,
600             alias: Some(alias),
601             blob: None,
602         },
603         grantee_uid.try_into().unwrap(),
604         access_vector,
605     ));
606     assert!(result.is_err());
607     assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
608 }
609 
610 /// Grant a key to a UID (user ID A + app B) then uninstall user ID A. Initialize a new user with
611 /// the same user ID as the now-removed user. Check that app B for the new user can't load the key.
612 #[test]
grant_removed_when_grantee_user_id_removed()613 fn grant_removed_when_grantee_user_id_removed() {
614     const GRANTOR_USER_ID: u32 = 97;
615     const GRANTOR_APPLICATION_ID: u32 = 10003;
616     static GRANTOR_UID: u32 = GRANTOR_USER_ID * AID_USER_OFFSET + GRANTOR_APPLICATION_ID;
617     static GRANTOR_GID: u32 = GRANTOR_UID;
618 
619     const GRANTEE_USER_ID: u32 = 99;
620     const GRANTEE_APPLICATION_ID: u32 = 10001;
621     static GRANTEE_UID: u32 = GRANTEE_USER_ID * AID_USER_OFFSET + GRANTEE_APPLICATION_ID;
622     static GRANTEE_GID: u32 = GRANTEE_UID;
623 
624     // Add a new user.
625     let create_grantee_user_id_fn = || {
626         let maint = get_maintenance();
627         maint.onUserAdded(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to add user");
628     };
629 
630     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
631     // `--test-threads=1`), and nothing yet done with binder on the main thread.
632     unsafe { run_as::run_as_root(create_grantee_user_id_fn) };
633 
634     // Child function to generate a key and grant it to GRANTEE_UID with `GET_INFO` permission.
635     let grantor_fn = || {
636         let sl = SecLevel::tee();
637         let access_vector = KeyPermission::GET_INFO.0;
638         let alias = format!("ks_grant_single_{}", getuid());
639         let mut grant_keys = generate_ec_key_and_grant_to_users(
640             &sl,
641             Some(alias),
642             vec![GRANTEE_UID.try_into().unwrap()],
643             access_vector,
644         )
645         .unwrap();
646 
647         grant_keys.remove(0)
648     };
649 
650     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
651     // `--test-threads=1`), and nothing yet done with binder on the main thread.
652     let grant_key_nspace = unsafe { run_as::run_as_app(GRANTOR_UID, GRANTOR_GID, grantor_fn) };
653 
654     // Child function for the grantee context: can load the granted key.
655     let grantee_fn = move || {
656         let keystore2 = get_keystore_service();
657         let rsp = get_granted_key(&keystore2, grant_key_nspace).expect("failed to get granted key");
658 
659         // Return the underlying key ID to simulate an ID leak.
660         assert_eq!(rsp.metadata.key.domain, Domain::KEY_ID);
661         rsp.metadata.key.nspace
662     };
663 
664     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
665     // `--test-threads=1`), and nothing yet done with binder on the main thread.
666     let key_id = unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
667 
668     // Remove the grantee user and create a new user with the same user ID.
669     let overwrite_grantee_user_id_fn = || {
670         let maint = get_maintenance();
671         maint.onUserRemoved(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to remove user");
672         maint.onUserAdded(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to add user");
673     };
674 
675     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
676     // `--test-threads=1`), and nothing yet done with binder on the main thread.
677     unsafe { run_as::run_as_root(overwrite_grantee_user_id_fn) };
678 
679     // Second context identified by <uid, grant_nspace> (where uid is the same because the
680     // now-deleted and newly-created grantee users have the same user ID) does not have access to
681     // the above granted key.
682     let new_grantee_fn = move || {
683         // Check that the key cannot be accessed via grant (i.e. KeyDescriptor with Domain::GRANT).
684         let keystore2 = get_keystore_service();
685         let result = get_granted_key(&keystore2, grant_key_nspace);
686         assert!(result.is_err());
687         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
688 
689         // Check that the key also cannot be accessed via key ID (i.e. KeyDescriptor with
690         // Domain::KEY_ID) if the second context somehow gets a hold of it.
691         let result = map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
692             domain: Domain::KEY_ID,
693             nspace: key_id,
694             alias: None,
695             blob: None,
696         }));
697         assert!(result.is_err());
698         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
699     };
700 
701     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
702     // `--test-threads=1`), and nothing yet done with binder on the main thread.
703     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, new_grantee_fn) };
704 
705     // Clean up: remove grantee user.
706     let remove_grantee_user_id_fn = || {
707         let maint = get_maintenance();
708         maint.onUserRemoved(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to remove user");
709     };
710 
711     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
712     // `--test-threads=1`), and nothing yet done with binder on the main thread.
713     unsafe { run_as::run_as_root(remove_grantee_user_id_fn) };
714 }
715 
716 /// Grant a key to a UID (user ID A + app B) then clear the namespace for user ID A + app B. Check
717 /// that the key can't be loaded by that UID (which would be the UID used if another app were to be
718 /// installed for user ID A with the same application ID B).
719 #[test]
grant_removed_when_grantee_app_uninstalled()720 fn grant_removed_when_grantee_app_uninstalled() {
721     const GRANTOR_USER_ID: u32 = 97;
722     const GRANTOR_APPLICATION_ID: u32 = 10003;
723     static GRANTOR_UID: u32 = GRANTOR_USER_ID * AID_USER_OFFSET + GRANTOR_APPLICATION_ID;
724     static GRANTOR_GID: u32 = GRANTOR_UID;
725 
726     const GRANTEE_USER_ID: u32 = 99;
727     const GRANTEE_APPLICATION_ID: u32 = 10001;
728     static GRANTEE_UID: u32 = GRANTEE_USER_ID * AID_USER_OFFSET + GRANTEE_APPLICATION_ID;
729     static GRANTEE_GID: u32 = GRANTEE_UID;
730 
731     // Add a new user.
732     let create_grantee_user_id_fn = || {
733         let maint = get_maintenance();
734         maint.onUserAdded(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to add user");
735     };
736 
737     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
738     // `--test-threads=1`), and nothing yet done with binder on the main thread.
739     unsafe { run_as::run_as_root(create_grantee_user_id_fn) };
740 
741     // Child function to generate a key and grant it to GRANTEE_UID with `GET_INFO` permission.
742     let grantor_fn = || {
743         let sl = SecLevel::tee();
744         let access_vector = KeyPermission::GET_INFO.0;
745         let alias = format!("ks_grant_single_{}", getuid());
746         let mut grant_keys = generate_ec_key_and_grant_to_users(
747             &sl,
748             Some(alias),
749             vec![GRANTEE_UID.try_into().unwrap()],
750             access_vector,
751         )
752         .unwrap();
753 
754         grant_keys.remove(0)
755     };
756 
757     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
758     // `--test-threads=1`), and nothing yet done with binder on the main thread.
759     let grant_key_nspace = unsafe { run_as::run_as_app(GRANTOR_UID, GRANTOR_GID, grantor_fn) };
760 
761     // Child function for the grantee context: can load the granted key.
762     let grantee_fn = move || {
763         let keystore2 = get_keystore_service();
764         let rsp = get_granted_key(&keystore2, grant_key_nspace).expect("failed to get granted key");
765 
766         // Return the underlying key ID to simulate an ID leak.
767         assert_eq!(rsp.metadata.key.domain, Domain::KEY_ID);
768         rsp.metadata.key.nspace
769     };
770 
771     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
772     // `--test-threads=1`), and nothing yet done with binder on the main thread.
773     let key_id = unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
774 
775     // Clear the app's namespace, which is what happens when an app is uninstalled. Exercising the
776     // full app uninstallation "flow" isn't possible from a Keystore VTS test since we'd need to
777     // exercise the Java code that calls into the Keystore service. So, we can only test the
778     // entrypoint that we know gets triggered during app uninstallation based on the code's control
779     // flow.
780     let clear_grantee_uid_namespace_fn = || {
781         let maint = get_maintenance();
782         maint
783             .clearNamespace(Domain::APP, GRANTEE_UID.try_into().unwrap())
784             .expect("failed to clear namespace");
785     };
786 
787     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
788     // `--test-threads=1`), and nothing yet done with binder on the main thread.
789     unsafe { run_as::run_as_root(clear_grantee_uid_namespace_fn) };
790 
791     // The same context identified by <uid, grant_nspace> not longer has access to the above granted
792     // key. This would be the context if a new app were installed and assigned the same app ID.
793     let new_grantee_fn = move || {
794         // Check that the key cannot be accessed via grant (i.e. KeyDescriptor with Domain::GRANT).
795         let keystore2 = get_keystore_service();
796         let result = get_granted_key(&keystore2, grant_key_nspace);
797         assert!(result.is_err());
798         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
799 
800         // Check that the key also cannot be accessed via key ID (i.e. KeyDescriptor with
801         // Domain::KEY_ID) if the second context somehow gets a hold of it.
802         let result = map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
803             domain: Domain::KEY_ID,
804             nspace: key_id,
805             alias: None,
806             blob: None,
807         }));
808         assert!(result.is_err());
809         assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
810     };
811 
812     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
813     // `--test-threads=1`), and nothing yet done with binder on the main thread.
814     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, new_grantee_fn) };
815 
816     // Clean up: remove grantee user.
817     let remove_grantee_user_id_fn = || {
818         let maint = get_maintenance();
819         maint.onUserRemoved(GRANTEE_USER_ID.try_into().unwrap()).expect("failed to remove user");
820     };
821 
822     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
823     // `--test-threads=1`), and nothing yet done with binder on the main thread.
824     unsafe { run_as::run_as_root(remove_grantee_user_id_fn) };
825 }
826 
827 /// Grant an APP key to the user and immediately ungrant the granted key. In grantee context try to load
828 /// the key. Grantee should fail to load the ungranted key with `KEY_NOT_FOUND` error response.
829 #[test]
ungrant_app_key_success()830 fn ungrant_app_key_success() {
831     const USER_ID: u32 = 99;
832     const APPLICATION_ID: u32 = 10001;
833     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
834     static GRANTEE_GID: u32 = GRANTEE_UID;
835 
836     // Generate a key and grant it to a user with GET_INFO permission.
837     let grantor_fn = || {
838         let sl = SecLevel::tee();
839         let alias = format!("ks_ungrant_test_key_1{}", getuid());
840         let access_vector = KeyPermission::GET_INFO.0;
841         let mut grant_keys = generate_ec_key_and_grant_to_users(
842             &sl,
843             Some(alias.to_string()),
844             vec![GRANTEE_UID.try_into().unwrap()],
845             access_vector,
846         )
847         .unwrap();
848 
849         let grant_key_nspace = grant_keys.remove(0);
850 
851         // Ungrant above granted key.
852         sl.keystore2
853             .ungrant(
854                 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: Some(alias), blob: None },
855                 GRANTEE_UID.try_into().unwrap(),
856             )
857             .unwrap();
858 
859         grant_key_nspace
860     };
861 
862     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
863     // `--test-threads=1`), and nothing yet done with binder.
864     let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
865 
866     // Grantee context, try to load the ungranted key.
867     let grantee_fn = move || {
868         let keystore2 = get_keystore_service();
869         let result = get_granted_key(&keystore2, grant_key_nspace);
870         assert!(result.is_err());
871         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
872     };
873 
874     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
875     // `--test-threads=1`), and nothing yet done with binder.
876     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
877 }
878 
879 /// Generate a key, grant it to the user and then delete the granted key. Try to ungrant
880 /// a deleted key. Test should fail to ungrant a non-existing key with `KEY_NOT_FOUND` error
881 /// response. Generate a new key with the same alias and try to access the previously granted
882 /// key in grantee context. Test should fail to load the granted key in grantee context as the
883 /// associated key is deleted from grantor context.
884 #[test]
ungrant_deleted_app_key_fails()885 fn ungrant_deleted_app_key_fails() {
886     const APPLICATION_ID: u32 = 10001;
887     const USER_ID: u32 = 99;
888     static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
889     static GRANTEE_GID: u32 = GRANTEE_UID;
890 
891     let grantor_fn = || {
892         let sl = SecLevel::tee();
893         let alias = format!("{}{}", "ks_grant_delete_ungrant_test_key_1", getuid());
894 
895         let key_metadata = key_generations::generate_ec_p256_signing_key(
896             &sl,
897             Domain::SELINUX,
898             key_generations::SELINUX_SHELL_NAMESPACE,
899             Some(alias.to_string()),
900             None,
901         )
902         .unwrap();
903 
904         let access_vector = KeyPermission::GET_INFO.0;
905         let grant_key = sl
906             .keystore2
907             .grant(&key_metadata.key, GRANTEE_UID.try_into().unwrap(), access_vector)
908             .unwrap();
909         assert_eq!(grant_key.domain, Domain::GRANT);
910 
911         // Delete above granted key.
912         sl.keystore2.deleteKey(&key_metadata.key).unwrap();
913 
914         // Try to ungrant above granted key.
915         let result =
916             map_ks_error(sl.keystore2.ungrant(&key_metadata.key, GRANTEE_UID.try_into().unwrap()));
917         assert!(result.is_err());
918         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
919 
920         // Generate a new key with the same alias and try to access the earlier granted key
921         // in grantee context.
922         let result = key_generations::generate_ec_p256_signing_key(
923             &sl,
924             Domain::SELINUX,
925             key_generations::SELINUX_SHELL_NAMESPACE,
926             Some(alias),
927             None,
928         );
929         assert!(result.is_ok());
930 
931         grant_key.nspace
932     };
933 
934     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
935     // `--test-threads=1`), and nothing yet done with binder.
936     let grant_key_nspace = unsafe { run_as::run_as_root(grantor_fn) };
937 
938     // Make sure grant did not persist, try to access the earlier granted key in grantee context.
939     // Grantee context should fail to load the granted key as its associated key is deleted in
940     // grantor context.
941     let grantee_fn = move || {
942         let keystore2 = get_keystore_service();
943         let result = get_granted_key(&keystore2, grant_key_nspace);
944         assert!(result.is_err());
945         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
946     };
947 
948     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
949     // `--test-threads=1`), and nothing yet done with binder.
950     unsafe { run_as::run_as_app(GRANTEE_UID, GRANTEE_GID, grantee_fn) };
951 }
952 
953 /// Grant a key to multiple users. Verify that all grantees should succeed in loading the key and
954 /// use it for performing an operation successfully.
955 #[test]
grant_app_key_to_multi_users_success()956 fn grant_app_key_to_multi_users_success() {
957     const APPLICATION_ID: u32 = 10001;
958     const USER_ID_1: u32 = 99;
959     static GRANTEE_1_UID: u32 = USER_ID_1 * AID_USER_OFFSET + APPLICATION_ID;
960     static GRANTEE_1_GID: u32 = GRANTEE_1_UID;
961 
962     const USER_ID_2: u32 = 98;
963     static GRANTEE_2_UID: u32 = USER_ID_2 * AID_USER_OFFSET + APPLICATION_ID;
964     static GRANTEE_2_GID: u32 = GRANTEE_2_UID;
965 
966     // Generate a key and grant it to multiple users with GET_INFO|USE permissions.
967     let grantor_fn = || {
968         let sl = SecLevel::tee();
969         let alias = format!("ks_grant_test_key_2{}", getuid());
970         let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0;
971 
972         generate_ec_key_and_grant_to_users(
973             &sl,
974             Some(alias),
975             vec![GRANTEE_1_UID.try_into().unwrap(), GRANTEE_2_UID.try_into().unwrap()],
976             access_vector,
977         )
978         .unwrap()
979     };
980 
981     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
982     // `--test-threads=1`), and nothing yet done with binder.
983     let mut grant_keys = unsafe { run_as::run_as_root(grantor_fn) };
984 
985     for (grantee_uid, grantee_gid) in
986         &[(GRANTEE_1_UID, GRANTEE_1_GID), (GRANTEE_2_UID, GRANTEE_2_GID)]
987     {
988         let grant_key_nspace = grant_keys.remove(0);
989         let grantee_fn = move || {
990             assert_eq!(Ok(()), sign_with_granted_key(grant_key_nspace));
991         };
992         // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
993         // `--test-threads=1`), and nothing yet done with binder.
994         unsafe { run_as::run_as_app(*grantee_uid, *grantee_gid, grantee_fn) };
995     }
996 }
997 
998 /// Grant a key to multiple users with GET_INFO|DELETE permissions. In one of the grantee context
999 /// use the key and delete it. Try to load the granted key in another grantee context. Test should
1000 /// fail to load the granted key with `KEY_NOT_FOUND` error response.
1001 #[test]
grant_app_key_to_multi_users_delete_then_key_not_found()1002 fn grant_app_key_to_multi_users_delete_then_key_not_found() {
1003     const USER_ID_1: u32 = 99;
1004     const APPLICATION_ID: u32 = 10001;
1005     static GRANTEE_1_UID: u32 = USER_ID_1 * AID_USER_OFFSET + APPLICATION_ID;
1006     static GRANTEE_1_GID: u32 = GRANTEE_1_UID;
1007 
1008     const USER_ID_2: u32 = 98;
1009     static GRANTEE_2_UID: u32 = USER_ID_2 * AID_USER_OFFSET + APPLICATION_ID;
1010     static GRANTEE_2_GID: u32 = GRANTEE_2_UID;
1011 
1012     // Generate a key and grant it to multiple users with GET_INFO permission.
1013     let grantor_fn = || {
1014         let sl = SecLevel::tee();
1015         let alias = format!("ks_grant_test_key_2{}", getuid());
1016         let access_vector =
1017             KeyPermission::GET_INFO.0 | KeyPermission::USE.0 | KeyPermission::DELETE.0;
1018 
1019         generate_ec_key_and_grant_to_users(
1020             &sl,
1021             Some(alias),
1022             vec![GRANTEE_1_UID.try_into().unwrap(), GRANTEE_2_UID.try_into().unwrap()],
1023             access_vector,
1024         )
1025         .unwrap()
1026     };
1027 
1028     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
1029     // `--test-threads=1`), and nothing yet done with binder.
1030     let mut grant_keys = unsafe { run_as::run_as_root(grantor_fn) };
1031 
1032     // Grantee #1 context
1033     let grant_key1_nspace = grant_keys.remove(0);
1034     let grantee1_fn = move || {
1035         assert_eq!(Ok(()), sign_with_granted_key(grant_key1_nspace));
1036 
1037         // Delete the granted key.
1038         get_keystore_service().deleteKey(&granted_key_descriptor(grant_key1_nspace)).unwrap();
1039     };
1040 
1041     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
1042     // `--test-threads=1`), and nothing yet done with binder.
1043     unsafe { run_as::run_as_app(GRANTEE_1_UID, GRANTEE_1_GID, grantee1_fn) };
1044 
1045     // Grantee #2 context
1046     let grant_key2_nspace = grant_keys.remove(0);
1047     let grantee2_fn = move || {
1048         let keystore2 = get_keystore_service();
1049 
1050         let result =
1051             map_ks_error(keystore2.getKeyEntry(&granted_key_descriptor(grant_key2_nspace)));
1052         assert!(result.is_err());
1053         assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
1054     };
1055 
1056     // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
1057     // `--test-threads=1`), and nothing yet done with binder.
1058     unsafe { run_as::run_as_app(GRANTEE_2_UID, GRANTEE_2_GID, grantee2_fn) };
1059 }
1060