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