blob: 85ac7bc4d11c66a54ebe1108467f9faf3ab51b37 [file] [log] [blame]
Janis Danisevskis1af91262020-08-10 14:58:08 -07001// Copyright 2020, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Janis Danisevskis1af91262020-08-10 14:58:08 -070015//! This crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0
16//! AIDL spec.
17
Max Bires8e93d2b2021-01-14 13:17:59 -080018use std::collections::HashMap;
19
Pavel Grafov94243c22021-04-21 18:03:11 +010020use crate::audit_log::log_key_deleted;
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +000021use crate::ks_err;
Janis Danisevskise92a5e62020-12-02 12:57:41 -080022use crate::permission::{KeyPerm, KeystorePerm};
Janis Danisevskis1af91262020-08-10 14:58:08 -070023use crate::security_level::KeystoreSecurityLevel;
Janis Danisevskis04b02832020-10-26 09:21:40 -070024use crate::utils::{
Eran Messeri24f31972023-01-25 17:00:33 +000025 check_grant_permission, check_key_permission, check_keystore_permission, count_key_entries,
Janis Danisevskisf84d0b02022-01-26 14:11:14 -080026 key_parameters_to_authorizations, list_key_entries, uid_to_android_user, watchdog as wd,
Janis Danisevskis04b02832020-10-26 09:21:40 -070027};
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000028use crate::{
29 database::Uuid,
Karuna Wadhera1cfc81d2024-11-07 23:35:51 +000030 globals::{
31 create_thread_local_db, DB, ENCODED_MODULE_INFO, LEGACY_BLOB_LOADER, LEGACY_IMPORTER,
32 SUPER_KEY,
33 },
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000034};
Max Bires8e93d2b2021-01-14 13:17:59 -080035use crate::{database::KEYSTORE_UUID, permission};
Janis Danisevskisb42fc182020-12-15 08:41:27 -080036use crate::{
37 database::{KeyEntryLoadBits, KeyType, SubComponentType},
38 error::ResponseCode,
39};
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070040use crate::{
David Drysdaledb7ddde2024-06-07 16:22:49 +010041 error::{self, into_logged_binder, ErrorCode},
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070042 id_rotation::IdRotationState,
43};
Shawn Willden708744a2020-12-11 13:05:27 +000044use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
Karuna Wadhera1cfc81d2024-11-07 23:35:51 +000045use android_hardware_security_keymint::aidl::android::hardware::security::keymint::Tag::Tag;
Andrew Walbrande45c8b2021-04-13 14:42:38 +000046use android_hardware_security_keymint::binder::{BinderFeatures, Strong, ThreadState};
Janis Danisevskis1af91262020-08-10 14:58:08 -070047use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070048 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
49 IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
50 KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
Janis Danisevskis1af91262020-08-10 14:58:08 -070051};
Max Bires8e93d2b2021-01-14 13:17:59 -080052use anyhow::{Context, Result};
Janis Danisevskise92a5e62020-12-02 12:57:41 -080053use error::Error;
54use keystore2_selinux as selinux;
Janis Danisevskis1af91262020-08-10 14:58:08 -070055
56/// Implementation of the IKeystoreService.
Max Bires8e93d2b2021-01-14 13:17:59 -080057#[derive(Default)]
Janis Danisevskis1af91262020-08-10 14:58:08 -070058pub struct KeystoreService {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -070059 i_sec_level_by_uuid: HashMap<Uuid, Strong<dyn IKeystoreSecurityLevel>>,
Max Bires8e93d2b2021-01-14 13:17:59 -080060 uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
Janis Danisevskis1af91262020-08-10 14:58:08 -070061}
62
63impl KeystoreService {
64 /// Create a new instance of the Keystore 2.0 service.
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070065 pub fn new_native_binder(
66 id_rotation_state: IdRotationState,
67 ) -> Result<Strong<dyn IKeystoreService>> {
Max Bires8e93d2b2021-01-14 13:17:59 -080068 let mut result: Self = Default::default();
David Drysdale18c29f32024-07-19 12:54:19 +010069 let (dev, uuid) = match KeystoreSecurityLevel::new_native_binder(
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070070 SecurityLevel::TRUSTED_ENVIRONMENT,
71 id_rotation_state.clone(),
David Drysdale18c29f32024-07-19 12:54:19 +010072 ) {
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
Max Bires8e93d2b2021-01-14 13:17:59 -080081 result.i_sec_level_by_uuid.insert(uuid, dev);
82 result.uuid_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, uuid);
Janis Danisevskisba998992020-12-29 16:08:40 -080083
Max Bires8e93d2b2021-01-14 13:17:59 -080084 // Strongbox is optional, so we ignore errors and turn the result into an Option.
Janis Danisevskis5cb52dc2021-04-07 16:31:18 -070085 if let Ok((dev, uuid)) =
86 KeystoreSecurityLevel::new_native_binder(SecurityLevel::STRONGBOX, id_rotation_state)
Max Bires8e93d2b2021-01-14 13:17:59 -080087 {
88 result.i_sec_level_by_uuid.insert(uuid, dev);
89 result.uuid_by_sec_level.insert(SecurityLevel::STRONGBOX, uuid);
90 }
91
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000092 let uuid_by_sec_level = result.uuid_by_sec_level.clone();
Janis Danisevskis0ffb8a82022-02-06 22:37:21 -080093 LEGACY_IMPORTER
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000094 .set_init(move || {
95 (create_thread_local_db(), uuid_by_sec_level, LEGACY_BLOB_LOADER.clone())
96 })
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +000097 .context(ks_err!("Trying to initialize the legacy migrator."))?;
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000098
Andrew Walbrande45c8b2021-04-13 14:42:38 +000099 Ok(BnKeystoreService::new_binder(
100 result,
101 BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
102 ))
Janis Danisevskis1af91262020-08-10 14:58:08 -0700103 }
104
Max Bires8e93d2b2021-01-14 13:17:59 -0800105 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
Stephen Crane221bbb52020-12-16 15:52:10 -0800113 fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800114 if let Some(dev) = self.i_sec_level_by_uuid.get(uuid) {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700115 Ok(dev.clone())
Max Bires8e93d2b2021-01-14 13:17:59 -0800116 } else {
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000117 Err(error::Error::sys()).context(ks_err!("KeyMint instance for key not found."))
Max Bires8e93d2b2021-01-14 13:17:59 -0800118 }
Janis Danisevskisba998992020-12-29 16:08:40 -0800119 }
120
Janis Danisevskis1af91262020-08-10 14:58:08 -0700121 fn get_security_level(
122 &self,
Max Bires8e93d2b2021-01-14 13:17:59 -0800123 sec_level: SecurityLevel,
Stephen Crane221bbb52020-12-16 15:52:10 -0800124 ) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800125 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 {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700130 Ok(dev.clone())
Max Bires8e93d2b2021-01-14 13:17:59 -0800131 } else {
132 Err(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000133 .context(ks_err!("No such security level."))
Max Bires8e93d2b2021-01-14 13:17:59 -0800134 }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700135 }
136
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700137 fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000138 let caller_uid = ThreadState::get_calling_uid();
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800139
Eric Biggers673d34a2023-10-18 01:54:18 +0000140 let super_key = SUPER_KEY
141 .read()
142 .unwrap()
143 .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800144
Janis Danisevskisaec14592020-11-12 09:41:49 -0800145 let (key_id_guard, mut key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -0700146 .with(|db| {
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800147 LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000148 db.borrow_mut().load_key_entry(
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700149 key,
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000150 KeyType::Client,
151 KeyEntryLoadBits::PUBLIC,
152 caller_uid,
Janis Danisevskis39d57e72021-10-19 16:56:20 -0700153 |k, av| check_key_permission(KeyPerm::GetInfo, k, &av),
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000154 )
155 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700156 })
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000157 .context(ks_err!("while trying to load key info."))?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700158
Janis Danisevskis377d1002021-01-27 19:07:48 -0800159 let i_sec_level = if !key_entry.pure_cert() {
160 Some(
Max Bires8e93d2b2021-01-14 13:17:59 -0800161 self.get_i_sec_level_by_uuid(key_entry.km_uuid())
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000162 .context(ks_err!("Trying to get security level proxy."))?,
Janis Danisevskis377d1002021-01-27 19:07:48 -0800163 )
164 } else {
165 None
166 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700167
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700168 Ok(KeyEntryResponse {
Janis Danisevskis377d1002021-01-27 19:07:48 -0800169 iSecurityLevel: i_sec_level,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700170 metadata: KeyMetadata {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700171 key: KeyDescriptor {
172 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800173 nspace: key_id_guard.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700174 ..Default::default()
175 },
Max Bires8e93d2b2021-01-14 13:17:59 -0800176 keySecurityLevel: self.uuid_to_sec_level(key_entry.km_uuid()),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700177 certificate: key_entry.take_cert(),
178 certificateChain: key_entry.take_cert_chain(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800179 modificationTimeMs: key_entry
180 .metadata()
181 .creation_date()
182 .map(|d| d.to_millis_epoch())
183 .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED))
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000184 .context(ks_err!("Trying to get creation date."))?,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700185 authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700186 },
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700187 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700188 }
189
190 fn update_subcomponent(
191 &self,
192 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700193 public_cert: Option<&[u8]>,
194 certificate_chain: Option<&[u8]>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700195 ) -> Result<()> {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000196 let caller_uid = ThreadState::get_calling_uid();
Eric Biggers673d34a2023-10-18 01:54:18 +0000197 let super_key = SUPER_KEY
198 .read()
199 .unwrap()
200 .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800201
Janis Danisevskis1af91262020-08-10 14:58:08 -0700202 DB.with::<_, Result<()>>(|db| {
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800203 let entry = match LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000204 db.borrow_mut().load_key_entry(
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700205 key,
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000206 KeyType::Client,
207 KeyEntryLoadBits::NONE,
208 caller_uid,
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000209 |k, av| check_key_permission(KeyPerm::Update, k, &av).context(ks_err!()),
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000210 )
211 }) {
Janis Danisevskis377d1002021-01-27 19:07:48 -0800212 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 }
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000218 .context(ks_err!("Failed to load key entry."))?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700219
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000220 let mut db = db.borrow_mut();
Paul Crowleyd5653e52021-03-25 09:46:31 -0700221 if let Some((key_id_guard, _key_entry)) = entry {
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800222 db.set_blob(&key_id_guard, SubComponentType::CERT, public_cert, None)
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000223 .context(ks_err!("Failed to update cert subcomponent."))?;
Janis Danisevskis377d1002021-01-27 19:07:48 -0800224
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800225 db.set_blob(&key_id_guard, SubComponentType::CERT_CHAIN, certificate_chain, None)
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000226 .context(ks_err!("Failed to update cert chain subcomponent."))?;
Janis Danisevskis377d1002021-01-27 19:07:48 -0800227 return Ok(());
Janis Danisevskis1af91262020-08-10 14:58:08 -0700228 }
229
Janis Danisevskis377d1002021-01-27 19:07:48 -0800230 // 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()) {
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000233 return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
234 .context(ks_err!("No key to update."));
Janis Danisevskis1af91262020-08-10 14:58:08 -0700235 }
Janis Danisevskis377d1002021-01-27 19:07:48 -0800236
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))
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000249 .context(ks_err!("Domain must be APP or SELINUX to insert a certificate."))
Janis Danisevskis377d1002021-01-27 19:07:48 -0800250 }
251 };
252
253 // Security critical: This must return on failure. Do not remove the `?`;
Janis Danisevskis39d57e72021-10-19 16:56:20 -0700254 check_key_permission(KeyPerm::Rebind, &key, &None)
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000255 .context(ks_err!("Caller does not have permission to insert this certificate."))?;
Janis Danisevskis377d1002021-01-27 19:07:48 -0800256
Janis Danisevskis0cabd712021-05-25 11:07:10 -0700257 db.store_new_certificate(
258 &key,
259 KeyType::Client,
260 certificate_chain.unwrap(),
261 &KEYSTORE_UUID,
262 )
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000263 .context(ks_err!("Failed to insert new certificate."))?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700264 Ok(())
265 })
Shaquille Johnsonaec2eca2022-11-30 17:08:05 +0000266 .context(ks_err!())
Janis Danisevskis1af91262020-08-10 14:58:08 -0700267 }
268
Eran Messeri24f31972023-01-25 17:00:33 +0000269 fn get_key_descriptor_for_lookup(
270 &self,
271 domain: Domain,
272 namespace: i64,
273 ) -> Result<KeyDescriptor> {
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800274 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 },
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000280 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 }
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800286 };
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.
Chris Wailes20f50df2022-04-19 17:23:52 -0700293 if let Err(e) = check_key_permission(KeyPerm::GetInfo, &k, &None) {
294 if let Some(selinux::Error::PermissionDenied) =
Rajesh Nyamagoud16198a32022-07-26 18:45:55 +0000295 e.root_cause().downcast_ref::<selinux::Error>()
296 {
Chris Wailes20f50df2022-04-19 17:23:52 -0700297 check_keystore_permission(KeystorePerm::List)
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000298 .context(ks_err!("While checking keystore permission."))?;
Chris Wailes20f50df2022-04-19 17:23:52 -0700299 if namespace != -1 {
300 k.nspace = namespace;
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800301 }
Chris Wailes20f50df2022-04-19 17:23:52 -0700302 } else {
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000303 return Err(e).context(ks_err!("While checking key permission."))?;
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800304 }
Chris Wailes20f50df2022-04-19 17:23:52 -0700305 }
Eran Messeri24f31972023-01-25 17:00:33 +0000306 Ok(k)
307 }
Janis Danisevskise92a5e62020-12-02 12:57:41 -0800308
Eran Messeri24f31972023-01-25 17:00:33 +0000309 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
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
Karuna Wadhera1cfc81d2024-11-07 23:35:51 +0000321 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
Eran Messeri24f31972023-01-25 17:00:33 +0000335 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))
Janis Danisevskis1af91262020-08-10 14:58:08 -0700343 }
344
345 fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
Janis Danisevskis93927dd2020-12-23 12:23:08 -0800346 let caller_uid = ThreadState::get_calling_uid();
Eric Biggers673d34a2023-10-18 01:54:18 +0000347 let super_key = SUPER_KEY
348 .read()
349 .unwrap()
350 .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800351
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800352 DB.with(|db| {
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800353 LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700354 db.borrow_mut().unbind_key(key, KeyType::Client, caller_uid, |k, av| {
Shaquille Johnsone8b152a2023-02-09 15:15:50 +0000355 check_key_permission(KeyPerm::Delete, k, &av)
356 .context(ks_err!("During delete_key."))
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000357 })
Janis Danisevskis93927dd2020-12-23 12:23:08 -0800358 })
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800359 })
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000360 .context(ks_err!("Trying to unbind the key."))?;
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -0800361 Ok(())
Janis Danisevskis1af91262020-08-10 14:58:08 -0700362 }
363
364 fn grant(
365 &self,
366 key: &KeyDescriptor,
367 grantee_uid: i32,
368 access_vector: permission::KeyPermSet,
369 ) -> Result<KeyDescriptor> {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000370 let caller_uid = ThreadState::get_calling_uid();
Eric Biggers673d34a2023-10-18 01:54:18 +0000371 let super_key = SUPER_KEY
372 .read()
373 .unwrap()
374 .get_after_first_unlock_key_by_user_id(uid_to_android_user(caller_uid));
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800375
Janis Danisevskis1af91262020-08-10 14:58:08 -0700376 DB.with(|db| {
Janis Danisevskisf84d0b02022-01-26 14:11:14 -0800377 LEGACY_IMPORTER.with_try_import(key, caller_uid, super_key, || {
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000378 db.borrow_mut().grant(
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700379 key,
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +0000380 caller_uid,
381 grantee_uid as u32,
382 access_vector,
383 |k, av| check_grant_permission(*av, k).context("During grant."),
384 )
385 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700386 })
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000387 .context(ks_err!("KeystoreService::grant."))
Janis Danisevskis1af91262020-08-10 14:58:08 -0700388 }
389
390 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
391 DB.with(|db| {
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700392 db.borrow_mut().ungrant(key, ThreadState::get_calling_uid(), grantee_uid as u32, |k| {
Janis Danisevskis39d57e72021-10-19 16:56:20 -0700393 check_key_permission(KeyPerm::Grant, k, &None)
Janis Danisevskis66784c42021-01-27 08:40:25 -0800394 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700395 })
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000396 .context(ks_err!("KeystoreService::ungrant."))
Janis Danisevskis1af91262020-08-10 14:58:08 -0700397 }
398}
399
400impl binder::Interface for KeystoreService {}
401
402// Implementation of IKeystoreService. See AIDL spec at
403// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
404impl IKeystoreService for KeystoreService {
405 fn getSecurityLevel(
406 &self,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700407 security_level: SecurityLevel,
Stephen Crane23cf7242022-01-19 17:49:46 +0000408 ) -> binder::Result<Strong<dyn IKeystoreSecurityLevel>> {
David Drysdale387c85b2024-06-10 14:40:45 +0100409 let _wp = wd::watch_millis_with("IKeystoreService::getSecurityLevel", 500, security_level);
David Drysdaledb7ddde2024-06-07 16:22:49 +0100410 self.get_security_level(security_level).map_err(into_logged_binder)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700411 }
Stephen Crane23cf7242022-01-19 17:49:46 +0000412 fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::Result<KeyEntryResponse> {
David Drysdale541846b2024-05-23 13:16:07 +0100413 let _wp = wd::watch("IKeystoreService::get_key_entry");
David Drysdaledb7ddde2024-06-07 16:22:49 +0100414 self.get_key_entry(key).map_err(into_logged_binder)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700415 }
416 fn updateSubcomponent(
417 &self,
418 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700419 public_cert: Option<&[u8]>,
420 certificate_chain: Option<&[u8]>,
Stephen Crane23cf7242022-01-19 17:49:46 +0000421 ) -> binder::Result<()> {
David Drysdale541846b2024-05-23 13:16:07 +0100422 let _wp = wd::watch("IKeystoreService::updateSubcomponent");
David Drysdaledb7ddde2024-06-07 16:22:49 +0100423 self.update_subcomponent(key, public_cert, certificate_chain).map_err(into_logged_binder)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700424 }
Stephen Crane23cf7242022-01-19 17:49:46 +0000425 fn listEntries(&self, domain: Domain, namespace: i64) -> binder::Result<Vec<KeyDescriptor>> {
David Drysdale541846b2024-05-23 13:16:07 +0100426 let _wp = wd::watch("IKeystoreService::listEntries");
David Drysdaledb7ddde2024-06-07 16:22:49 +0100427 self.list_entries(domain, namespace).map_err(into_logged_binder)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700428 }
Stephen Crane23cf7242022-01-19 17:49:46 +0000429 fn deleteKey(&self, key: &KeyDescriptor) -> binder::Result<()> {
David Drysdale541846b2024-05-23 13:16:07 +0100430 let _wp = wd::watch("IKeystoreService::deleteKey");
Pavel Grafov94243c22021-04-21 18:03:11 +0100431 let result = self.delete_key(key);
432 log_key_deleted(key, ThreadState::get_calling_uid(), result.is_ok());
David Drysdaledb7ddde2024-06-07 16:22:49 +0100433 result.map_err(into_logged_binder)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700434 }
435 fn grant(
436 &self,
437 key: &KeyDescriptor,
438 grantee_uid: i32,
439 access_vector: i32,
Stephen Crane23cf7242022-01-19 17:49:46 +0000440 ) -> binder::Result<KeyDescriptor> {
David Drysdale541846b2024-05-23 13:16:07 +0100441 let _wp = wd::watch("IKeystoreService::grant");
David Drysdaledb7ddde2024-06-07 16:22:49 +0100442 self.grant(key, grantee_uid, access_vector.into()).map_err(into_logged_binder)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700443 }
Stephen Crane23cf7242022-01-19 17:49:46 +0000444 fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::Result<()> {
David Drysdale541846b2024-05-23 13:16:07 +0100445 let _wp = wd::watch("IKeystoreService::ungrant");
David Drysdaledb7ddde2024-06-07 16:22:49 +0100446 self.ungrant(key, grantee_uid).map_err(into_logged_binder)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700447 }
Eran Messeri24f31972023-01-25 17:00:33 +0000448 fn listEntriesBatched(
449 &self,
450 domain: Domain,
451 namespace: i64,
452 start_past_alias: Option<&str>,
453 ) -> binder::Result<Vec<KeyDescriptor>> {
David Drysdale541846b2024-05-23 13:16:07 +0100454 let _wp = wd::watch("IKeystoreService::listEntriesBatched");
David Drysdaledb7ddde2024-06-07 16:22:49 +0100455 self.list_entries_batched(domain, namespace, start_past_alias).map_err(into_logged_binder)
Eran Messeri24f31972023-01-25 17:00:33 +0000456 }
457
458 fn getNumberOfEntries(&self, domain: Domain, namespace: i64) -> binder::Result<i32> {
David Drysdale541846b2024-05-23 13:16:07 +0100459 let _wp = wd::watch("IKeystoreService::getNumberOfEntries");
David Drysdaledb7ddde2024-06-07 16:22:49 +0100460 self.count_num_entries(domain, namespace).map_err(into_logged_binder)
Eran Messeri24f31972023-01-25 17:00:33 +0000461 }
Karuna Wadhera1cfc81d2024-11-07 23:35:51 +0000462
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 }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700472}