1*e1997b9aSAndroid Build Coastguard Worker // Copyright 2020, The Android Open Source Project
2*e1997b9aSAndroid Build Coastguard Worker //
3*e1997b9aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*e1997b9aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*e1997b9aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*e1997b9aSAndroid Build Coastguard Worker //
7*e1997b9aSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*e1997b9aSAndroid Build Coastguard Worker //
9*e1997b9aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*e1997b9aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*e1997b9aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e1997b9aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*e1997b9aSAndroid Build Coastguard Worker // limitations under the License.
14*e1997b9aSAndroid Build Coastguard Worker
15*e1997b9aSAndroid Build Coastguard Worker //! This module holds global state of Keystore such as the thread local
16*e1997b9aSAndroid Build Coastguard Worker //! database connections and connections to services that Keystore needs
17*e1997b9aSAndroid Build Coastguard Worker //! to talk to.
18*e1997b9aSAndroid Build Coastguard Worker
19*e1997b9aSAndroid Build Coastguard Worker use crate::async_task::AsyncTask;
20*e1997b9aSAndroid Build Coastguard Worker use crate::gc::Gc;
21*e1997b9aSAndroid Build Coastguard Worker use crate::km_compat::{BacklevelKeyMintWrapper, KeyMintV1};
22*e1997b9aSAndroid Build Coastguard Worker use crate::ks_err;
23*e1997b9aSAndroid Build Coastguard Worker use crate::legacy_blob::LegacyBlobLoader;
24*e1997b9aSAndroid Build Coastguard Worker use crate::legacy_importer::LegacyImporter;
25*e1997b9aSAndroid Build Coastguard Worker use crate::super_key::SuperKeyManager;
26*e1997b9aSAndroid Build Coastguard Worker use crate::utils::{retry_get_interface, watchdog as wd};
27*e1997b9aSAndroid Build Coastguard Worker use crate::{
28*e1997b9aSAndroid Build Coastguard Worker database::KeystoreDB,
29*e1997b9aSAndroid Build Coastguard Worker database::Uuid,
30*e1997b9aSAndroid Build Coastguard Worker error::{map_binder_status, map_binder_status_code, Error, ErrorCode},
31*e1997b9aSAndroid Build Coastguard Worker };
32*e1997b9aSAndroid Build Coastguard Worker use crate::{enforcements::Enforcements, error::map_km_error};
33*e1997b9aSAndroid Build Coastguard Worker use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
34*e1997b9aSAndroid Build Coastguard Worker IKeyMintDevice::BpKeyMintDevice, IKeyMintDevice::IKeyMintDevice,
35*e1997b9aSAndroid Build Coastguard Worker KeyMintHardwareInfo::KeyMintHardwareInfo, SecurityLevel::SecurityLevel,
36*e1997b9aSAndroid Build Coastguard Worker };
37*e1997b9aSAndroid Build Coastguard Worker use android_hardware_security_keymint::binder::{StatusCode, Strong};
38*e1997b9aSAndroid Build Coastguard Worker use android_hardware_security_rkp::aidl::android::hardware::security::keymint::{
39*e1997b9aSAndroid Build Coastguard Worker IRemotelyProvisionedComponent::BpRemotelyProvisionedComponent,
40*e1997b9aSAndroid Build Coastguard Worker IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
41*e1997b9aSAndroid Build Coastguard Worker };
42*e1997b9aSAndroid Build Coastguard Worker use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
43*e1997b9aSAndroid Build Coastguard Worker ISecureClock::BpSecureClock, ISecureClock::ISecureClock,
44*e1997b9aSAndroid Build Coastguard Worker };
45*e1997b9aSAndroid Build Coastguard Worker use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
46*e1997b9aSAndroid Build Coastguard Worker use anyhow::{Context, Result};
47*e1997b9aSAndroid Build Coastguard Worker use binder::FromIBinder;
48*e1997b9aSAndroid Build Coastguard Worker use binder::{get_declared_instances, is_declared};
49*e1997b9aSAndroid Build Coastguard Worker use std::sync::{Arc, LazyLock, Mutex, RwLock};
50*e1997b9aSAndroid Build Coastguard Worker use std::{cell::RefCell, sync::Once};
51*e1997b9aSAndroid Build Coastguard Worker use std::{collections::HashMap, path::Path, path::PathBuf};
52*e1997b9aSAndroid Build Coastguard Worker
53*e1997b9aSAndroid Build Coastguard Worker static DB_INIT: Once = Once::new();
54*e1997b9aSAndroid Build Coastguard Worker
55*e1997b9aSAndroid Build Coastguard Worker /// Open a connection to the Keystore 2.0 database. This is called during the initialization of
56*e1997b9aSAndroid Build Coastguard Worker /// the thread local DB field. It should never be called directly. The first time this is called
57*e1997b9aSAndroid Build Coastguard Worker /// we also call KeystoreDB::cleanup_leftovers to restore the key lifecycle invariant. See the
58*e1997b9aSAndroid Build Coastguard Worker /// documentation of cleanup_leftovers for more details. The function also constructs a blob
59*e1997b9aSAndroid Build Coastguard Worker /// garbage collector. The initializing closure constructs another database connection without
60*e1997b9aSAndroid Build Coastguard Worker /// a gc. Although one GC is created for each thread local database connection, this closure
61*e1997b9aSAndroid Build Coastguard Worker /// is run only once, as long as the ASYNC_TASK instance is the same. So only one additional
62*e1997b9aSAndroid Build Coastguard Worker /// database connection is created for the garbage collector worker.
create_thread_local_db() -> KeystoreDB63*e1997b9aSAndroid Build Coastguard Worker pub fn create_thread_local_db() -> KeystoreDB {
64*e1997b9aSAndroid Build Coastguard Worker let db_path = DB_PATH.read().expect("Could not get the database directory");
65*e1997b9aSAndroid Build Coastguard Worker
66*e1997b9aSAndroid Build Coastguard Worker let result = KeystoreDB::new(&db_path, Some(GC.clone()));
67*e1997b9aSAndroid Build Coastguard Worker let mut db = match result {
68*e1997b9aSAndroid Build Coastguard Worker Ok(db) => db,
69*e1997b9aSAndroid Build Coastguard Worker Err(e) => {
70*e1997b9aSAndroid Build Coastguard Worker log::error!("Failed to open Keystore database at {db_path:?}: {e:?}");
71*e1997b9aSAndroid Build Coastguard Worker log::error!("Has /data been mounted correctly?");
72*e1997b9aSAndroid Build Coastguard Worker panic!("Failed to open database for Keystore, cannot continue: {e:?}")
73*e1997b9aSAndroid Build Coastguard Worker }
74*e1997b9aSAndroid Build Coastguard Worker };
75*e1997b9aSAndroid Build Coastguard Worker
76*e1997b9aSAndroid Build Coastguard Worker DB_INIT.call_once(|| {
77*e1997b9aSAndroid Build Coastguard Worker log::info!("Touching Keystore 2.0 database for this first time since boot.");
78*e1997b9aSAndroid Build Coastguard Worker log::info!("Calling cleanup leftovers.");
79*e1997b9aSAndroid Build Coastguard Worker let n = db.cleanup_leftovers().expect("Failed to cleanup database on startup");
80*e1997b9aSAndroid Build Coastguard Worker if n != 0 {
81*e1997b9aSAndroid Build Coastguard Worker log::info!(
82*e1997b9aSAndroid Build Coastguard Worker "Cleaned up {n} failed entries, indicating keystore crash on key generation"
83*e1997b9aSAndroid Build Coastguard Worker );
84*e1997b9aSAndroid Build Coastguard Worker }
85*e1997b9aSAndroid Build Coastguard Worker });
86*e1997b9aSAndroid Build Coastguard Worker db
87*e1997b9aSAndroid Build Coastguard Worker }
88*e1997b9aSAndroid Build Coastguard Worker
89*e1997b9aSAndroid Build Coastguard Worker thread_local! {
90*e1997b9aSAndroid Build Coastguard Worker /// Database connections are not thread safe, but connecting to the
91*e1997b9aSAndroid Build Coastguard Worker /// same database multiple times is safe as long as each connection is
92*e1997b9aSAndroid Build Coastguard Worker /// used by only one thread. So we store one database connection per
93*e1997b9aSAndroid Build Coastguard Worker /// thread in this thread local key.
94*e1997b9aSAndroid Build Coastguard Worker pub static DB: RefCell<KeystoreDB> = RefCell::new(create_thread_local_db());
95*e1997b9aSAndroid Build Coastguard Worker }
96*e1997b9aSAndroid Build Coastguard Worker
97*e1997b9aSAndroid Build Coastguard Worker struct DevicesMap<T: FromIBinder + ?Sized> {
98*e1997b9aSAndroid Build Coastguard Worker devices_by_uuid: HashMap<Uuid, (Strong<T>, KeyMintHardwareInfo)>,
99*e1997b9aSAndroid Build Coastguard Worker uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
100*e1997b9aSAndroid Build Coastguard Worker }
101*e1997b9aSAndroid Build Coastguard Worker
102*e1997b9aSAndroid Build Coastguard Worker impl<T: FromIBinder + ?Sized> DevicesMap<T> {
dev_by_sec_level( &self, sec_level: &SecurityLevel, ) -> Option<(Strong<T>, KeyMintHardwareInfo, Uuid)>103*e1997b9aSAndroid Build Coastguard Worker fn dev_by_sec_level(
104*e1997b9aSAndroid Build Coastguard Worker &self,
105*e1997b9aSAndroid Build Coastguard Worker sec_level: &SecurityLevel,
106*e1997b9aSAndroid Build Coastguard Worker ) -> Option<(Strong<T>, KeyMintHardwareInfo, Uuid)> {
107*e1997b9aSAndroid Build Coastguard Worker self.uuid_by_sec_level.get(sec_level).and_then(|uuid| self.dev_by_uuid(uuid))
108*e1997b9aSAndroid Build Coastguard Worker }
109*e1997b9aSAndroid Build Coastguard Worker
dev_by_uuid(&self, uuid: &Uuid) -> Option<(Strong<T>, KeyMintHardwareInfo, Uuid)>110*e1997b9aSAndroid Build Coastguard Worker fn dev_by_uuid(&self, uuid: &Uuid) -> Option<(Strong<T>, KeyMintHardwareInfo, Uuid)> {
111*e1997b9aSAndroid Build Coastguard Worker self.devices_by_uuid
112*e1997b9aSAndroid Build Coastguard Worker .get(uuid)
113*e1997b9aSAndroid Build Coastguard Worker .map(|(dev, hw_info)| ((*dev).clone(), (*hw_info).clone(), *uuid))
114*e1997b9aSAndroid Build Coastguard Worker }
115*e1997b9aSAndroid Build Coastguard Worker
devices(&self) -> Vec<Strong<T>>116*e1997b9aSAndroid Build Coastguard Worker fn devices(&self) -> Vec<Strong<T>> {
117*e1997b9aSAndroid Build Coastguard Worker self.devices_by_uuid.values().map(|(dev, _)| dev.clone()).collect()
118*e1997b9aSAndroid Build Coastguard Worker }
119*e1997b9aSAndroid Build Coastguard Worker
120*e1997b9aSAndroid Build Coastguard Worker /// The requested security level and the security level of the actual implementation may
121*e1997b9aSAndroid Build Coastguard Worker /// differ. So we map the requested security level to the uuid of the implementation
122*e1997b9aSAndroid Build Coastguard Worker /// so that there cannot be any confusion as to which KeyMint instance is requested.
insert(&mut self, sec_level: SecurityLevel, dev: Strong<T>, hw_info: KeyMintHardwareInfo)123*e1997b9aSAndroid Build Coastguard Worker fn insert(&mut self, sec_level: SecurityLevel, dev: Strong<T>, hw_info: KeyMintHardwareInfo) {
124*e1997b9aSAndroid Build Coastguard Worker // For now we use the reported security level of the KM instance as UUID.
125*e1997b9aSAndroid Build Coastguard Worker // TODO update this section once UUID was added to the KM hardware info.
126*e1997b9aSAndroid Build Coastguard Worker let uuid: Uuid = sec_level.into();
127*e1997b9aSAndroid Build Coastguard Worker self.devices_by_uuid.insert(uuid, (dev, hw_info));
128*e1997b9aSAndroid Build Coastguard Worker self.uuid_by_sec_level.insert(sec_level, uuid);
129*e1997b9aSAndroid Build Coastguard Worker }
130*e1997b9aSAndroid Build Coastguard Worker }
131*e1997b9aSAndroid Build Coastguard Worker
132*e1997b9aSAndroid Build Coastguard Worker impl<T: FromIBinder + ?Sized> Default for DevicesMap<T> {
default() -> Self133*e1997b9aSAndroid Build Coastguard Worker fn default() -> Self {
134*e1997b9aSAndroid Build Coastguard Worker Self {
135*e1997b9aSAndroid Build Coastguard Worker devices_by_uuid: HashMap::<Uuid, (Strong<T>, KeyMintHardwareInfo)>::new(),
136*e1997b9aSAndroid Build Coastguard Worker uuid_by_sec_level: Default::default(),
137*e1997b9aSAndroid Build Coastguard Worker }
138*e1997b9aSAndroid Build Coastguard Worker }
139*e1997b9aSAndroid Build Coastguard Worker }
140*e1997b9aSAndroid Build Coastguard Worker
141*e1997b9aSAndroid Build Coastguard Worker /// The path where keystore stores all its keys.
142*e1997b9aSAndroid Build Coastguard Worker pub static DB_PATH: LazyLock<RwLock<PathBuf>> =
143*e1997b9aSAndroid Build Coastguard Worker LazyLock::new(|| RwLock::new(Path::new("/data/misc/keystore").to_path_buf()));
144*e1997b9aSAndroid Build Coastguard Worker /// Runtime database of unwrapped super keys.
145*e1997b9aSAndroid Build Coastguard Worker pub static SUPER_KEY: LazyLock<Arc<RwLock<SuperKeyManager>>> = LazyLock::new(Default::default);
146*e1997b9aSAndroid Build Coastguard Worker /// Map of KeyMint devices.
147*e1997b9aSAndroid Build Coastguard Worker static KEY_MINT_DEVICES: LazyLock<Mutex<DevicesMap<dyn IKeyMintDevice>>> =
148*e1997b9aSAndroid Build Coastguard Worker LazyLock::new(Default::default);
149*e1997b9aSAndroid Build Coastguard Worker /// Timestamp service.
150*e1997b9aSAndroid Build Coastguard Worker static TIME_STAMP_DEVICE: Mutex<Option<Strong<dyn ISecureClock>>> = Mutex::new(None);
151*e1997b9aSAndroid Build Coastguard Worker /// A single on-demand worker thread that handles deferred tasks with two different
152*e1997b9aSAndroid Build Coastguard Worker /// priorities.
153*e1997b9aSAndroid Build Coastguard Worker pub static ASYNC_TASK: LazyLock<Arc<AsyncTask>> = LazyLock::new(Default::default);
154*e1997b9aSAndroid Build Coastguard Worker /// Singleton for enforcements.
155*e1997b9aSAndroid Build Coastguard Worker pub static ENFORCEMENTS: LazyLock<Enforcements> = LazyLock::new(Default::default);
156*e1997b9aSAndroid Build Coastguard Worker /// LegacyBlobLoader is initialized and exists globally.
157*e1997b9aSAndroid Build Coastguard Worker /// The same directory used by the database is used by the LegacyBlobLoader as well.
158*e1997b9aSAndroid Build Coastguard Worker pub static LEGACY_BLOB_LOADER: LazyLock<Arc<LegacyBlobLoader>> = LazyLock::new(|| {
159*e1997b9aSAndroid Build Coastguard Worker Arc::new(LegacyBlobLoader::new(
160*e1997b9aSAndroid Build Coastguard Worker &DB_PATH.read().expect("Could not determine database path for legacy blob loader"),
161*e1997b9aSAndroid Build Coastguard Worker ))
162*e1997b9aSAndroid Build Coastguard Worker });
163*e1997b9aSAndroid Build Coastguard Worker /// Legacy migrator. Atomically migrates legacy blobs to the database.
164*e1997b9aSAndroid Build Coastguard Worker pub static LEGACY_IMPORTER: LazyLock<Arc<LegacyImporter>> =
165*e1997b9aSAndroid Build Coastguard Worker LazyLock::new(|| Arc::new(LegacyImporter::new(Arc::new(Default::default()))));
166*e1997b9aSAndroid Build Coastguard Worker /// Background thread which handles logging via statsd and logd
167*e1997b9aSAndroid Build Coastguard Worker pub static LOGS_HANDLER: LazyLock<Arc<AsyncTask>> = LazyLock::new(Default::default);
168*e1997b9aSAndroid Build Coastguard Worker /// DER-encoded module information returned by `getSupplementaryAttestationInfo(Tag.MODULE_HASH)`.
169*e1997b9aSAndroid Build Coastguard Worker pub static ENCODED_MODULE_INFO: RwLock<Option<Vec<u8>>> = RwLock::new(None);
170*e1997b9aSAndroid Build Coastguard Worker
171*e1997b9aSAndroid Build Coastguard Worker static GC: LazyLock<Arc<Gc>> = LazyLock::new(|| {
172*e1997b9aSAndroid Build Coastguard Worker Arc::new(Gc::new_init_with(ASYNC_TASK.clone(), || {
173*e1997b9aSAndroid Build Coastguard Worker (
174*e1997b9aSAndroid Build Coastguard Worker Box::new(|uuid, blob| {
175*e1997b9aSAndroid Build Coastguard Worker let km_dev = get_keymint_dev_by_uuid(uuid).map(|(dev, _)| dev)?;
176*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("invalidate key closure: calling IKeyMintDevice::deleteKey");
177*e1997b9aSAndroid Build Coastguard Worker map_km_error(km_dev.deleteKey(blob))
178*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to invalidate key blob."))
179*e1997b9aSAndroid Build Coastguard Worker }),
180*e1997b9aSAndroid Build Coastguard Worker KeystoreDB::new(
181*e1997b9aSAndroid Build Coastguard Worker &DB_PATH.read().expect("Could not determine database path for GC"),
182*e1997b9aSAndroid Build Coastguard Worker None,
183*e1997b9aSAndroid Build Coastguard Worker )
184*e1997b9aSAndroid Build Coastguard Worker .expect("Failed to open database"),
185*e1997b9aSAndroid Build Coastguard Worker SUPER_KEY.clone(),
186*e1997b9aSAndroid Build Coastguard Worker )
187*e1997b9aSAndroid Build Coastguard Worker }))
188*e1997b9aSAndroid Build Coastguard Worker });
189*e1997b9aSAndroid Build Coastguard Worker
190*e1997b9aSAndroid Build Coastguard Worker /// Determine the service name for a KeyMint device of the given security level
191*e1997b9aSAndroid Build Coastguard Worker /// gotten by binder service from the device and determining what services
192*e1997b9aSAndroid Build Coastguard Worker /// are available.
keymint_service_name(security_level: &SecurityLevel) -> Result<Option<String>>193*e1997b9aSAndroid Build Coastguard Worker fn keymint_service_name(security_level: &SecurityLevel) -> Result<Option<String>> {
194*e1997b9aSAndroid Build Coastguard Worker let keymint_descriptor: &str = <BpKeyMintDevice as IKeyMintDevice>::get_descriptor();
195*e1997b9aSAndroid Build Coastguard Worker let keymint_instances = get_declared_instances(keymint_descriptor).unwrap();
196*e1997b9aSAndroid Build Coastguard Worker
197*e1997b9aSAndroid Build Coastguard Worker let service_name = match *security_level {
198*e1997b9aSAndroid Build Coastguard Worker SecurityLevel::TRUSTED_ENVIRONMENT => {
199*e1997b9aSAndroid Build Coastguard Worker if keymint_instances.iter().any(|instance| *instance == "default") {
200*e1997b9aSAndroid Build Coastguard Worker Some(format!("{}/default", keymint_descriptor))
201*e1997b9aSAndroid Build Coastguard Worker } else {
202*e1997b9aSAndroid Build Coastguard Worker None
203*e1997b9aSAndroid Build Coastguard Worker }
204*e1997b9aSAndroid Build Coastguard Worker }
205*e1997b9aSAndroid Build Coastguard Worker SecurityLevel::STRONGBOX => {
206*e1997b9aSAndroid Build Coastguard Worker if keymint_instances.iter().any(|instance| *instance == "strongbox") {
207*e1997b9aSAndroid Build Coastguard Worker Some(format!("{}/strongbox", keymint_descriptor))
208*e1997b9aSAndroid Build Coastguard Worker } else {
209*e1997b9aSAndroid Build Coastguard Worker None
210*e1997b9aSAndroid Build Coastguard Worker }
211*e1997b9aSAndroid Build Coastguard Worker }
212*e1997b9aSAndroid Build Coastguard Worker _ => {
213*e1997b9aSAndroid Build Coastguard Worker return Err(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)).context(ks_err!(
214*e1997b9aSAndroid Build Coastguard Worker "Trying to find keymint for security level: {:?}",
215*e1997b9aSAndroid Build Coastguard Worker security_level
216*e1997b9aSAndroid Build Coastguard Worker ));
217*e1997b9aSAndroid Build Coastguard Worker }
218*e1997b9aSAndroid Build Coastguard Worker };
219*e1997b9aSAndroid Build Coastguard Worker
220*e1997b9aSAndroid Build Coastguard Worker Ok(service_name)
221*e1997b9aSAndroid Build Coastguard Worker }
222*e1997b9aSAndroid Build Coastguard Worker
223*e1997b9aSAndroid Build Coastguard Worker /// Make a new connection to a KeyMint device of the given security level.
224*e1997b9aSAndroid Build Coastguard Worker /// If no native KeyMint device can be found this function also brings
225*e1997b9aSAndroid Build Coastguard Worker /// up the compatibility service and attempts to connect to the legacy wrapper.
connect_keymint( security_level: &SecurityLevel, ) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo)>226*e1997b9aSAndroid Build Coastguard Worker fn connect_keymint(
227*e1997b9aSAndroid Build Coastguard Worker security_level: &SecurityLevel,
228*e1997b9aSAndroid Build Coastguard Worker ) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo)> {
229*e1997b9aSAndroid Build Coastguard Worker // Show the keymint interface that is registered in the binder
230*e1997b9aSAndroid Build Coastguard Worker // service and use the security level to get the service name.
231*e1997b9aSAndroid Build Coastguard Worker let service_name = keymint_service_name(security_level)
232*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Get service name from binder service"))?;
233*e1997b9aSAndroid Build Coastguard Worker
234*e1997b9aSAndroid Build Coastguard Worker let (keymint, hal_version) = if let Some(service_name) = service_name {
235*e1997b9aSAndroid Build Coastguard Worker let km: Strong<dyn IKeyMintDevice> =
236*e1997b9aSAndroid Build Coastguard Worker if SecurityLevel::TRUSTED_ENVIRONMENT == *security_level {
237*e1997b9aSAndroid Build Coastguard Worker map_binder_status_code(retry_get_interface(&service_name))
238*e1997b9aSAndroid Build Coastguard Worker } else {
239*e1997b9aSAndroid Build Coastguard Worker map_binder_status_code(binder::get_interface(&service_name))
240*e1997b9aSAndroid Build Coastguard Worker }
241*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to connect to genuine KeyMint service."))?;
242*e1997b9aSAndroid Build Coastguard Worker // Map the HAL version code for KeyMint to be <AIDL version> * 100, so
243*e1997b9aSAndroid Build Coastguard Worker // - V1 is 100
244*e1997b9aSAndroid Build Coastguard Worker // - V2 is 200
245*e1997b9aSAndroid Build Coastguard Worker // - V3 is 300
246*e1997b9aSAndroid Build Coastguard Worker // etc.
247*e1997b9aSAndroid Build Coastguard Worker let km_version = km.getInterfaceVersion()?;
248*e1997b9aSAndroid Build Coastguard Worker (km, Some(km_version * 100))
249*e1997b9aSAndroid Build Coastguard Worker } else {
250*e1997b9aSAndroid Build Coastguard Worker // This is a no-op if it was called before.
251*e1997b9aSAndroid Build Coastguard Worker keystore2_km_compat::add_keymint_device_service();
252*e1997b9aSAndroid Build Coastguard Worker
253*e1997b9aSAndroid Build Coastguard Worker let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
254*e1997b9aSAndroid Build Coastguard Worker map_binder_status_code(binder::get_interface("android.security.compat"))
255*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to connect to compat service."))?;
256*e1997b9aSAndroid Build Coastguard Worker (
257*e1997b9aSAndroid Build Coastguard Worker map_binder_status(keystore_compat_service.getKeyMintDevice(*security_level))
258*e1997b9aSAndroid Build Coastguard Worker .map_err(|e| match e {
259*e1997b9aSAndroid Build Coastguard Worker Error::BinderTransaction(StatusCode::NAME_NOT_FOUND) => {
260*e1997b9aSAndroid Build Coastguard Worker Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)
261*e1997b9aSAndroid Build Coastguard Worker }
262*e1997b9aSAndroid Build Coastguard Worker e => e,
263*e1997b9aSAndroid Build Coastguard Worker })
264*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!(
265*e1997b9aSAndroid Build Coastguard Worker "Trying to get Legacy wrapper. Attempt to get keystore \
266*e1997b9aSAndroid Build Coastguard Worker compat service for security level {:?}",
267*e1997b9aSAndroid Build Coastguard Worker *security_level
268*e1997b9aSAndroid Build Coastguard Worker ))?,
269*e1997b9aSAndroid Build Coastguard Worker None,
270*e1997b9aSAndroid Build Coastguard Worker )
271*e1997b9aSAndroid Build Coastguard Worker };
272*e1997b9aSAndroid Build Coastguard Worker
273*e1997b9aSAndroid Build Coastguard Worker // If the KeyMint device is back-level, use a wrapper that intercepts and
274*e1997b9aSAndroid Build Coastguard Worker // emulates things that are not supported by the hardware.
275*e1997b9aSAndroid Build Coastguard Worker let keymint = match hal_version {
276*e1997b9aSAndroid Build Coastguard Worker Some(400) | Some(300) | Some(200) => {
277*e1997b9aSAndroid Build Coastguard Worker // KeyMint v2+: use as-is (we don't have any software emulation of v3 or v4-specific KeyMint features).
278*e1997b9aSAndroid Build Coastguard Worker log::info!(
279*e1997b9aSAndroid Build Coastguard Worker "KeyMint device is current version ({:?}) for security level: {:?}",
280*e1997b9aSAndroid Build Coastguard Worker hal_version,
281*e1997b9aSAndroid Build Coastguard Worker security_level
282*e1997b9aSAndroid Build Coastguard Worker );
283*e1997b9aSAndroid Build Coastguard Worker keymint
284*e1997b9aSAndroid Build Coastguard Worker }
285*e1997b9aSAndroid Build Coastguard Worker Some(100) => {
286*e1997b9aSAndroid Build Coastguard Worker // KeyMint v1: perform software emulation.
287*e1997b9aSAndroid Build Coastguard Worker log::info!(
288*e1997b9aSAndroid Build Coastguard Worker "Add emulation wrapper around {:?} device for security level: {:?}",
289*e1997b9aSAndroid Build Coastguard Worker hal_version,
290*e1997b9aSAndroid Build Coastguard Worker security_level
291*e1997b9aSAndroid Build Coastguard Worker );
292*e1997b9aSAndroid Build Coastguard Worker BacklevelKeyMintWrapper::wrap(KeyMintV1::new(*security_level), keymint)
293*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to create V1 compatibility wrapper."))?
294*e1997b9aSAndroid Build Coastguard Worker }
295*e1997b9aSAndroid Build Coastguard Worker None => {
296*e1997b9aSAndroid Build Coastguard Worker // Compatibility wrapper around a KeyMaster device: this roughly
297*e1997b9aSAndroid Build Coastguard Worker // behaves like KeyMint V1 (e.g. it includes AGREE_KEY support,
298*e1997b9aSAndroid Build Coastguard Worker // albeit in software.)
299*e1997b9aSAndroid Build Coastguard Worker log::info!(
300*e1997b9aSAndroid Build Coastguard Worker "Add emulation wrapper around Keymaster device for security level: {:?}",
301*e1997b9aSAndroid Build Coastguard Worker security_level
302*e1997b9aSAndroid Build Coastguard Worker );
303*e1997b9aSAndroid Build Coastguard Worker BacklevelKeyMintWrapper::wrap(KeyMintV1::new(*security_level), keymint)
304*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to create km_compat V1 compatibility wrapper ."))?
305*e1997b9aSAndroid Build Coastguard Worker }
306*e1997b9aSAndroid Build Coastguard Worker _ => {
307*e1997b9aSAndroid Build Coastguard Worker return Err(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)).context(ks_err!(
308*e1997b9aSAndroid Build Coastguard Worker "unexpected hal_version {:?} for security level: {:?}",
309*e1997b9aSAndroid Build Coastguard Worker hal_version,
310*e1997b9aSAndroid Build Coastguard Worker security_level
311*e1997b9aSAndroid Build Coastguard Worker ));
312*e1997b9aSAndroid Build Coastguard Worker }
313*e1997b9aSAndroid Build Coastguard Worker };
314*e1997b9aSAndroid Build Coastguard Worker
315*e1997b9aSAndroid Build Coastguard Worker let wp = wd::watch("connect_keymint: calling IKeyMintDevice::getHardwareInfo()");
316*e1997b9aSAndroid Build Coastguard Worker let mut hw_info =
317*e1997b9aSAndroid Build Coastguard Worker map_km_error(keymint.getHardwareInfo()).context(ks_err!("Failed to get hardware info."))?;
318*e1997b9aSAndroid Build Coastguard Worker drop(wp);
319*e1997b9aSAndroid Build Coastguard Worker
320*e1997b9aSAndroid Build Coastguard Worker // The legacy wrapper sets hw_info.versionNumber to the underlying HAL version like so:
321*e1997b9aSAndroid Build Coastguard Worker // 10 * <major> + <minor>, e.g., KM 3.0 = 30. So 30, 40, and 41 are the only viable values.
322*e1997b9aSAndroid Build Coastguard Worker //
323*e1997b9aSAndroid Build Coastguard Worker // For KeyMint the returned versionNumber is implementation defined and thus completely
324*e1997b9aSAndroid Build Coastguard Worker // meaningless to Keystore 2.0. So set the versionNumber field that is returned to
325*e1997b9aSAndroid Build Coastguard Worker // the rest of the code to be the <AIDL version> * 100, so KeyMint V1 is 100, KeyMint V2 is 200
326*e1997b9aSAndroid Build Coastguard Worker // and so on.
327*e1997b9aSAndroid Build Coastguard Worker //
328*e1997b9aSAndroid Build Coastguard Worker // This ensures that versionNumber value across KeyMaster and KeyMint is monotonically
329*e1997b9aSAndroid Build Coastguard Worker // increasing (and so comparisons like `versionNumber >= KEY_MINT_1` are valid).
330*e1997b9aSAndroid Build Coastguard Worker if let Some(hal_version) = hal_version {
331*e1997b9aSAndroid Build Coastguard Worker hw_info.versionNumber = hal_version;
332*e1997b9aSAndroid Build Coastguard Worker }
333*e1997b9aSAndroid Build Coastguard Worker
334*e1997b9aSAndroid Build Coastguard Worker Ok((keymint, hw_info))
335*e1997b9aSAndroid Build Coastguard Worker }
336*e1997b9aSAndroid Build Coastguard Worker
337*e1997b9aSAndroid Build Coastguard Worker /// Get a keymint device for the given security level either from our cache or
338*e1997b9aSAndroid Build Coastguard Worker /// by making a new connection. Returns the device, the hardware info and the uuid.
339*e1997b9aSAndroid Build Coastguard Worker /// TODO the latter can be removed when the uuid is part of the hardware info.
get_keymint_device( security_level: &SecurityLevel, ) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo, Uuid)>340*e1997b9aSAndroid Build Coastguard Worker pub fn get_keymint_device(
341*e1997b9aSAndroid Build Coastguard Worker security_level: &SecurityLevel,
342*e1997b9aSAndroid Build Coastguard Worker ) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo, Uuid)> {
343*e1997b9aSAndroid Build Coastguard Worker let mut devices_map = KEY_MINT_DEVICES.lock().unwrap();
344*e1997b9aSAndroid Build Coastguard Worker if let Some((dev, hw_info, uuid)) = devices_map.dev_by_sec_level(security_level) {
345*e1997b9aSAndroid Build Coastguard Worker Ok((dev, hw_info, uuid))
346*e1997b9aSAndroid Build Coastguard Worker } else {
347*e1997b9aSAndroid Build Coastguard Worker let (dev, hw_info) =
348*e1997b9aSAndroid Build Coastguard Worker connect_keymint(security_level).context(ks_err!("Cannot connect to Keymint"))?;
349*e1997b9aSAndroid Build Coastguard Worker devices_map.insert(*security_level, dev, hw_info);
350*e1997b9aSAndroid Build Coastguard Worker // Unwrap must succeed because we just inserted it.
351*e1997b9aSAndroid Build Coastguard Worker Ok(devices_map.dev_by_sec_level(security_level).unwrap())
352*e1997b9aSAndroid Build Coastguard Worker }
353*e1997b9aSAndroid Build Coastguard Worker }
354*e1997b9aSAndroid Build Coastguard Worker
355*e1997b9aSAndroid Build Coastguard Worker /// Get a keymint device for the given uuid. This will only access the cache, but will not
356*e1997b9aSAndroid Build Coastguard Worker /// attempt to establish a new connection. It is assumed that the cache is already populated
357*e1997b9aSAndroid Build Coastguard Worker /// when this is called. This is a fair assumption, because service.rs iterates through all
358*e1997b9aSAndroid Build Coastguard Worker /// security levels when it gets instantiated.
get_keymint_dev_by_uuid( uuid: &Uuid, ) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo)>359*e1997b9aSAndroid Build Coastguard Worker pub fn get_keymint_dev_by_uuid(
360*e1997b9aSAndroid Build Coastguard Worker uuid: &Uuid,
361*e1997b9aSAndroid Build Coastguard Worker ) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo)> {
362*e1997b9aSAndroid Build Coastguard Worker let devices_map = KEY_MINT_DEVICES.lock().unwrap();
363*e1997b9aSAndroid Build Coastguard Worker if let Some((dev, hw_info, _)) = devices_map.dev_by_uuid(uuid) {
364*e1997b9aSAndroid Build Coastguard Worker Ok((dev, hw_info))
365*e1997b9aSAndroid Build Coastguard Worker } else {
366*e1997b9aSAndroid Build Coastguard Worker Err(Error::sys()).context(ks_err!("No KeyMint instance found."))
367*e1997b9aSAndroid Build Coastguard Worker }
368*e1997b9aSAndroid Build Coastguard Worker }
369*e1997b9aSAndroid Build Coastguard Worker
370*e1997b9aSAndroid Build Coastguard Worker /// Return all known keymint devices.
get_keymint_devices() -> Vec<Strong<dyn IKeyMintDevice>>371*e1997b9aSAndroid Build Coastguard Worker pub fn get_keymint_devices() -> Vec<Strong<dyn IKeyMintDevice>> {
372*e1997b9aSAndroid Build Coastguard Worker KEY_MINT_DEVICES.lock().unwrap().devices()
373*e1997b9aSAndroid Build Coastguard Worker }
374*e1997b9aSAndroid Build Coastguard Worker
375*e1997b9aSAndroid Build Coastguard Worker /// Make a new connection to a secure clock service.
376*e1997b9aSAndroid Build Coastguard Worker /// If no native SecureClock device can be found brings up the compatibility service and attempts
377*e1997b9aSAndroid Build Coastguard Worker /// to connect to the legacy wrapper.
connect_secureclock() -> Result<Strong<dyn ISecureClock>>378*e1997b9aSAndroid Build Coastguard Worker fn connect_secureclock() -> Result<Strong<dyn ISecureClock>> {
379*e1997b9aSAndroid Build Coastguard Worker let secure_clock_descriptor: &str = <BpSecureClock as ISecureClock>::get_descriptor();
380*e1997b9aSAndroid Build Coastguard Worker let secureclock_instances = get_declared_instances(secure_clock_descriptor).unwrap();
381*e1997b9aSAndroid Build Coastguard Worker
382*e1997b9aSAndroid Build Coastguard Worker let secure_clock_available =
383*e1997b9aSAndroid Build Coastguard Worker secureclock_instances.iter().any(|instance| *instance == "default");
384*e1997b9aSAndroid Build Coastguard Worker
385*e1997b9aSAndroid Build Coastguard Worker let default_time_stamp_service_name = format!("{}/default", secure_clock_descriptor);
386*e1997b9aSAndroid Build Coastguard Worker
387*e1997b9aSAndroid Build Coastguard Worker let secureclock = if secure_clock_available {
388*e1997b9aSAndroid Build Coastguard Worker map_binder_status_code(binder::get_interface(&default_time_stamp_service_name))
389*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to connect to genuine secure clock service."))
390*e1997b9aSAndroid Build Coastguard Worker } else {
391*e1997b9aSAndroid Build Coastguard Worker // This is a no-op if it was called before.
392*e1997b9aSAndroid Build Coastguard Worker keystore2_km_compat::add_keymint_device_service();
393*e1997b9aSAndroid Build Coastguard Worker
394*e1997b9aSAndroid Build Coastguard Worker let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
395*e1997b9aSAndroid Build Coastguard Worker map_binder_status_code(binder::get_interface("android.security.compat"))
396*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to connect to compat service."))?;
397*e1997b9aSAndroid Build Coastguard Worker
398*e1997b9aSAndroid Build Coastguard Worker // Legacy secure clock services were only implemented by TEE.
399*e1997b9aSAndroid Build Coastguard Worker map_binder_status(keystore_compat_service.getSecureClock())
400*e1997b9aSAndroid Build Coastguard Worker .map_err(|e| match e {
401*e1997b9aSAndroid Build Coastguard Worker Error::BinderTransaction(StatusCode::NAME_NOT_FOUND) => {
402*e1997b9aSAndroid Build Coastguard Worker Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)
403*e1997b9aSAndroid Build Coastguard Worker }
404*e1997b9aSAndroid Build Coastguard Worker e => e,
405*e1997b9aSAndroid Build Coastguard Worker })
406*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed attempt to get legacy secure clock."))
407*e1997b9aSAndroid Build Coastguard Worker }?;
408*e1997b9aSAndroid Build Coastguard Worker
409*e1997b9aSAndroid Build Coastguard Worker Ok(secureclock)
410*e1997b9aSAndroid Build Coastguard Worker }
411*e1997b9aSAndroid Build Coastguard Worker
412*e1997b9aSAndroid Build Coastguard Worker /// Get the timestamp service that verifies auth token timeliness towards security levels with
413*e1997b9aSAndroid Build Coastguard Worker /// different clocks.
get_timestamp_service() -> Result<Strong<dyn ISecureClock>>414*e1997b9aSAndroid Build Coastguard Worker pub fn get_timestamp_service() -> Result<Strong<dyn ISecureClock>> {
415*e1997b9aSAndroid Build Coastguard Worker let mut ts_device = TIME_STAMP_DEVICE.lock().unwrap();
416*e1997b9aSAndroid Build Coastguard Worker if let Some(dev) = &*ts_device {
417*e1997b9aSAndroid Build Coastguard Worker Ok(dev.clone())
418*e1997b9aSAndroid Build Coastguard Worker } else {
419*e1997b9aSAndroid Build Coastguard Worker let dev = connect_secureclock().context(ks_err!())?;
420*e1997b9aSAndroid Build Coastguard Worker *ts_device = Some(dev.clone());
421*e1997b9aSAndroid Build Coastguard Worker Ok(dev)
422*e1997b9aSAndroid Build Coastguard Worker }
423*e1997b9aSAndroid Build Coastguard Worker }
424*e1997b9aSAndroid Build Coastguard Worker
425*e1997b9aSAndroid Build Coastguard Worker /// Get the service name of a remotely provisioned component corresponding to given security level.
get_remotely_provisioned_component_name(security_level: &SecurityLevel) -> Result<String>426*e1997b9aSAndroid Build Coastguard Worker pub fn get_remotely_provisioned_component_name(security_level: &SecurityLevel) -> Result<String> {
427*e1997b9aSAndroid Build Coastguard Worker let remote_prov_descriptor: &str =
428*e1997b9aSAndroid Build Coastguard Worker <BpRemotelyProvisionedComponent as IRemotelyProvisionedComponent>::get_descriptor();
429*e1997b9aSAndroid Build Coastguard Worker
430*e1997b9aSAndroid Build Coastguard Worker match *security_level {
431*e1997b9aSAndroid Build Coastguard Worker SecurityLevel::TRUSTED_ENVIRONMENT => {
432*e1997b9aSAndroid Build Coastguard Worker let instance = format!("{}/default", remote_prov_descriptor);
433*e1997b9aSAndroid Build Coastguard Worker if is_declared(&instance)? {
434*e1997b9aSAndroid Build Coastguard Worker Some(instance)
435*e1997b9aSAndroid Build Coastguard Worker } else {
436*e1997b9aSAndroid Build Coastguard Worker None
437*e1997b9aSAndroid Build Coastguard Worker }
438*e1997b9aSAndroid Build Coastguard Worker }
439*e1997b9aSAndroid Build Coastguard Worker SecurityLevel::STRONGBOX => {
440*e1997b9aSAndroid Build Coastguard Worker let instance = format!("{}/strongbox", remote_prov_descriptor);
441*e1997b9aSAndroid Build Coastguard Worker if is_declared(&instance)? {
442*e1997b9aSAndroid Build Coastguard Worker Some(instance)
443*e1997b9aSAndroid Build Coastguard Worker } else {
444*e1997b9aSAndroid Build Coastguard Worker None
445*e1997b9aSAndroid Build Coastguard Worker }
446*e1997b9aSAndroid Build Coastguard Worker }
447*e1997b9aSAndroid Build Coastguard Worker _ => None,
448*e1997b9aSAndroid Build Coastguard Worker }
449*e1997b9aSAndroid Build Coastguard Worker .ok_or(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
450*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to get rpc for sec level {:?}", *security_level))
451*e1997b9aSAndroid Build Coastguard Worker }
452