xref: /aosp_15_r20/system/security/keystore2/src/service.rs (revision e1997b9af69e3155ead6e072d106a0077849ffba)
1 // Copyright 2020, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! This crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0
16 //! AIDL spec.
17 
18 use std::collections::HashMap;
19 
20 use crate::audit_log::log_key_deleted;
21 use crate::ks_err;
22 use crate::permission::{KeyPerm, KeystorePerm};
23 use crate::security_level::KeystoreSecurityLevel;
24 use crate::utils::{
25     check_grant_permission, check_key_permission, check_keystore_permission, count_key_entries,
26     key_parameters_to_authorizations, list_key_entries, uid_to_android_user, watchdog as wd,
27 };
28 use crate::{
29     database::Uuid,
30     globals::{
31         create_thread_local_db, DB, ENCODED_MODULE_INFO, LEGACY_BLOB_LOADER, LEGACY_IMPORTER,
32         SUPER_KEY,
33     },
34 };
35 use crate::{database::KEYSTORE_UUID, permission};
36 use crate::{
37     database::{KeyEntryLoadBits, KeyType, SubComponentType},
38     error::ResponseCode,
39 };
40 use crate::{
41     error::{self, into_logged_binder, ErrorCode},
42     id_rotation::IdRotationState,
43 };
44 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
45 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::Tag::Tag;
46 use android_hardware_security_keymint::binder::{BinderFeatures, Strong, ThreadState};
47 use android_system_keystore2::aidl::android::system::keystore2::{
48     Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
49     IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
50     KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
51 };
52 use anyhow::{Context, Result};
53 use error::Error;
54 use keystore2_selinux as selinux;
55 
56 /// Implementation of the IKeystoreService.
57 #[derive(Default)]
58 pub struct KeystoreService {
59     i_sec_level_by_uuid: HashMap<Uuid, Strong<dyn IKeystoreSecurityLevel>>,
60     uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
61 }
62 
63 impl KeystoreService {
64     /// Create a new instance of the Keystore 2.0 service.
new_native_binder( id_rotation_state: IdRotationState, ) -> Result<Strong<dyn IKeystoreService>>65     pub fn new_native_binder(
66         id_rotation_state: IdRotationState,
67     ) -> Result<Strong<dyn IKeystoreService>> {
68         let mut result: Self = Default::default();
69         let (dev, uuid) = match KeystoreSecurityLevel::new_native_binder(
70             SecurityLevel::TRUSTED_ENVIRONMENT,
71             id_rotation_state.clone(),
72         ) {
73             Ok(v) => v,
74             Err(e) => {
75                 log::error!("Failed to construct mandatory security level TEE: {e:?}");
76                 log::error!("Does the device have a /default Keymaster or KeyMint instance?");
77                 return Err(e.context(ks_err!("Trying to construct mandatory security level TEE")));
78             }
79         };
80 
81         result.i_sec_level_by_uuid.insert(uuid, dev);
82         result.uuid_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, uuid);
83 
84         // Strongbox is optional, so we ignore errors and turn the result into an Option.
85         if let Ok((dev, uuid)) =
86             KeystoreSecurityLevel::new_native_binder(SecurityLevel::STRONGBOX, id_rotation_state)
87         {
88             result.i_sec_level_by_uuid.insert(uuid, dev);
89             result.uuid_by_sec_level.insert(SecurityLevel::STRONGBOX, uuid);
90         }
91 
92         let uuid_by_sec_level = result.uuid_by_sec_level.clone();
93         LEGACY_IMPORTER
94             .set_init(move || {
95                 (create_thread_local_db(), uuid_by_sec_level, LEGACY_BLOB_LOADER.clone())
96             })
97             .context(ks_err!("Trying to initialize the legacy migrator."))?;
98 
99         Ok(BnKeystoreService::new_binder(
100             result,
101             BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
102         ))
103     }
104 
uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel105     fn uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel {
106         self.uuid_by_sec_level
107             .iter()
108             .find(|(_, v)| **v == *uuid)
109             .map(|(s, _)| *s)
110             .unwrap_or(SecurityLevel::SOFTWARE)
111     }
112 
get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>>113     fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
114         if let Some(dev) = self.i_sec_level_by_uuid.get(uuid) {
115             Ok(dev.clone())
116         } else {
117             Err(error::Error::sys()).context(ks_err!("KeyMint instance for key not found."))
118         }
119     }
120 
get_security_level( &self, sec_level: SecurityLevel, ) -> Result<Strong<dyn IKeystoreSecurityLevel>>121     fn get_security_level(
122         &self,
123         sec_level: SecurityLevel,
124     ) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
125         if let Some(dev) = self
126             .uuid_by_sec_level
127             .get(&sec_level)
128             .and_then(|uuid| self.i_sec_level_by_uuid.get(uuid))
129         {
130             Ok(dev.clone())
131         } else {
132             Err(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
133                 .context(ks_err!("No such security level."))
134         }
135     }
136 
get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse>137     fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
138         let caller_uid = ThreadState::get_calling_uid();
139 
140         let super_key = SUPER_KEY
141             .read()
142             .unwrap()
143             .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
144 
145         let (key_id_guard, mut key_entry) = DB
146             .with(|db| {
147                 LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
148                     db.borrow_mut().load_key_entry(
149                         key,
150                         KeyType::Client,
151                         KeyEntryLoadBits::PUBLIC,
152                         caller_uid,
153                         |k, av| check_key_permission(KeyPerm::GetInfo, k, &av),
154                     )
155                 })
156             })
157             .context(ks_err!("while trying to load key info."))?;
158 
159         let i_sec_level = if !key_entry.pure_cert() {
160             Some(
161                 self.get_i_sec_level_by_uuid(key_entry.km_uuid())
162                     .context(ks_err!("Trying to get security level proxy."))?,
163             )
164         } else {
165             None
166         };
167 
168         Ok(KeyEntryResponse {
169             iSecurityLevel: i_sec_level,
170             metadata: KeyMetadata {
171                 key: KeyDescriptor {
172                     domain: Domain::KEY_ID,
173                     nspace: key_id_guard.id(),
174                     ..Default::default()
175                 },
176                 keySecurityLevel: self.uuid_to_sec_level(key_entry.km_uuid()),
177                 certificate: key_entry.take_cert(),
178                 certificateChain: key_entry.take_cert_chain(),
179                 modificationTimeMs: key_entry
180                     .metadata()
181                     .creation_date()
182                     .map(|d| d.to_millis_epoch())
183                     .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED))
184                     .context(ks_err!("Trying to get creation date."))?,
185                 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
186             },
187         })
188     }
189 
update_subcomponent( &self, key: &KeyDescriptor, public_cert: Option<&[u8]>, certificate_chain: Option<&[u8]>, ) -> Result<()>190     fn update_subcomponent(
191         &self,
192         key: &KeyDescriptor,
193         public_cert: Option<&[u8]>,
194         certificate_chain: Option<&[u8]>,
195     ) -> Result<()> {
196         let caller_uid = ThreadState::get_calling_uid();
197         let super_key = SUPER_KEY
198             .read()
199             .unwrap()
200             .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
201 
202         DB.with::<_, Result<()>>(|db| {
203             let entry = match LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
204                 db.borrow_mut().load_key_entry(
205                     key,
206                     KeyType::Client,
207                     KeyEntryLoadBits::NONE,
208                     caller_uid,
209                     |k, av| check_key_permission(KeyPerm::Update, k, &av).context(ks_err!()),
210                 )
211             }) {
212                 Err(e) => match e.root_cause().downcast_ref::<Error>() {
213                     Some(Error::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None),
214                     _ => Err(e),
215                 },
216                 Ok(v) => Ok(Some(v)),
217             }
218             .context(ks_err!("Failed to load key entry."))?;
219 
220             let mut db = db.borrow_mut();
221             if let Some((key_id_guard, _key_entry)) = entry {
222                 db.set_blob(&key_id_guard, SubComponentType::CERT, public_cert, None)
223                     .context(ks_err!("Failed to update cert subcomponent."))?;
224 
225                 db.set_blob(&key_id_guard, SubComponentType::CERT_CHAIN, certificate_chain, None)
226                     .context(ks_err!("Failed to update cert chain subcomponent."))?;
227                 return Ok(());
228             }
229 
230             // If we reach this point we have to check the special condition where a certificate
231             // entry may be made.
232             if !(public_cert.is_none() && certificate_chain.is_some()) {
233                 return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
234                     .context(ks_err!("No key to update."));
235             }
236 
237             // So we know that we have a certificate chain and no public cert.
238             // Now check that we have everything we need to make a new certificate entry.
239             let key = match (key.domain, &key.alias) {
240                 (Domain::APP, Some(ref alias)) => KeyDescriptor {
241                     domain: Domain::APP,
242                     nspace: ThreadState::get_calling_uid() as i64,
243                     alias: Some(alias.clone()),
244                     blob: None,
245                 },
246                 (Domain::SELINUX, Some(_)) => key.clone(),
247                 _ => {
248                     return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT))
249                         .context(ks_err!("Domain must be APP or SELINUX to insert a certificate."))
250                 }
251             };
252 
253             // Security critical: This must return on failure. Do not remove the `?`;
254             check_key_permission(KeyPerm::Rebind, &key, &None)
255                 .context(ks_err!("Caller does not have permission to insert this certificate."))?;
256 
257             db.store_new_certificate(
258                 &key,
259                 KeyType::Client,
260                 certificate_chain.unwrap(),
261                 &KEYSTORE_UUID,
262             )
263             .context(ks_err!("Failed to insert new certificate."))?;
264             Ok(())
265         })
266         .context(ks_err!())
267     }
268 
get_key_descriptor_for_lookup( &self, domain: Domain, namespace: i64, ) -> Result<KeyDescriptor>269     fn get_key_descriptor_for_lookup(
270         &self,
271         domain: Domain,
272         namespace: i64,
273     ) -> Result<KeyDescriptor> {
274         let mut k = match domain {
275             Domain::APP => KeyDescriptor {
276                 domain,
277                 nspace: ThreadState::get_calling_uid() as u64 as i64,
278                 ..Default::default()
279             },
280             Domain::SELINUX => KeyDescriptor { domain, nspace: namespace, ..Default::default() },
281             _ => {
282                 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(ks_err!(
283                     "List entries is only supported for Domain::APP and Domain::SELINUX."
284                 ))
285             }
286         };
287 
288         // First we check if the caller has the info permission for the selected domain/namespace.
289         // By default we use the calling uid as namespace if domain is Domain::APP.
290         // If the first check fails we check if the caller has the list permission allowing to list
291         // any namespace. In that case we also adjust the queried namespace if a specific uid was
292         // selected.
293         if let Err(e) = check_key_permission(KeyPerm::GetInfo, &k, &None) {
294             if let Some(selinux::Error::PermissionDenied) =
295                 e.root_cause().downcast_ref::<selinux::Error>()
296             {
297                 check_keystore_permission(KeystorePerm::List)
298                     .context(ks_err!("While checking keystore permission."))?;
299                 if namespace != -1 {
300                     k.nspace = namespace;
301                 }
302             } else {
303                 return Err(e).context(ks_err!("While checking key permission."))?;
304             }
305         }
306         Ok(k)
307     }
308 
list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>>309     fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
310         let k = self.get_key_descriptor_for_lookup(domain, namespace)?;
311 
312         DB.with(|db| list_key_entries(&mut db.borrow_mut(), k.domain, k.nspace, None))
313     }
314 
count_num_entries(&self, domain: Domain, namespace: i64) -> Result<i32>315     fn count_num_entries(&self, domain: Domain, namespace: i64) -> Result<i32> {
316         let k = self.get_key_descriptor_for_lookup(domain, namespace)?;
317 
318         DB.with(|db| count_key_entries(&mut db.borrow_mut(), k.domain, k.nspace))
319     }
320 
get_supplementary_attestation_info(&self, tag: Tag) -> Result<Vec<u8>>321     fn get_supplementary_attestation_info(&self, tag: Tag) -> Result<Vec<u8>> {
322         match tag {
323             Tag::MODULE_HASH => {
324                 let info = ENCODED_MODULE_INFO.read().unwrap();
325                 (*info)
326                     .clone()
327                     .ok_or(Error::Rc(ResponseCode::INFO_NOT_AVAILABLE))
328                     .context(ks_err!("Module info not received."))
329             }
330             _ => Err(Error::Rc(ResponseCode::INVALID_ARGUMENT))
331                 .context(ks_err!("Tag {tag:?} not supported for getSupplementaryAttestationInfo.")),
332         }
333     }
334 
list_entries_batched( &self, domain: Domain, namespace: i64, start_past_alias: Option<&str>, ) -> Result<Vec<KeyDescriptor>>335     fn list_entries_batched(
336         &self,
337         domain: Domain,
338         namespace: i64,
339         start_past_alias: Option<&str>,
340     ) -> Result<Vec<KeyDescriptor>> {
341         let k = self.get_key_descriptor_for_lookup(domain, namespace)?;
342         DB.with(|db| list_key_entries(&mut db.borrow_mut(), k.domain, k.nspace, start_past_alias))
343     }
344 
delete_key(&self, key: &KeyDescriptor) -> Result<()>345     fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
346         let caller_uid = ThreadState::get_calling_uid();
347         let super_key = SUPER_KEY
348             .read()
349             .unwrap()
350             .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
351 
352         DB.with(|db| {
353             LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
354                 db.borrow_mut().unbind_key(key, KeyType::Client, caller_uid, |k, av| {
355                     check_key_permission(KeyPerm::Delete, k, &av)
356                         .context(ks_err!("During delete_key."))
357                 })
358             })
359         })
360         .context(ks_err!("Trying to unbind the key."))?;
361         Ok(())
362     }
363 
grant( &self, key: &KeyDescriptor, grantee_uid: i32, access_vector: permission::KeyPermSet, ) -> Result<KeyDescriptor>364     fn grant(
365         &self,
366         key: &KeyDescriptor,
367         grantee_uid: i32,
368         access_vector: permission::KeyPermSet,
369     ) -> Result<KeyDescriptor> {
370         let caller_uid = ThreadState::get_calling_uid();
371         let super_key = SUPER_KEY
372             .read()
373             .unwrap()
374             .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
375 
376         DB.with(|db| {
377             LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
378                 db.borrow_mut().grant(
379                     key,
380                     caller_uid,
381                     grantee_uid as u32,
382                     access_vector,
383                     |k, av| check_grant_permission(*av, k).context("During grant."),
384                 )
385             })
386         })
387         .context(ks_err!("KeystoreService::grant."))
388     }
389 
ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()>390     fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
391         DB.with(|db| {
392             db.borrow_mut().ungrant(key, ThreadState::get_calling_uid(), grantee_uid as u32, |k| {
393                 check_key_permission(KeyPerm::Grant, k, &None)
394             })
395         })
396         .context(ks_err!("KeystoreService::ungrant."))
397     }
398 }
399 
400 impl binder::Interface for KeystoreService {}
401 
402 // Implementation of IKeystoreService. See AIDL spec at
403 // system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
404 impl IKeystoreService for KeystoreService {
getSecurityLevel( &self, security_level: SecurityLevel, ) -> binder::Result<Strong<dyn IKeystoreSecurityLevel>>405     fn getSecurityLevel(
406         &self,
407         security_level: SecurityLevel,
408     ) -> binder::Result<Strong<dyn IKeystoreSecurityLevel>> {
409         let _wp = wd::watch_millis_with("IKeystoreService::getSecurityLevel", 500, security_level);
410         self.get_security_level(security_level).map_err(into_logged_binder)
411     }
getKeyEntry(&self, key: &KeyDescriptor) -> binder::Result<KeyEntryResponse>412     fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::Result<KeyEntryResponse> {
413         let _wp = wd::watch("IKeystoreService::get_key_entry");
414         self.get_key_entry(key).map_err(into_logged_binder)
415     }
updateSubcomponent( &self, key: &KeyDescriptor, public_cert: Option<&[u8]>, certificate_chain: Option<&[u8]>, ) -> binder::Result<()>416     fn updateSubcomponent(
417         &self,
418         key: &KeyDescriptor,
419         public_cert: Option<&[u8]>,
420         certificate_chain: Option<&[u8]>,
421     ) -> binder::Result<()> {
422         let _wp = wd::watch("IKeystoreService::updateSubcomponent");
423         self.update_subcomponent(key, public_cert, certificate_chain).map_err(into_logged_binder)
424     }
listEntries(&self, domain: Domain, namespace: i64) -> binder::Result<Vec<KeyDescriptor>>425     fn listEntries(&self, domain: Domain, namespace: i64) -> binder::Result<Vec<KeyDescriptor>> {
426         let _wp = wd::watch("IKeystoreService::listEntries");
427         self.list_entries(domain, namespace).map_err(into_logged_binder)
428     }
deleteKey(&self, key: &KeyDescriptor) -> binder::Result<()>429     fn deleteKey(&self, key: &KeyDescriptor) -> binder::Result<()> {
430         let _wp = wd::watch("IKeystoreService::deleteKey");
431         let result = self.delete_key(key);
432         log_key_deleted(key, ThreadState::get_calling_uid(), result.is_ok());
433         result.map_err(into_logged_binder)
434     }
grant( &self, key: &KeyDescriptor, grantee_uid: i32, access_vector: i32, ) -> binder::Result<KeyDescriptor>435     fn grant(
436         &self,
437         key: &KeyDescriptor,
438         grantee_uid: i32,
439         access_vector: i32,
440     ) -> binder::Result<KeyDescriptor> {
441         let _wp = wd::watch("IKeystoreService::grant");
442         self.grant(key, grantee_uid, access_vector.into()).map_err(into_logged_binder)
443     }
ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::Result<()>444     fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::Result<()> {
445         let _wp = wd::watch("IKeystoreService::ungrant");
446         self.ungrant(key, grantee_uid).map_err(into_logged_binder)
447     }
listEntriesBatched( &self, domain: Domain, namespace: i64, start_past_alias: Option<&str>, ) -> binder::Result<Vec<KeyDescriptor>>448     fn listEntriesBatched(
449         &self,
450         domain: Domain,
451         namespace: i64,
452         start_past_alias: Option<&str>,
453     ) -> binder::Result<Vec<KeyDescriptor>> {
454         let _wp = wd::watch("IKeystoreService::listEntriesBatched");
455         self.list_entries_batched(domain, namespace, start_past_alias).map_err(into_logged_binder)
456     }
457 
getNumberOfEntries(&self, domain: Domain, namespace: i64) -> binder::Result<i32>458     fn getNumberOfEntries(&self, domain: Domain, namespace: i64) -> binder::Result<i32> {
459         let _wp = wd::watch("IKeystoreService::getNumberOfEntries");
460         self.count_num_entries(domain, namespace).map_err(into_logged_binder)
461     }
462 
getSupplementaryAttestationInfo(&self, tag: Tag) -> binder::Result<Vec<u8>>463     fn getSupplementaryAttestationInfo(&self, tag: Tag) -> binder::Result<Vec<u8>> {
464         if keystore2_flags::attest_modules() {
465             let _wp = wd::watch("IKeystoreService::getSupplementaryAttestationInfo");
466             self.get_supplementary_attestation_info(tag).map_err(into_logged_binder)
467         } else {
468             log::error!("attest_modules flag is not toggled");
469             Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
470         }
471     }
472 }
473