blob: 9ee2a1e6b7ffd0433ffd136e02a93f801b97f06e [file] [log] [blame]
Janis Danisevskisa75e2082020-10-07 16:44:26 -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
15//! This module holds global state of Keystore such as the thread local
16//! database connections and connections to services that Keystore needs
17//! to talk to.
18
Eric Biggersb5613da2024-03-13 19:31:42 +000019use crate::async_task::AsyncTask;
Janis Danisevskis93927dd2020-12-23 12:23:08 -080020use crate::gc::Gc;
Shaquille Johnsondf83fb72023-03-24 12:26:52 +000021use crate::km_compat::{BacklevelKeyMintWrapper, KeyMintV1};
22use crate::ks_err;
Hasini Gunasinghea020b532021-01-07 21:42:35 +000023use crate::legacy_blob::LegacyBlobLoader;
Janis Danisevskis0ffb8a82022-02-06 22:37:21 -080024use crate::legacy_importer::LegacyImporter;
Janis Danisevskisb42fc182020-12-15 08:41:27 -080025use crate::super_key::SuperKeyManager;
Alice Wang81dbef72024-07-31 15:13:14 +000026use crate::utils::{retry_get_interface, watchdog as wd};
Janis Danisevskisba998992020-12-29 16:08:40 -080027use crate::{
28 database::KeystoreDB,
Max Bires8e93d2b2021-01-14 13:17:59 -080029 database::Uuid,
Janis Danisevskis8c6378e2021-01-01 09:30:37 -080030 error::{map_binder_status, map_binder_status_code, Error, ErrorCode},
Janis Danisevskisba998992020-12-29 16:08:40 -080031};
Max Bires8e93d2b2021-01-14 13:17:59 -080032use crate::{enforcements::Enforcements, error::map_km_error};
33use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Shaquille Johnson8d67b752023-03-31 11:17:34 +010034 IKeyMintDevice::BpKeyMintDevice, IKeyMintDevice::IKeyMintDevice,
35 KeyMintHardwareInfo::KeyMintHardwareInfo, SecurityLevel::SecurityLevel,
Max Bires8e93d2b2021-01-14 13:17:59 -080036};
Stephen Crane221bbb52020-12-16 15:52:10 -080037use android_hardware_security_keymint::binder::{StatusCode, Strong};
Shaquille Johnsondf83fb72023-03-24 12:26:52 +000038use android_hardware_security_rkp::aidl::android::hardware::security::keymint::{
39 IRemotelyProvisionedComponent::BpRemotelyProvisionedComponent,
40 IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
41};
42use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
43 ISecureClock::BpSecureClock, ISecureClock::ISecureClock,
44};
Janis Danisevskis8c6378e2021-01-01 09:30:37 -080045use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
Janis Danisevskisba998992020-12-29 16:08:40 -080046use anyhow::{Context, Result};
Shaquille Johnsondf83fb72023-03-24 12:26:52 +000047use binder::FromIBinder;
Karuna Wadhera9ae66c02024-05-16 19:40:59 +000048use binder::{get_declared_instances, is_declared};
David Drysdale940a0ff2025-01-13 14:19:16 +000049use rustutils::system_properties::PropertyWatcher;
50use std::sync::{
51 atomic::{AtomicBool, Ordering},
52 Arc, LazyLock, Mutex, RwLock,
53};
Janis Danisevskis93927dd2020-12-23 12:23:08 -080054use std::{cell::RefCell, sync::Once};
Janis Danisevskis3f2955c2021-02-02 21:53:35 -080055use std::{collections::HashMap, path::Path, path::PathBuf};
Janis Danisevskis93927dd2020-12-23 12:23:08 -080056
57static DB_INIT: Once = Once::new();
58
59/// Open a connection to the Keystore 2.0 database. This is called during the initialization of
60/// the thread local DB field. It should never be called directly. The first time this is called
61/// we also call KeystoreDB::cleanup_leftovers to restore the key lifecycle invariant. See the
Janis Danisevskis7e8b4622021-02-13 10:01:59 -080062/// documentation of cleanup_leftovers for more details. The function also constructs a blob
63/// garbage collector. The initializing closure constructs another database connection without
64/// a gc. Although one GC is created for each thread local database connection, this closure
65/// is run only once, as long as the ASYNC_TASK instance is the same. So only one additional
66/// database connection is created for the garbage collector worker.
Hasini Gunasinghe3ed5da72021-02-04 15:18:54 +000067pub fn create_thread_local_db() -> KeystoreDB {
David Drysdale18c29f32024-07-19 12:54:19 +010068 let db_path = DB_PATH.read().expect("Could not get the database directory");
Seth Moore472fcbb2021-05-12 10:07:51 -070069
David Drysdale18c29f32024-07-19 12:54:19 +010070 let result = KeystoreDB::new(&db_path, Some(GC.clone()));
71 let mut db = match result {
72 Ok(db) => db,
73 Err(e) => {
74 log::error!("Failed to open Keystore database at {db_path:?}: {e:?}");
75 log::error!("Has /data been mounted correctly?");
76 panic!("Failed to open database for Keystore, cannot continue: {e:?}")
77 }
78 };
Seth Moore472fcbb2021-05-12 10:07:51 -070079
Janis Danisevskis93927dd2020-12-23 12:23:08 -080080 DB_INIT.call_once(|| {
81 log::info!("Touching Keystore 2.0 database for this first time since boot.");
82 log::info!("Calling cleanup leftovers.");
David Drysdale18c29f32024-07-19 12:54:19 +010083 let n = db.cleanup_leftovers().expect("Failed to cleanup database on startup");
Janis Danisevskis93927dd2020-12-23 12:23:08 -080084 if n != 0 {
85 log::info!(
David Drysdale18c29f32024-07-19 12:54:19 +010086 "Cleaned up {n} failed entries, indicating keystore crash on key generation"
Janis Danisevskis93927dd2020-12-23 12:23:08 -080087 );
88 }
Janis Danisevskis93927dd2020-12-23 12:23:08 -080089 });
90 db
91}
Janis Danisevskisa75e2082020-10-07 16:44:26 -070092
93thread_local! {
94 /// Database connections are not thread safe, but connecting to the
95 /// same database multiple times is safe as long as each connection is
96 /// used by only one thread. So we store one database connection per
97 /// thread in this thread local key.
David Drysdale18c29f32024-07-19 12:54:19 +010098 pub static DB: RefCell<KeystoreDB> = RefCell::new(create_thread_local_db());
Janis Danisevskisa75e2082020-10-07 16:44:26 -070099}
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800100
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700101struct DevicesMap<T: FromIBinder + ?Sized> {
102 devices_by_uuid: HashMap<Uuid, (Strong<T>, KeyMintHardwareInfo)>,
Max Bires8e93d2b2021-01-14 13:17:59 -0800103 uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
104}
105
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700106impl<T: FromIBinder + ?Sized> DevicesMap<T> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800107 fn dev_by_sec_level(
108 &self,
109 sec_level: &SecurityLevel,
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700110 ) -> Option<(Strong<T>, KeyMintHardwareInfo, Uuid)> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800111 self.uuid_by_sec_level.get(sec_level).and_then(|uuid| self.dev_by_uuid(uuid))
112 }
113
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700114 fn dev_by_uuid(&self, uuid: &Uuid) -> Option<(Strong<T>, KeyMintHardwareInfo, Uuid)> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800115 self.devices_by_uuid
116 .get(uuid)
117 .map(|(dev, hw_info)| ((*dev).clone(), (*hw_info).clone(), *uuid))
118 }
119
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700120 fn devices(&self) -> Vec<Strong<T>> {
121 self.devices_by_uuid.values().map(|(dev, _)| dev.clone()).collect()
David Drysdale0e45a612021-02-25 17:24:36 +0000122 }
123
Max Bires8e93d2b2021-01-14 13:17:59 -0800124 /// The requested security level and the security level of the actual implementation may
125 /// differ. So we map the requested security level to the uuid of the implementation
126 /// so that there cannot be any confusion as to which KeyMint instance is requested.
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700127 fn insert(&mut self, sec_level: SecurityLevel, dev: Strong<T>, hw_info: KeyMintHardwareInfo) {
Max Bires8e93d2b2021-01-14 13:17:59 -0800128 // For now we use the reported security level of the KM instance as UUID.
129 // TODO update this section once UUID was added to the KM hardware info.
130 let uuid: Uuid = sec_level.into();
131 self.devices_by_uuid.insert(uuid, (dev, hw_info));
132 self.uuid_by_sec_level.insert(sec_level, uuid);
133 }
134}
135
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700136impl<T: FromIBinder + ?Sized> Default for DevicesMap<T> {
137 fn default() -> Self {
138 Self {
139 devices_by_uuid: HashMap::<Uuid, (Strong<T>, KeyMintHardwareInfo)>::new(),
140 uuid_by_sec_level: Default::default(),
141 }
142 }
Max Biresb2e1d032021-02-08 21:35:05 -0800143}
144
Andrew Walbrana4bc1a92024-09-03 13:08:17 +0100145/// The path where keystore stores all its keys.
146pub static DB_PATH: LazyLock<RwLock<PathBuf>> =
147 LazyLock::new(|| RwLock::new(Path::new("/data/misc/keystore").to_path_buf()));
148/// Runtime database of unwrapped super keys.
149pub static SUPER_KEY: LazyLock<Arc<RwLock<SuperKeyManager>>> = LazyLock::new(Default::default);
150/// Map of KeyMint devices.
151static KEY_MINT_DEVICES: LazyLock<Mutex<DevicesMap<dyn IKeyMintDevice>>> =
152 LazyLock::new(Default::default);
153/// Timestamp service.
154static TIME_STAMP_DEVICE: Mutex<Option<Strong<dyn ISecureClock>>> = Mutex::new(None);
155/// A single on-demand worker thread that handles deferred tasks with two different
156/// priorities.
157pub static ASYNC_TASK: LazyLock<Arc<AsyncTask>> = LazyLock::new(Default::default);
158/// Singleton for enforcements.
159pub static ENFORCEMENTS: LazyLock<Enforcements> = LazyLock::new(Default::default);
160/// LegacyBlobLoader is initialized and exists globally.
161/// The same directory used by the database is used by the LegacyBlobLoader as well.
162pub static LEGACY_BLOB_LOADER: LazyLock<Arc<LegacyBlobLoader>> = LazyLock::new(|| {
163 Arc::new(LegacyBlobLoader::new(
164 &DB_PATH.read().expect("Could not determine database path for legacy blob loader"),
165 ))
166});
167/// Legacy migrator. Atomically migrates legacy blobs to the database.
168pub static LEGACY_IMPORTER: LazyLock<Arc<LegacyImporter>> =
169 LazyLock::new(|| Arc::new(LegacyImporter::new(Arc::new(Default::default()))));
170/// Background thread which handles logging via statsd and logd
171pub static LOGS_HANDLER: LazyLock<Arc<AsyncTask>> = LazyLock::new(Default::default);
Karuna Wadhera1cfc81d2024-11-07 23:35:51 +0000172/// DER-encoded module information returned by `getSupplementaryAttestationInfo(Tag.MODULE_HASH)`.
173pub static ENCODED_MODULE_INFO: RwLock<Option<Vec<u8>>> = RwLock::new(None);
Janis Danisevskis3395f862021-05-06 10:54:17 -0700174
Andrew Walbrana4bc1a92024-09-03 13:08:17 +0100175static GC: LazyLock<Arc<Gc>> = LazyLock::new(|| {
176 Arc::new(Gc::new_init_with(ASYNC_TASK.clone(), || {
Janis Danisevskis3395f862021-05-06 10:54:17 -0700177 (
178 Box::new(|uuid, blob| {
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700179 let km_dev = get_keymint_dev_by_uuid(uuid).map(|(dev, _)| dev)?;
David Drysdalec652f6c2024-07-18 13:01:23 +0100180 let _wp = wd::watch("invalidate key closure: calling IKeyMintDevice::deleteKey");
Chris Wailes263de9f2022-08-11 15:00:51 -0700181 map_km_error(km_dev.deleteKey(blob))
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000182 .context(ks_err!("Trying to invalidate key blob."))
Janis Danisevskis3395f862021-05-06 10:54:17 -0700183 }),
Andrew Walbrana4bc1a92024-09-03 13:08:17 +0100184 KeystoreDB::new(
185 &DB_PATH.read().expect("Could not determine database path for GC"),
186 None,
187 )
188 .expect("Failed to open database"),
Janis Danisevskis3395f862021-05-06 10:54:17 -0700189 SUPER_KEY.clone(),
190 )
Andrew Walbrana4bc1a92024-09-03 13:08:17 +0100191 }))
192});
Janis Danisevskisba998992020-12-29 16:08:40 -0800193
David Drysdalec97eb9e2022-01-26 13:03:48 -0800194/// Determine the service name for a KeyMint device of the given security level
Shaquille Johnsondf83fb72023-03-24 12:26:52 +0000195/// gotten by binder service from the device and determining what services
196/// are available.
Shaquille Johnson8d67b752023-03-31 11:17:34 +0100197fn keymint_service_name(security_level: &SecurityLevel) -> Result<Option<String>> {
198 let keymint_descriptor: &str = <BpKeyMintDevice as IKeyMintDevice>::get_descriptor();
199 let keymint_instances = get_declared_instances(keymint_descriptor).unwrap();
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800200
Max Bires8e93d2b2021-01-14 13:17:59 -0800201 let service_name = match *security_level {
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800202 SecurityLevel::TRUSTED_ENVIRONMENT => {
Joel Galensonec7872a2021-07-02 14:37:10 -0700203 if keymint_instances.iter().any(|instance| *instance == "default") {
Shaquille Johnson8d67b752023-03-31 11:17:34 +0100204 Some(format!("{}/default", keymint_descriptor))
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800205 } else {
206 None
207 }
208 }
209 SecurityLevel::STRONGBOX => {
Joel Galensonec7872a2021-07-02 14:37:10 -0700210 if keymint_instances.iter().any(|instance| *instance == "strongbox") {
Shaquille Johnson8d67b752023-03-31 11:17:34 +0100211 Some(format!("{}/strongbox", keymint_descriptor))
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800212 } else {
213 None
214 }
215 }
Janis Danisevskisba998992020-12-29 16:08:40 -0800216 _ => {
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000217 return Err(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)).context(ks_err!(
Shaquille Johnson8d67b752023-03-31 11:17:34 +0100218 "Trying to find keymint for security level: {:?}",
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000219 security_level
David Drysdalec97eb9e2022-01-26 13:03:48 -0800220 ));
Janis Danisevskisba998992020-12-29 16:08:40 -0800221 }
222 };
223
Shaquille Johnson8d67b752023-03-31 11:17:34 +0100224 Ok(service_name)
David Drysdalec97eb9e2022-01-26 13:03:48 -0800225}
226
227/// Make a new connection to a KeyMint device of the given security level.
228/// If no native KeyMint device can be found this function also brings
229/// up the compatibility service and attempts to connect to the legacy wrapper.
230fn connect_keymint(
231 security_level: &SecurityLevel,
232) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo)> {
Shaquille Johnsondf83fb72023-03-24 12:26:52 +0000233 // Show the keymint interface that is registered in the binder
234 // service and use the security level to get the service name.
235 let service_name = keymint_service_name(security_level)
236 .context(ks_err!("Get service name from binder service"))?;
David Drysdalec97eb9e2022-01-26 13:03:48 -0800237
Shaquille Johnson8d67b752023-03-31 11:17:34 +0100238 let (keymint, hal_version) = if let Some(service_name) = service_name {
David Drysdalea6c82a92021-12-06 11:24:26 +0000239 let km: Strong<dyn IKeyMintDevice> =
Alice Wang81dbef72024-07-31 15:13:14 +0000240 if SecurityLevel::TRUSTED_ENVIRONMENT == *security_level {
241 map_binder_status_code(retry_get_interface(&service_name))
242 } else {
243 map_binder_status_code(binder::get_interface(&service_name))
244 }
245 .context(ks_err!("Trying to connect to genuine KeyMint service."))?;
David Drysdalea6c82a92021-12-06 11:24:26 +0000246 // Map the HAL version code for KeyMint to be <AIDL version> * 100, so
247 // - V1 is 100
248 // - V2 is 200
Shaquille Johnson8d67b752023-03-31 11:17:34 +0100249 // - V3 is 300
David Drysdalea6c82a92021-12-06 11:24:26 +0000250 // etc.
Shaquille Johnson8d67b752023-03-31 11:17:34 +0100251 let km_version = km.getInterfaceVersion()?;
252 (km, Some(km_version * 100))
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800253 } else {
254 // This is a no-op if it was called before.
255 keystore2_km_compat::add_keymint_device_service();
Janis Danisevskis8c6378e2021-01-01 09:30:37 -0800256
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800257 let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
258 map_binder_status_code(binder::get_interface("android.security.compat"))
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000259 .context(ks_err!("Trying to connect to compat service."))?;
Janis Danisevskisbf855c02021-06-03 13:05:29 -0700260 (
261 map_binder_status(keystore_compat_service.getKeyMintDevice(*security_level))
262 .map_err(|e| match e {
263 Error::BinderTransaction(StatusCode::NAME_NOT_FOUND) => {
264 Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)
265 }
266 e => e,
267 })
Shaquille Johnson69c92a02024-02-28 22:14:05 +0000268 .context(ks_err!(
269 "Trying to get Legacy wrapper. Attempt to get keystore \
270 compat service for security level {:?}",
271 *security_level
272 ))?,
Janis Danisevskisbf855c02021-06-03 13:05:29 -0700273 None,
274 )
275 };
Janis Danisevskisba998992020-12-29 16:08:40 -0800276
David Drysdalec97eb9e2022-01-26 13:03:48 -0800277 // If the KeyMint device is back-level, use a wrapper that intercepts and
278 // emulates things that are not supported by the hardware.
279 let keymint = match hal_version {
Karuna Wadhera542212b2024-11-01 21:23:50 +0000280 Some(400) | Some(300) | Some(200) => {
281 // KeyMint v2+: use as-is (we don't have any software emulation of v3 or v4-specific KeyMint features).
David Drysdalec97eb9e2022-01-26 13:03:48 -0800282 log::info!(
283 "KeyMint device is current version ({:?}) for security level: {:?}",
284 hal_version,
285 security_level
286 );
287 keymint
288 }
289 Some(100) => {
290 // KeyMint v1: perform software emulation.
291 log::info!(
292 "Add emulation wrapper around {:?} device for security level: {:?}",
293 hal_version,
294 security_level
295 );
296 BacklevelKeyMintWrapper::wrap(KeyMintV1::new(*security_level), keymint)
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000297 .context(ks_err!("Trying to create V1 compatibility wrapper."))?
David Drysdalec97eb9e2022-01-26 13:03:48 -0800298 }
299 None => {
300 // Compatibility wrapper around a KeyMaster device: this roughly
301 // behaves like KeyMint V1 (e.g. it includes AGREE_KEY support,
302 // albeit in software.)
303 log::info!(
304 "Add emulation wrapper around Keymaster device for security level: {:?}",
305 security_level
306 );
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000307 BacklevelKeyMintWrapper::wrap(KeyMintV1::new(*security_level), keymint)
308 .context(ks_err!("Trying to create km_compat V1 compatibility wrapper ."))?
David Drysdalec97eb9e2022-01-26 13:03:48 -0800309 }
310 _ => {
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000311 return Err(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)).context(ks_err!(
312 "unexpected hal_version {:?} for security level: {:?}",
313 hal_version,
314 security_level
315 ));
David Drysdalec97eb9e2022-01-26 13:03:48 -0800316 }
317 };
318
David Drysdalec652f6c2024-07-18 13:01:23 +0100319 let wp = wd::watch("connect_keymint: calling IKeyMintDevice::getHardwareInfo()");
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000320 let mut hw_info =
321 map_km_error(keymint.getHardwareInfo()).context(ks_err!("Failed to get hardware info."))?;
Janis Danisevskis2ee014b2021-05-05 14:29:08 -0700322 drop(wp);
Max Bires8e93d2b2021-01-14 13:17:59 -0800323
Janis Danisevskisbf855c02021-06-03 13:05:29 -0700324 // The legacy wrapper sets hw_info.versionNumber to the underlying HAL version like so:
325 // 10 * <major> + <minor>, e.g., KM 3.0 = 30. So 30, 40, and 41 are the only viable values.
David Drysdalea6c82a92021-12-06 11:24:26 +0000326 //
327 // For KeyMint the returned versionNumber is implementation defined and thus completely
328 // meaningless to Keystore 2.0. So set the versionNumber field that is returned to
329 // the rest of the code to be the <AIDL version> * 100, so KeyMint V1 is 100, KeyMint V2 is 200
330 // and so on.
331 //
332 // This ensures that versionNumber value across KeyMaster and KeyMint is monotonically
333 // increasing (and so comparisons like `versionNumber >= KEY_MINT_1` are valid).
Janis Danisevskisbf855c02021-06-03 13:05:29 -0700334 if let Some(hal_version) = hal_version {
335 hw_info.versionNumber = hal_version;
336 }
337
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700338 Ok((keymint, hw_info))
Janis Danisevskisba998992020-12-29 16:08:40 -0800339}
340
341/// Get a keymint device for the given security level either from our cache or
Max Bires8e93d2b2021-01-14 13:17:59 -0800342/// by making a new connection. Returns the device, the hardware info and the uuid.
343/// TODO the latter can be removed when the uuid is part of the hardware info.
344pub fn get_keymint_device(
345 security_level: &SecurityLevel,
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700346) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo, Uuid)> {
Janis Danisevskisba998992020-12-29 16:08:40 -0800347 let mut devices_map = KEY_MINT_DEVICES.lock().unwrap();
Chris Wailesd5aaaef2021-07-27 16:04:33 -0700348 if let Some((dev, hw_info, uuid)) = devices_map.dev_by_sec_level(security_level) {
Max Bires8e93d2b2021-01-14 13:17:59 -0800349 Ok((dev, hw_info, uuid))
Janis Danisevskisba998992020-12-29 16:08:40 -0800350 } else {
Shaquille Johnsond4443c62023-02-23 17:39:24 +0000351 let (dev, hw_info) =
352 connect_keymint(security_level).context(ks_err!("Cannot connect to Keymint"))?;
Max Bires8e93d2b2021-01-14 13:17:59 -0800353 devices_map.insert(*security_level, dev, hw_info);
354 // Unwrap must succeed because we just inserted it.
355 Ok(devices_map.dev_by_sec_level(security_level).unwrap())
356 }
357}
358
359/// Get a keymint device for the given uuid. This will only access the cache, but will not
360/// attempt to establish a new connection. It is assumed that the cache is already populated
361/// when this is called. This is a fair assumption, because service.rs iterates through all
362/// security levels when it gets instantiated.
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700363pub fn get_keymint_dev_by_uuid(
364 uuid: &Uuid,
365) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo)> {
Max Bires8e93d2b2021-01-14 13:17:59 -0800366 let devices_map = KEY_MINT_DEVICES.lock().unwrap();
367 if let Some((dev, hw_info, _)) = devices_map.dev_by_uuid(uuid) {
368 Ok((dev, hw_info))
369 } else {
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000370 Err(Error::sys()).context(ks_err!("No KeyMint instance found."))
Janis Danisevskisba998992020-12-29 16:08:40 -0800371 }
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800372}
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800373
David Drysdale0e45a612021-02-25 17:24:36 +0000374/// Return all known keymint devices.
375pub fn get_keymint_devices() -> Vec<Strong<dyn IKeyMintDevice>> {
376 KEY_MINT_DEVICES.lock().unwrap().devices()
377}
378
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800379/// Make a new connection to a secure clock service.
380/// If no native SecureClock device can be found brings up the compatibility service and attempts
381/// to connect to the legacy wrapper.
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700382fn connect_secureclock() -> Result<Strong<dyn ISecureClock>> {
Shaquille Johnsondf83fb72023-03-24 12:26:52 +0000383 let secure_clock_descriptor: &str = <BpSecureClock as ISecureClock>::get_descriptor();
384 let secureclock_instances = get_declared_instances(secure_clock_descriptor).unwrap();
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800385
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800386 let secure_clock_available =
Joel Galensonec7872a2021-07-02 14:37:10 -0700387 secureclock_instances.iter().any(|instance| *instance == "default");
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800388
Shaquille Johnsondf83fb72023-03-24 12:26:52 +0000389 let default_time_stamp_service_name = format!("{}/default", secure_clock_descriptor);
Max Bires130e51b2021-04-05 14:07:20 -0700390
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800391 let secureclock = if secure_clock_available {
Max Bires130e51b2021-04-05 14:07:20 -0700392 map_binder_status_code(binder::get_interface(&default_time_stamp_service_name))
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000393 .context(ks_err!("Trying to connect to genuine secure clock service."))
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800394 } else {
395 // This is a no-op if it was called before.
396 keystore2_km_compat::add_keymint_device_service();
397
398 let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
399 map_binder_status_code(binder::get_interface("android.security.compat"))
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000400 .context(ks_err!("Trying to connect to compat service."))?;
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800401
402 // Legacy secure clock services were only implemented by TEE.
403 map_binder_status(keystore_compat_service.getSecureClock())
404 .map_err(|e| match e {
405 Error::BinderTransaction(StatusCode::NAME_NOT_FOUND) => {
406 Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800407 }
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800408 e => e,
409 })
Shaquille Johnson69c92a02024-02-28 22:14:05 +0000410 .context(ks_err!("Failed attempt to get legacy secure clock."))
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800411 }?;
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800412
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700413 Ok(secureclock)
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800414}
415
416/// Get the timestamp service that verifies auth token timeliness towards security levels with
417/// different clocks.
Janis Danisevskis5f3a0572021-06-18 11:26:42 -0700418pub fn get_timestamp_service() -> Result<Strong<dyn ISecureClock>> {
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800419 let mut ts_device = TIME_STAMP_DEVICE.lock().unwrap();
420 if let Some(dev) = &*ts_device {
421 Ok(dev.clone())
422 } else {
Shaquille Johnson9da2e1c2022-09-19 12:39:01 +0000423 let dev = connect_secureclock().context(ks_err!())?;
Janis Danisevskisc3a496b2021-01-05 10:37:22 -0800424 *ts_device = Some(dev.clone());
425 Ok(dev)
426 }
427}
Max Biresb2e1d032021-02-08 21:35:05 -0800428
Tri Voe8f04442022-12-21 08:53:56 -0800429/// Get the service name of a remotely provisioned component corresponding to given security level.
430pub fn get_remotely_provisioned_component_name(security_level: &SecurityLevel) -> Result<String> {
Shaquille Johnsondf83fb72023-03-24 12:26:52 +0000431 let remote_prov_descriptor: &str =
432 <BpRemotelyProvisionedComponent as IRemotelyProvisionedComponent>::get_descriptor();
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800433
Tri Voe8f04442022-12-21 08:53:56 -0800434 match *security_level {
Max Biresb2e1d032021-02-08 21:35:05 -0800435 SecurityLevel::TRUSTED_ENVIRONMENT => {
Karuna Wadhera9ae66c02024-05-16 19:40:59 +0000436 let instance = format!("{}/default", remote_prov_descriptor);
437 if is_declared(&instance)? {
438 Some(instance)
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800439 } else {
440 None
441 }
Max Biresb2e1d032021-02-08 21:35:05 -0800442 }
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800443 SecurityLevel::STRONGBOX => {
Karuna Wadhera9ae66c02024-05-16 19:40:59 +0000444 let instance = format!("{}/strongbox", remote_prov_descriptor);
445 if is_declared(&instance)? {
446 Some(instance)
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800447 } else {
448 None
449 }
Max Biresb2e1d032021-02-08 21:35:05 -0800450 }
Janis Danisevskisef14e1a2021-02-23 23:16:55 -0800451 _ => None,
452 }
453 .ok_or(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
Shaquille Johnson69c92a02024-02-28 22:14:05 +0000454 .context(ks_err!("Failed to get rpc for sec level {:?}", *security_level))
Tri Voe8f04442022-12-21 08:53:56 -0800455}
David Drysdale940a0ff2025-01-13 14:19:16 +0000456
457/// Whether boot is complete.
458static BOOT_COMPLETED: AtomicBool = AtomicBool::new(false);
459
460/// Indicate whether boot is complete.
461///
462/// This in turn indicates whether it is safe to make permanent changes to state.
463pub fn boot_completed() -> bool {
464 BOOT_COMPLETED.load(Ordering::Acquire)
465}
466
467/// Monitor the system property for boot complete. This blocks and so needs to be run in a separate
468/// thread.
469pub fn await_boot_completed() {
470 // Use a fairly long watchdog timeout of 5 minutes here. This blocks until the device
471 // boots, which on a very slow device (e.g., emulator for a non-native architecture) can
472 // take minutes. Blocking here would be unexpected only if it never finishes.
473 let _wp = wd::watch_millis("await_boot_completed", 300_000);
474 log::info!("monitoring for sys.boot_completed=1");
475 while let Err(e) = watch_for_boot_completed() {
476 log::error!("failed to watch for boot_completed: {e:?}");
477 std::thread::sleep(std::time::Duration::from_secs(5));
478 }
479
480 BOOT_COMPLETED.store(true, Ordering::Release);
481 log::info!("wait_for_boot_completed done, triggering GC");
482
483 // Garbage collection may have been skipped until now, so trigger a check.
484 GC.notify_gc();
485}
486
487fn watch_for_boot_completed() -> Result<()> {
488 let mut w = PropertyWatcher::new("sys.boot_completed")
489 .context(ks_err!("PropertyWatcher::new failed"))?;
490 w.wait_for_value("1", None).context(ks_err!("Failed to wait for sys.boot_completed"))?;
491 Ok(())
492}