1*e1997b9aSAndroid Build Coastguard Worker // Copyright 2021, 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 implements IKeystoreMaintenance AIDL interface. 16*e1997b9aSAndroid Build Coastguard Worker 17*e1997b9aSAndroid Build Coastguard Worker use crate::database::{KeyEntryLoadBits, KeyType}; 18*e1997b9aSAndroid Build Coastguard Worker use crate::error::into_logged_binder; 19*e1997b9aSAndroid Build Coastguard Worker use crate::error::map_km_error; 20*e1997b9aSAndroid Build Coastguard Worker use crate::error::Error; 21*e1997b9aSAndroid Build Coastguard Worker use crate::globals::get_keymint_device; 22*e1997b9aSAndroid Build Coastguard Worker use crate::globals::{DB, LEGACY_IMPORTER, SUPER_KEY, ENCODED_MODULE_INFO}; 23*e1997b9aSAndroid Build Coastguard Worker use crate::ks_err; 24*e1997b9aSAndroid Build Coastguard Worker use crate::permission::{KeyPerm, KeystorePerm}; 25*e1997b9aSAndroid Build Coastguard Worker use crate::super_key::SuperKeyManager; 26*e1997b9aSAndroid Build Coastguard Worker use crate::utils::{ 27*e1997b9aSAndroid Build Coastguard Worker check_dump_permission, check_get_app_uids_affected_by_sid_permissions, check_key_permission, 28*e1997b9aSAndroid Build Coastguard Worker check_keystore_permission, uid_to_android_user, watchdog as wd, 29*e1997b9aSAndroid Build Coastguard Worker }; 30*e1997b9aSAndroid Build Coastguard Worker use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{ 31*e1997b9aSAndroid Build Coastguard Worker ErrorCode::ErrorCode, IKeyMintDevice::IKeyMintDevice, KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, Tag::Tag, 32*e1997b9aSAndroid Build Coastguard Worker }; 33*e1997b9aSAndroid Build Coastguard Worker use android_security_maintenance::aidl::android::security::maintenance::IKeystoreMaintenance::{ 34*e1997b9aSAndroid Build Coastguard Worker BnKeystoreMaintenance, IKeystoreMaintenance, 35*e1997b9aSAndroid Build Coastguard Worker }; 36*e1997b9aSAndroid Build Coastguard Worker use android_security_maintenance::binder::{ 37*e1997b9aSAndroid Build Coastguard Worker BinderFeatures, Interface, Result as BinderResult, Strong, ThreadState, 38*e1997b9aSAndroid Build Coastguard Worker }; 39*e1997b9aSAndroid Build Coastguard Worker use android_security_metrics::aidl::android::security::metrics::{ 40*e1997b9aSAndroid Build Coastguard Worker KeystoreAtomPayload::KeystoreAtomPayload::StorageStats 41*e1997b9aSAndroid Build Coastguard Worker }; 42*e1997b9aSAndroid Build Coastguard Worker use android_system_keystore2::aidl::android::system::keystore2::KeyDescriptor::KeyDescriptor; 43*e1997b9aSAndroid Build Coastguard Worker use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode; 44*e1997b9aSAndroid Build Coastguard Worker use anyhow::{anyhow, Context, Result}; 45*e1997b9aSAndroid Build Coastguard Worker use bssl_crypto::digest; 46*e1997b9aSAndroid Build Coastguard Worker use der::{DerOrd, Encode, asn1::OctetString, asn1::SetOfVec, Sequence}; 47*e1997b9aSAndroid Build Coastguard Worker use keystore2_crypto::Password; 48*e1997b9aSAndroid Build Coastguard Worker use std::cmp::Ordering; 49*e1997b9aSAndroid Build Coastguard Worker 50*e1997b9aSAndroid Build Coastguard Worker /// Reexport Domain for the benefit of DeleteListener 51*e1997b9aSAndroid Build Coastguard Worker pub use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain; 52*e1997b9aSAndroid Build Coastguard Worker 53*e1997b9aSAndroid Build Coastguard Worker /// Version number of KeyMint V4. 54*e1997b9aSAndroid Build Coastguard Worker pub const KEYMINT_V4: i32 = 400; 55*e1997b9aSAndroid Build Coastguard Worker 56*e1997b9aSAndroid Build Coastguard Worker /// Module information structure for DER-encoding. 57*e1997b9aSAndroid Build Coastguard Worker #[derive(Sequence, Debug)] 58*e1997b9aSAndroid Build Coastguard Worker struct ModuleInfo { 59*e1997b9aSAndroid Build Coastguard Worker name: OctetString, 60*e1997b9aSAndroid Build Coastguard Worker version: i32, 61*e1997b9aSAndroid Build Coastguard Worker } 62*e1997b9aSAndroid Build Coastguard Worker 63*e1997b9aSAndroid Build Coastguard Worker impl DerOrd for ModuleInfo { 64*e1997b9aSAndroid Build Coastguard Worker // DER mandates "encodings of the component values of a set-of value shall appear in ascending 65*e1997b9aSAndroid Build Coastguard Worker // order". `der_cmp` serves as a proxy for determining that ordering (though why the `der` crate 66*e1997b9aSAndroid Build Coastguard Worker // requires this is unclear). Essentially, we just need to compare the `name` lengths, and then 67*e1997b9aSAndroid Build Coastguard Worker // if those are equal, the `name`s themselves. (No need to consider `version`s since there can't 68*e1997b9aSAndroid Build Coastguard Worker // be more than one `ModuleInfo` with the same `name` in the set-of `ModuleInfo`s.) We rely on 69*e1997b9aSAndroid Build Coastguard Worker // `OctetString`'s `der_cmp` to do the aforementioned comparison. der_cmp(&self, other: &Self) -> std::result::Result<Ordering, der::Error>70*e1997b9aSAndroid Build Coastguard Worker fn der_cmp(&self, other: &Self) -> std::result::Result<Ordering, der::Error> { 71*e1997b9aSAndroid Build Coastguard Worker self.name.der_cmp(&other.name) 72*e1997b9aSAndroid Build Coastguard Worker } 73*e1997b9aSAndroid Build Coastguard Worker } 74*e1997b9aSAndroid Build Coastguard Worker 75*e1997b9aSAndroid Build Coastguard Worker /// The Maintenance module takes a delete listener argument which observes user and namespace 76*e1997b9aSAndroid Build Coastguard Worker /// deletion events. 77*e1997b9aSAndroid Build Coastguard Worker pub trait DeleteListener { 78*e1997b9aSAndroid Build Coastguard Worker /// Called by the maintenance module when an app/namespace is deleted. delete_namespace(&self, domain: Domain, namespace: i64) -> Result<()>79*e1997b9aSAndroid Build Coastguard Worker fn delete_namespace(&self, domain: Domain, namespace: i64) -> Result<()>; 80*e1997b9aSAndroid Build Coastguard Worker /// Called by the maintenance module when a user is deleted. delete_user(&self, user_id: u32) -> Result<()>81*e1997b9aSAndroid Build Coastguard Worker fn delete_user(&self, user_id: u32) -> Result<()>; 82*e1997b9aSAndroid Build Coastguard Worker } 83*e1997b9aSAndroid Build Coastguard Worker 84*e1997b9aSAndroid Build Coastguard Worker /// This struct is defined to implement the aforementioned AIDL interface. 85*e1997b9aSAndroid Build Coastguard Worker pub struct Maintenance { 86*e1997b9aSAndroid Build Coastguard Worker delete_listener: Box<dyn DeleteListener + Send + Sync + 'static>, 87*e1997b9aSAndroid Build Coastguard Worker } 88*e1997b9aSAndroid Build Coastguard Worker 89*e1997b9aSAndroid Build Coastguard Worker impl Maintenance { 90*e1997b9aSAndroid Build Coastguard Worker /// Create a new instance of Keystore Maintenance service. new_native_binder( delete_listener: Box<dyn DeleteListener + Send + Sync + 'static>, ) -> Result<Strong<dyn IKeystoreMaintenance>>91*e1997b9aSAndroid Build Coastguard Worker pub fn new_native_binder( 92*e1997b9aSAndroid Build Coastguard Worker delete_listener: Box<dyn DeleteListener + Send + Sync + 'static>, 93*e1997b9aSAndroid Build Coastguard Worker ) -> Result<Strong<dyn IKeystoreMaintenance>> { 94*e1997b9aSAndroid Build Coastguard Worker Ok(BnKeystoreMaintenance::new_binder( 95*e1997b9aSAndroid Build Coastguard Worker Self { delete_listener }, 96*e1997b9aSAndroid Build Coastguard Worker BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() }, 97*e1997b9aSAndroid Build Coastguard Worker )) 98*e1997b9aSAndroid Build Coastguard Worker } 99*e1997b9aSAndroid Build Coastguard Worker add_or_remove_user(&self, user_id: i32) -> Result<()>100*e1997b9aSAndroid Build Coastguard Worker fn add_or_remove_user(&self, user_id: i32) -> Result<()> { 101*e1997b9aSAndroid Build Coastguard Worker // Check permission. Function should return if this failed. Therefore having '?' at the end 102*e1997b9aSAndroid Build Coastguard Worker // is very important. 103*e1997b9aSAndroid Build Coastguard Worker check_keystore_permission(KeystorePerm::ChangeUser).context(ks_err!())?; 104*e1997b9aSAndroid Build Coastguard Worker 105*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| { 106*e1997b9aSAndroid Build Coastguard Worker SUPER_KEY.write().unwrap().remove_user( 107*e1997b9aSAndroid Build Coastguard Worker &mut db.borrow_mut(), 108*e1997b9aSAndroid Build Coastguard Worker &LEGACY_IMPORTER, 109*e1997b9aSAndroid Build Coastguard Worker user_id as u32, 110*e1997b9aSAndroid Build Coastguard Worker ) 111*e1997b9aSAndroid Build Coastguard Worker }) 112*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to delete keys from db."))?; 113*e1997b9aSAndroid Build Coastguard Worker self.delete_listener 114*e1997b9aSAndroid Build Coastguard Worker .delete_user(user_id as u32) 115*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("While invoking the delete listener.")) 116*e1997b9aSAndroid Build Coastguard Worker } 117*e1997b9aSAndroid Build Coastguard Worker init_user_super_keys( &self, user_id: i32, password: Password, allow_existing: bool, ) -> Result<()>118*e1997b9aSAndroid Build Coastguard Worker fn init_user_super_keys( 119*e1997b9aSAndroid Build Coastguard Worker &self, 120*e1997b9aSAndroid Build Coastguard Worker user_id: i32, 121*e1997b9aSAndroid Build Coastguard Worker password: Password, 122*e1997b9aSAndroid Build Coastguard Worker allow_existing: bool, 123*e1997b9aSAndroid Build Coastguard Worker ) -> Result<()> { 124*e1997b9aSAndroid Build Coastguard Worker // Permission check. Must return on error. Do not touch the '?'. 125*e1997b9aSAndroid Build Coastguard Worker check_keystore_permission(KeystorePerm::ChangeUser).context(ks_err!())?; 126*e1997b9aSAndroid Build Coastguard Worker 127*e1997b9aSAndroid Build Coastguard Worker let mut skm = SUPER_KEY.write().unwrap(); 128*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| { 129*e1997b9aSAndroid Build Coastguard Worker skm.initialize_user( 130*e1997b9aSAndroid Build Coastguard Worker &mut db.borrow_mut(), 131*e1997b9aSAndroid Build Coastguard Worker &LEGACY_IMPORTER, 132*e1997b9aSAndroid Build Coastguard Worker user_id as u32, 133*e1997b9aSAndroid Build Coastguard Worker &password, 134*e1997b9aSAndroid Build Coastguard Worker allow_existing, 135*e1997b9aSAndroid Build Coastguard Worker ) 136*e1997b9aSAndroid Build Coastguard Worker }) 137*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to initialize user super keys")) 138*e1997b9aSAndroid Build Coastguard Worker } 139*e1997b9aSAndroid Build Coastguard Worker 140*e1997b9aSAndroid Build Coastguard Worker // Deletes all auth-bound keys when the user's LSKF is removed. on_user_lskf_removed(user_id: i32) -> Result<()>141*e1997b9aSAndroid Build Coastguard Worker fn on_user_lskf_removed(user_id: i32) -> Result<()> { 142*e1997b9aSAndroid Build Coastguard Worker // Permission check. Must return on error. Do not touch the '?'. 143*e1997b9aSAndroid Build Coastguard Worker check_keystore_permission(KeystorePerm::ChangePassword).context(ks_err!())?; 144*e1997b9aSAndroid Build Coastguard Worker 145*e1997b9aSAndroid Build Coastguard Worker LEGACY_IMPORTER 146*e1997b9aSAndroid Build Coastguard Worker .bulk_delete_user(user_id as u32, true) 147*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to delete legacy keys."))?; 148*e1997b9aSAndroid Build Coastguard Worker 149*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| db.borrow_mut().unbind_auth_bound_keys_for_user(user_id as u32)) 150*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to delete auth-bound keys.")) 151*e1997b9aSAndroid Build Coastguard Worker } 152*e1997b9aSAndroid Build Coastguard Worker clear_namespace(&self, domain: Domain, nspace: i64) -> Result<()>153*e1997b9aSAndroid Build Coastguard Worker fn clear_namespace(&self, domain: Domain, nspace: i64) -> Result<()> { 154*e1997b9aSAndroid Build Coastguard Worker // Permission check. Must return on error. Do not touch the '?'. 155*e1997b9aSAndroid Build Coastguard Worker check_keystore_permission(KeystorePerm::ClearUID).context("In clear_namespace.")?; 156*e1997b9aSAndroid Build Coastguard Worker 157*e1997b9aSAndroid Build Coastguard Worker LEGACY_IMPORTER 158*e1997b9aSAndroid Build Coastguard Worker .bulk_delete_uid(domain, nspace) 159*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to delete legacy keys."))?; 160*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| db.borrow_mut().unbind_keys_for_namespace(domain, nspace)) 161*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Trying to delete keys from db."))?; 162*e1997b9aSAndroid Build Coastguard Worker self.delete_listener 163*e1997b9aSAndroid Build Coastguard Worker .delete_namespace(domain, nspace) 164*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("While invoking the delete listener.")) 165*e1997b9aSAndroid Build Coastguard Worker } 166*e1997b9aSAndroid Build Coastguard Worker call_with_watchdog<F>( sec_level: SecurityLevel, name: &'static str, op: &F, min_version: Option<i32>, ) -> Result<()> where F: Fn(Strong<dyn IKeyMintDevice>) -> binder::Result<()>,167*e1997b9aSAndroid Build Coastguard Worker fn call_with_watchdog<F>( 168*e1997b9aSAndroid Build Coastguard Worker sec_level: SecurityLevel, 169*e1997b9aSAndroid Build Coastguard Worker name: &'static str, 170*e1997b9aSAndroid Build Coastguard Worker op: &F, 171*e1997b9aSAndroid Build Coastguard Worker min_version: Option<i32>, 172*e1997b9aSAndroid Build Coastguard Worker ) -> Result<()> 173*e1997b9aSAndroid Build Coastguard Worker where 174*e1997b9aSAndroid Build Coastguard Worker F: Fn(Strong<dyn IKeyMintDevice>) -> binder::Result<()>, 175*e1997b9aSAndroid Build Coastguard Worker { 176*e1997b9aSAndroid Build Coastguard Worker let (km_dev, hw_info, _) = 177*e1997b9aSAndroid Build Coastguard Worker get_keymint_device(&sec_level).context(ks_err!("getting keymint device"))?; 178*e1997b9aSAndroid Build Coastguard Worker 179*e1997b9aSAndroid Build Coastguard Worker if let Some(min_version) = min_version { 180*e1997b9aSAndroid Build Coastguard Worker if hw_info.versionNumber < min_version { 181*e1997b9aSAndroid Build Coastguard Worker log::info!("skipping {name} for {sec_level:?} since its keymint version {} is less than the minimum required version {min_version}", hw_info.versionNumber); 182*e1997b9aSAndroid Build Coastguard Worker return Ok(()); 183*e1997b9aSAndroid Build Coastguard Worker } 184*e1997b9aSAndroid Build Coastguard Worker } 185*e1997b9aSAndroid Build Coastguard Worker 186*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch_millis_with("Maintenance::call_with_watchdog", 500, (sec_level, name)); 187*e1997b9aSAndroid Build Coastguard Worker map_km_error(op(km_dev)).with_context(|| ks_err!("calling {}", name))?; 188*e1997b9aSAndroid Build Coastguard Worker Ok(()) 189*e1997b9aSAndroid Build Coastguard Worker } 190*e1997b9aSAndroid Build Coastguard Worker call_on_all_security_levels<F>( name: &'static str, op: F, min_version: Option<i32>, ) -> Result<()> where F: Fn(Strong<dyn IKeyMintDevice>) -> binder::Result<()>,191*e1997b9aSAndroid Build Coastguard Worker fn call_on_all_security_levels<F>( 192*e1997b9aSAndroid Build Coastguard Worker name: &'static str, 193*e1997b9aSAndroid Build Coastguard Worker op: F, 194*e1997b9aSAndroid Build Coastguard Worker min_version: Option<i32>, 195*e1997b9aSAndroid Build Coastguard Worker ) -> Result<()> 196*e1997b9aSAndroid Build Coastguard Worker where 197*e1997b9aSAndroid Build Coastguard Worker F: Fn(Strong<dyn IKeyMintDevice>) -> binder::Result<()>, 198*e1997b9aSAndroid Build Coastguard Worker { 199*e1997b9aSAndroid Build Coastguard Worker let sec_levels = [ 200*e1997b9aSAndroid Build Coastguard Worker (SecurityLevel::TRUSTED_ENVIRONMENT, "TRUSTED_ENVIRONMENT"), 201*e1997b9aSAndroid Build Coastguard Worker (SecurityLevel::STRONGBOX, "STRONGBOX"), 202*e1997b9aSAndroid Build Coastguard Worker ]; 203*e1997b9aSAndroid Build Coastguard Worker sec_levels.iter().try_fold((), |_result, (sec_level, sec_level_string)| { 204*e1997b9aSAndroid Build Coastguard Worker let curr_result = Maintenance::call_with_watchdog(*sec_level, name, &op, min_version); 205*e1997b9aSAndroid Build Coastguard Worker match curr_result { 206*e1997b9aSAndroid Build Coastguard Worker Ok(()) => log::info!( 207*e1997b9aSAndroid Build Coastguard Worker "Call to {} succeeded for security level {}.", 208*e1997b9aSAndroid Build Coastguard Worker name, 209*e1997b9aSAndroid Build Coastguard Worker &sec_level_string 210*e1997b9aSAndroid Build Coastguard Worker ), 211*e1997b9aSAndroid Build Coastguard Worker Err(ref e) => { 212*e1997b9aSAndroid Build Coastguard Worker if *sec_level == SecurityLevel::STRONGBOX 213*e1997b9aSAndroid Build Coastguard Worker && e.downcast_ref::<Error>() 214*e1997b9aSAndroid Build Coastguard Worker == Some(&Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)) 215*e1997b9aSAndroid Build Coastguard Worker { 216*e1997b9aSAndroid Build Coastguard Worker log::info!("Call to {} failed for StrongBox as it is not available", name,) 217*e1997b9aSAndroid Build Coastguard Worker } else { 218*e1997b9aSAndroid Build Coastguard Worker log::error!( 219*e1997b9aSAndroid Build Coastguard Worker "Call to {} failed for security level {}: {}.", 220*e1997b9aSAndroid Build Coastguard Worker name, 221*e1997b9aSAndroid Build Coastguard Worker &sec_level_string, 222*e1997b9aSAndroid Build Coastguard Worker e 223*e1997b9aSAndroid Build Coastguard Worker ) 224*e1997b9aSAndroid Build Coastguard Worker } 225*e1997b9aSAndroid Build Coastguard Worker } 226*e1997b9aSAndroid Build Coastguard Worker } 227*e1997b9aSAndroid Build Coastguard Worker curr_result 228*e1997b9aSAndroid Build Coastguard Worker }) 229*e1997b9aSAndroid Build Coastguard Worker } 230*e1997b9aSAndroid Build Coastguard Worker early_boot_ended() -> Result<()>231*e1997b9aSAndroid Build Coastguard Worker fn early_boot_ended() -> Result<()> { 232*e1997b9aSAndroid Build Coastguard Worker check_keystore_permission(KeystorePerm::EarlyBootEnded) 233*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Checking permission"))?; 234*e1997b9aSAndroid Build Coastguard Worker log::info!("In early_boot_ended."); 235*e1997b9aSAndroid Build Coastguard Worker 236*e1997b9aSAndroid Build Coastguard Worker if let Err(e) = 237*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| SuperKeyManager::set_up_boot_level_cache(&SUPER_KEY, &mut db.borrow_mut())) 238*e1997b9aSAndroid Build Coastguard Worker { 239*e1997b9aSAndroid Build Coastguard Worker log::error!("SUPER_KEY.set_up_boot_level_cache failed:\n{:?}\n:(", e); 240*e1997b9aSAndroid Build Coastguard Worker } 241*e1997b9aSAndroid Build Coastguard Worker 242*e1997b9aSAndroid Build Coastguard Worker Maintenance::call_on_all_security_levels("earlyBootEnded", |dev| dev.earlyBootEnded(), None) 243*e1997b9aSAndroid Build Coastguard Worker } 244*e1997b9aSAndroid Build Coastguard Worker migrate_key_namespace(source: &KeyDescriptor, destination: &KeyDescriptor) -> Result<()>245*e1997b9aSAndroid Build Coastguard Worker fn migrate_key_namespace(source: &KeyDescriptor, destination: &KeyDescriptor) -> Result<()> { 246*e1997b9aSAndroid Build Coastguard Worker let calling_uid = ThreadState::get_calling_uid(); 247*e1997b9aSAndroid Build Coastguard Worker 248*e1997b9aSAndroid Build Coastguard Worker match source.domain { 249*e1997b9aSAndroid Build Coastguard Worker Domain::SELINUX | Domain::KEY_ID | Domain::APP => (), 250*e1997b9aSAndroid Build Coastguard Worker _ => { 251*e1997b9aSAndroid Build Coastguard Worker return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)) 252*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Source domain must be one of APP, SELINUX, or KEY_ID.")); 253*e1997b9aSAndroid Build Coastguard Worker } 254*e1997b9aSAndroid Build Coastguard Worker }; 255*e1997b9aSAndroid Build Coastguard Worker 256*e1997b9aSAndroid Build Coastguard Worker match destination.domain { 257*e1997b9aSAndroid Build Coastguard Worker Domain::SELINUX | Domain::APP => (), 258*e1997b9aSAndroid Build Coastguard Worker _ => { 259*e1997b9aSAndroid Build Coastguard Worker return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)) 260*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Destination domain must be one of APP or SELINUX.")); 261*e1997b9aSAndroid Build Coastguard Worker } 262*e1997b9aSAndroid Build Coastguard Worker }; 263*e1997b9aSAndroid Build Coastguard Worker 264*e1997b9aSAndroid Build Coastguard Worker let user_id = uid_to_android_user(calling_uid); 265*e1997b9aSAndroid Build Coastguard Worker 266*e1997b9aSAndroid Build Coastguard Worker let super_key = SUPER_KEY.read().unwrap().get_after_first_unlock_key_by_user_id(user_id); 267*e1997b9aSAndroid Build Coastguard Worker 268*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| { 269*e1997b9aSAndroid Build Coastguard Worker let (key_id_guard, _) = LEGACY_IMPORTER 270*e1997b9aSAndroid Build Coastguard Worker .with_try_import(source, calling_uid, super_key, || { 271*e1997b9aSAndroid Build Coastguard Worker db.borrow_mut().load_key_entry( 272*e1997b9aSAndroid Build Coastguard Worker source, 273*e1997b9aSAndroid Build Coastguard Worker KeyType::Client, 274*e1997b9aSAndroid Build Coastguard Worker KeyEntryLoadBits::NONE, 275*e1997b9aSAndroid Build Coastguard Worker calling_uid, 276*e1997b9aSAndroid Build Coastguard Worker |k, av| { 277*e1997b9aSAndroid Build Coastguard Worker check_key_permission(KeyPerm::Use, k, &av)?; 278*e1997b9aSAndroid Build Coastguard Worker check_key_permission(KeyPerm::Delete, k, &av)?; 279*e1997b9aSAndroid Build Coastguard Worker check_key_permission(KeyPerm::Grant, k, &av) 280*e1997b9aSAndroid Build Coastguard Worker }, 281*e1997b9aSAndroid Build Coastguard Worker ) 282*e1997b9aSAndroid Build Coastguard Worker }) 283*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to load key blob."))?; 284*e1997b9aSAndroid Build Coastguard Worker { 285*e1997b9aSAndroid Build Coastguard Worker db.borrow_mut().migrate_key_namespace(key_id_guard, destination, calling_uid, |k| { 286*e1997b9aSAndroid Build Coastguard Worker check_key_permission(KeyPerm::Rebind, k, &None) 287*e1997b9aSAndroid Build Coastguard Worker }) 288*e1997b9aSAndroid Build Coastguard Worker } 289*e1997b9aSAndroid Build Coastguard Worker }) 290*e1997b9aSAndroid Build Coastguard Worker } 291*e1997b9aSAndroid Build Coastguard Worker delete_all_keys() -> Result<()>292*e1997b9aSAndroid Build Coastguard Worker fn delete_all_keys() -> Result<()> { 293*e1997b9aSAndroid Build Coastguard Worker // Security critical permission check. This statement must return on fail. 294*e1997b9aSAndroid Build Coastguard Worker check_keystore_permission(KeystorePerm::DeleteAllKeys) 295*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Checking permission"))?; 296*e1997b9aSAndroid Build Coastguard Worker log::info!("In delete_all_keys."); 297*e1997b9aSAndroid Build Coastguard Worker 298*e1997b9aSAndroid Build Coastguard Worker Maintenance::call_on_all_security_levels("deleteAllKeys", |dev| dev.deleteAllKeys(), None) 299*e1997b9aSAndroid Build Coastguard Worker } 300*e1997b9aSAndroid Build Coastguard Worker get_app_uids_affected_by_sid( user_id: i32, secure_user_id: i64, ) -> Result<std::vec::Vec<i64>>301*e1997b9aSAndroid Build Coastguard Worker fn get_app_uids_affected_by_sid( 302*e1997b9aSAndroid Build Coastguard Worker user_id: i32, 303*e1997b9aSAndroid Build Coastguard Worker secure_user_id: i64, 304*e1997b9aSAndroid Build Coastguard Worker ) -> Result<std::vec::Vec<i64>> { 305*e1997b9aSAndroid Build Coastguard Worker // This method is intended to be called by Settings and discloses a list of apps 306*e1997b9aSAndroid Build Coastguard Worker // associated with a user, so it requires the "android.permission.MANAGE_USERS" 307*e1997b9aSAndroid Build Coastguard Worker // permission (to avoid leaking list of apps to unauthorized callers). 308*e1997b9aSAndroid Build Coastguard Worker check_get_app_uids_affected_by_sid_permissions().context(ks_err!())?; 309*e1997b9aSAndroid Build Coastguard Worker DB.with(|db| db.borrow_mut().get_app_uids_affected_by_sid(user_id, secure_user_id)) 310*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to get app UIDs affected by SID")) 311*e1997b9aSAndroid Build Coastguard Worker } 312*e1997b9aSAndroid Build Coastguard Worker dump_state(&self, f: &mut dyn std::io::Write) -> std::io::Result<()>313*e1997b9aSAndroid Build Coastguard Worker fn dump_state(&self, f: &mut dyn std::io::Write) -> std::io::Result<()> { 314*e1997b9aSAndroid Build Coastguard Worker writeln!(f, "keystore2 running")?; 315*e1997b9aSAndroid Build Coastguard Worker writeln!(f)?; 316*e1997b9aSAndroid Build Coastguard Worker 317*e1997b9aSAndroid Build Coastguard Worker // Display underlying device information 318*e1997b9aSAndroid Build Coastguard Worker for sec_level in &[SecurityLevel::TRUSTED_ENVIRONMENT, SecurityLevel::STRONGBOX] { 319*e1997b9aSAndroid Build Coastguard Worker let Ok((_dev, hw_info, uuid)) = get_keymint_device(sec_level) else { continue }; 320*e1997b9aSAndroid Build Coastguard Worker 321*e1997b9aSAndroid Build Coastguard Worker writeln!(f, "Device info for {sec_level:?} with {uuid:?}")?; 322*e1997b9aSAndroid Build Coastguard Worker writeln!(f, " HAL version: {}", hw_info.versionNumber)?; 323*e1997b9aSAndroid Build Coastguard Worker writeln!(f, " Implementation name: {}", hw_info.keyMintName)?; 324*e1997b9aSAndroid Build Coastguard Worker writeln!(f, " Implementation author: {}", hw_info.keyMintAuthorName)?; 325*e1997b9aSAndroid Build Coastguard Worker writeln!(f, " Timestamp token required: {}", hw_info.timestampTokenRequired)?; 326*e1997b9aSAndroid Build Coastguard Worker } 327*e1997b9aSAndroid Build Coastguard Worker writeln!(f)?; 328*e1997b9aSAndroid Build Coastguard Worker 329*e1997b9aSAndroid Build Coastguard Worker // Display database size information. 330*e1997b9aSAndroid Build Coastguard Worker match crate::metrics_store::pull_storage_stats() { 331*e1997b9aSAndroid Build Coastguard Worker Ok(atoms) => { 332*e1997b9aSAndroid Build Coastguard Worker writeln!(f, "Database size information (in bytes):")?; 333*e1997b9aSAndroid Build Coastguard Worker for atom in atoms { 334*e1997b9aSAndroid Build Coastguard Worker if let StorageStats(stats) = &atom.payload { 335*e1997b9aSAndroid Build Coastguard Worker let stype = format!("{:?}", stats.storage_type); 336*e1997b9aSAndroid Build Coastguard Worker if stats.unused_size == 0 { 337*e1997b9aSAndroid Build Coastguard Worker writeln!(f, " {:<40}: {:>12}", stype, stats.size)?; 338*e1997b9aSAndroid Build Coastguard Worker } else { 339*e1997b9aSAndroid Build Coastguard Worker writeln!( 340*e1997b9aSAndroid Build Coastguard Worker f, 341*e1997b9aSAndroid Build Coastguard Worker " {:<40}: {:>12} (unused {})", 342*e1997b9aSAndroid Build Coastguard Worker stype, stats.size, stats.unused_size 343*e1997b9aSAndroid Build Coastguard Worker )?; 344*e1997b9aSAndroid Build Coastguard Worker } 345*e1997b9aSAndroid Build Coastguard Worker } 346*e1997b9aSAndroid Build Coastguard Worker } 347*e1997b9aSAndroid Build Coastguard Worker } 348*e1997b9aSAndroid Build Coastguard Worker Err(e) => { 349*e1997b9aSAndroid Build Coastguard Worker writeln!(f, "Failed to retrieve storage stats: {e:?}")?; 350*e1997b9aSAndroid Build Coastguard Worker } 351*e1997b9aSAndroid Build Coastguard Worker } 352*e1997b9aSAndroid Build Coastguard Worker writeln!(f)?; 353*e1997b9aSAndroid Build Coastguard Worker 354*e1997b9aSAndroid Build Coastguard Worker // Display accumulated metrics. 355*e1997b9aSAndroid Build Coastguard Worker writeln!(f, "Metrics information:")?; 356*e1997b9aSAndroid Build Coastguard Worker writeln!(f)?; 357*e1997b9aSAndroid Build Coastguard Worker write!(f, "{:?}", *crate::metrics_store::METRICS_STORE)?; 358*e1997b9aSAndroid Build Coastguard Worker writeln!(f)?; 359*e1997b9aSAndroid Build Coastguard Worker 360*e1997b9aSAndroid Build Coastguard Worker // Reminder: any additional information added to the `dump_state()` output needs to be 361*e1997b9aSAndroid Build Coastguard Worker // careful not to include confidential information (e.g. key material). 362*e1997b9aSAndroid Build Coastguard Worker 363*e1997b9aSAndroid Build Coastguard Worker Ok(()) 364*e1997b9aSAndroid Build Coastguard Worker } 365*e1997b9aSAndroid Build Coastguard Worker 366*e1997b9aSAndroid Build Coastguard Worker #[allow(dead_code)] set_module_info(module_info: Vec<ModuleInfo>) -> Result<()>367*e1997b9aSAndroid Build Coastguard Worker fn set_module_info(module_info: Vec<ModuleInfo>) -> Result<()> { 368*e1997b9aSAndroid Build Coastguard Worker let encoding = Self::encode_module_info(module_info) 369*e1997b9aSAndroid Build Coastguard Worker .map_err(|e| anyhow!({ e })) 370*e1997b9aSAndroid Build Coastguard Worker .context(ks_err!("Failed to encode module_info"))?; 371*e1997b9aSAndroid Build Coastguard Worker let hash = digest::Sha256::hash(&encoding).to_vec(); 372*e1997b9aSAndroid Build Coastguard Worker 373*e1997b9aSAndroid Build Coastguard Worker { 374*e1997b9aSAndroid Build Coastguard Worker let mut saved = ENCODED_MODULE_INFO.write().unwrap(); 375*e1997b9aSAndroid Build Coastguard Worker if let Some(saved_encoding) = &*saved { 376*e1997b9aSAndroid Build Coastguard Worker if *saved_encoding == encoding { 377*e1997b9aSAndroid Build Coastguard Worker log::warn!( 378*e1997b9aSAndroid Build Coastguard Worker "Module info already set, ignoring repeated attempt to set same info." 379*e1997b9aSAndroid Build Coastguard Worker ); 380*e1997b9aSAndroid Build Coastguard Worker return Ok(()); 381*e1997b9aSAndroid Build Coastguard Worker } 382*e1997b9aSAndroid Build Coastguard Worker return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(ks_err!( 383*e1997b9aSAndroid Build Coastguard Worker "Failed to set module info as it is already set to a different value." 384*e1997b9aSAndroid Build Coastguard Worker )); 385*e1997b9aSAndroid Build Coastguard Worker } 386*e1997b9aSAndroid Build Coastguard Worker *saved = Some(encoding); 387*e1997b9aSAndroid Build Coastguard Worker } 388*e1997b9aSAndroid Build Coastguard Worker 389*e1997b9aSAndroid Build Coastguard Worker let kps = 390*e1997b9aSAndroid Build Coastguard Worker vec![KeyParameter { tag: Tag::MODULE_HASH, value: KeyParameterValue::Blob(hash) }]; 391*e1997b9aSAndroid Build Coastguard Worker 392*e1997b9aSAndroid Build Coastguard Worker Maintenance::call_on_all_security_levels( 393*e1997b9aSAndroid Build Coastguard Worker "setAdditionalAttestationInfo", 394*e1997b9aSAndroid Build Coastguard Worker |dev| dev.setAdditionalAttestationInfo(&kps), 395*e1997b9aSAndroid Build Coastguard Worker Some(KEYMINT_V4), 396*e1997b9aSAndroid Build Coastguard Worker ) 397*e1997b9aSAndroid Build Coastguard Worker } 398*e1997b9aSAndroid Build Coastguard Worker 399*e1997b9aSAndroid Build Coastguard Worker #[allow(dead_code)] encode_module_info(module_info: Vec<ModuleInfo>) -> Result<Vec<u8>, der::Error>400*e1997b9aSAndroid Build Coastguard Worker fn encode_module_info(module_info: Vec<ModuleInfo>) -> Result<Vec<u8>, der::Error> { 401*e1997b9aSAndroid Build Coastguard Worker SetOfVec::<ModuleInfo>::from_iter(module_info.into_iter())?.to_der() 402*e1997b9aSAndroid Build Coastguard Worker } 403*e1997b9aSAndroid Build Coastguard Worker } 404*e1997b9aSAndroid Build Coastguard Worker 405*e1997b9aSAndroid Build Coastguard Worker impl Interface for Maintenance { dump( &self, f: &mut dyn std::io::Write, _args: &[&std::ffi::CStr], ) -> Result<(), binder::StatusCode>406*e1997b9aSAndroid Build Coastguard Worker fn dump( 407*e1997b9aSAndroid Build Coastguard Worker &self, 408*e1997b9aSAndroid Build Coastguard Worker f: &mut dyn std::io::Write, 409*e1997b9aSAndroid Build Coastguard Worker _args: &[&std::ffi::CStr], 410*e1997b9aSAndroid Build Coastguard Worker ) -> Result<(), binder::StatusCode> { 411*e1997b9aSAndroid Build Coastguard Worker if !keystore2_flags::enable_dump() { 412*e1997b9aSAndroid Build Coastguard Worker log::info!("skipping dump() as flag not enabled"); 413*e1997b9aSAndroid Build Coastguard Worker return Ok(()); 414*e1997b9aSAndroid Build Coastguard Worker } 415*e1997b9aSAndroid Build Coastguard Worker log::info!("dump()"); 416*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::dump"); 417*e1997b9aSAndroid Build Coastguard Worker check_dump_permission().map_err(|_e| { 418*e1997b9aSAndroid Build Coastguard Worker log::error!("dump permission denied"); 419*e1997b9aSAndroid Build Coastguard Worker binder::StatusCode::PERMISSION_DENIED 420*e1997b9aSAndroid Build Coastguard Worker })?; 421*e1997b9aSAndroid Build Coastguard Worker 422*e1997b9aSAndroid Build Coastguard Worker self.dump_state(f).map_err(|e| { 423*e1997b9aSAndroid Build Coastguard Worker log::error!("dump_state failed: {e:?}"); 424*e1997b9aSAndroid Build Coastguard Worker binder::StatusCode::UNKNOWN_ERROR 425*e1997b9aSAndroid Build Coastguard Worker }) 426*e1997b9aSAndroid Build Coastguard Worker } 427*e1997b9aSAndroid Build Coastguard Worker } 428*e1997b9aSAndroid Build Coastguard Worker 429*e1997b9aSAndroid Build Coastguard Worker impl IKeystoreMaintenance for Maintenance { onUserAdded(&self, user_id: i32) -> BinderResult<()>430*e1997b9aSAndroid Build Coastguard Worker fn onUserAdded(&self, user_id: i32) -> BinderResult<()> { 431*e1997b9aSAndroid Build Coastguard Worker log::info!("onUserAdded(user={user_id})"); 432*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::onUserAdded"); 433*e1997b9aSAndroid Build Coastguard Worker self.add_or_remove_user(user_id).map_err(into_logged_binder) 434*e1997b9aSAndroid Build Coastguard Worker } 435*e1997b9aSAndroid Build Coastguard Worker initUserSuperKeys( &self, user_id: i32, password: &[u8], allow_existing: bool, ) -> BinderResult<()>436*e1997b9aSAndroid Build Coastguard Worker fn initUserSuperKeys( 437*e1997b9aSAndroid Build Coastguard Worker &self, 438*e1997b9aSAndroid Build Coastguard Worker user_id: i32, 439*e1997b9aSAndroid Build Coastguard Worker password: &[u8], 440*e1997b9aSAndroid Build Coastguard Worker allow_existing: bool, 441*e1997b9aSAndroid Build Coastguard Worker ) -> BinderResult<()> { 442*e1997b9aSAndroid Build Coastguard Worker log::info!("initUserSuperKeys(user={user_id}, allow_existing={allow_existing})"); 443*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::initUserSuperKeys"); 444*e1997b9aSAndroid Build Coastguard Worker self.init_user_super_keys(user_id, password.into(), allow_existing) 445*e1997b9aSAndroid Build Coastguard Worker .map_err(into_logged_binder) 446*e1997b9aSAndroid Build Coastguard Worker } 447*e1997b9aSAndroid Build Coastguard Worker onUserRemoved(&self, user_id: i32) -> BinderResult<()>448*e1997b9aSAndroid Build Coastguard Worker fn onUserRemoved(&self, user_id: i32) -> BinderResult<()> { 449*e1997b9aSAndroid Build Coastguard Worker log::info!("onUserRemoved(user={user_id})"); 450*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::onUserRemoved"); 451*e1997b9aSAndroid Build Coastguard Worker self.add_or_remove_user(user_id).map_err(into_logged_binder) 452*e1997b9aSAndroid Build Coastguard Worker } 453*e1997b9aSAndroid Build Coastguard Worker onUserLskfRemoved(&self, user_id: i32) -> BinderResult<()>454*e1997b9aSAndroid Build Coastguard Worker fn onUserLskfRemoved(&self, user_id: i32) -> BinderResult<()> { 455*e1997b9aSAndroid Build Coastguard Worker log::info!("onUserLskfRemoved(user={user_id})"); 456*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::onUserLskfRemoved"); 457*e1997b9aSAndroid Build Coastguard Worker Self::on_user_lskf_removed(user_id).map_err(into_logged_binder) 458*e1997b9aSAndroid Build Coastguard Worker } 459*e1997b9aSAndroid Build Coastguard Worker clearNamespace(&self, domain: Domain, nspace: i64) -> BinderResult<()>460*e1997b9aSAndroid Build Coastguard Worker fn clearNamespace(&self, domain: Domain, nspace: i64) -> BinderResult<()> { 461*e1997b9aSAndroid Build Coastguard Worker log::info!("clearNamespace({domain:?}, nspace={nspace})"); 462*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::clearNamespace"); 463*e1997b9aSAndroid Build Coastguard Worker self.clear_namespace(domain, nspace).map_err(into_logged_binder) 464*e1997b9aSAndroid Build Coastguard Worker } 465*e1997b9aSAndroid Build Coastguard Worker earlyBootEnded(&self) -> BinderResult<()>466*e1997b9aSAndroid Build Coastguard Worker fn earlyBootEnded(&self) -> BinderResult<()> { 467*e1997b9aSAndroid Build Coastguard Worker log::info!("earlyBootEnded()"); 468*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::earlyBootEnded"); 469*e1997b9aSAndroid Build Coastguard Worker Self::early_boot_ended().map_err(into_logged_binder) 470*e1997b9aSAndroid Build Coastguard Worker } 471*e1997b9aSAndroid Build Coastguard Worker migrateKeyNamespace( &self, source: &KeyDescriptor, destination: &KeyDescriptor, ) -> BinderResult<()>472*e1997b9aSAndroid Build Coastguard Worker fn migrateKeyNamespace( 473*e1997b9aSAndroid Build Coastguard Worker &self, 474*e1997b9aSAndroid Build Coastguard Worker source: &KeyDescriptor, 475*e1997b9aSAndroid Build Coastguard Worker destination: &KeyDescriptor, 476*e1997b9aSAndroid Build Coastguard Worker ) -> BinderResult<()> { 477*e1997b9aSAndroid Build Coastguard Worker log::info!("migrateKeyNamespace(src={source:?}, dest={destination:?})"); 478*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::migrateKeyNamespace"); 479*e1997b9aSAndroid Build Coastguard Worker Self::migrate_key_namespace(source, destination).map_err(into_logged_binder) 480*e1997b9aSAndroid Build Coastguard Worker } 481*e1997b9aSAndroid Build Coastguard Worker deleteAllKeys(&self) -> BinderResult<()>482*e1997b9aSAndroid Build Coastguard Worker fn deleteAllKeys(&self) -> BinderResult<()> { 483*e1997b9aSAndroid Build Coastguard Worker log::warn!("deleteAllKeys() invoked, indicating initial setup or post-factory reset"); 484*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::deleteAllKeys"); 485*e1997b9aSAndroid Build Coastguard Worker Self::delete_all_keys().map_err(into_logged_binder) 486*e1997b9aSAndroid Build Coastguard Worker } 487*e1997b9aSAndroid Build Coastguard Worker getAppUidsAffectedBySid( &self, user_id: i32, secure_user_id: i64, ) -> BinderResult<std::vec::Vec<i64>>488*e1997b9aSAndroid Build Coastguard Worker fn getAppUidsAffectedBySid( 489*e1997b9aSAndroid Build Coastguard Worker &self, 490*e1997b9aSAndroid Build Coastguard Worker user_id: i32, 491*e1997b9aSAndroid Build Coastguard Worker secure_user_id: i64, 492*e1997b9aSAndroid Build Coastguard Worker ) -> BinderResult<std::vec::Vec<i64>> { 493*e1997b9aSAndroid Build Coastguard Worker log::info!("getAppUidsAffectedBySid(secure_user_id={secure_user_id:?})"); 494*e1997b9aSAndroid Build Coastguard Worker let _wp = wd::watch("IKeystoreMaintenance::getAppUidsAffectedBySid"); 495*e1997b9aSAndroid Build Coastguard Worker Self::get_app_uids_affected_by_sid(user_id, secure_user_id).map_err(into_logged_binder) 496*e1997b9aSAndroid Build Coastguard Worker } 497*e1997b9aSAndroid Build Coastguard Worker } 498