1 // Copyright 2021, 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 implements IKeystoreMaintenance AIDL interface. 16 17 use crate::database::{KeyEntryLoadBits, KeyType}; 18 use crate::error::into_logged_binder; 19 use crate::error::map_km_error; 20 use crate::error::Error; 21 use crate::globals::get_keymint_device; 22 use crate::globals::{DB, ENCODED_MODULE_INFO, LEGACY_IMPORTER, SUPER_KEY}; 23 use crate::ks_err; 24 use crate::permission::{KeyPerm, KeystorePerm}; 25 use crate::super_key::SuperKeyManager; 26 use crate::utils::{ 27 check_dump_permission, check_get_app_uids_affected_by_sid_permissions, check_key_permission, 28 check_keystore_permission, uid_to_android_user, watchdog as wd, 29 }; 30 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{ 31 ErrorCode::ErrorCode, IKeyMintDevice::IKeyMintDevice, KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, Tag::Tag, 32 }; 33 use apex_aidl_interface::aidl::android::apex::{ 34 IApexService::IApexService, 35 }; 36 use android_security_maintenance::aidl::android::security::maintenance::IKeystoreMaintenance::{ 37 BnKeystoreMaintenance, IKeystoreMaintenance, 38 }; 39 use android_security_maintenance::binder::{ 40 BinderFeatures, Interface, Result as BinderResult, Strong, ThreadState, 41 }; 42 use android_security_metrics::aidl::android::security::metrics::{ 43 KeystoreAtomPayload::KeystoreAtomPayload::StorageStats 44 }; 45 use android_system_keystore2::aidl::android::system::keystore2::KeyDescriptor::KeyDescriptor; 46 use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode; 47 use anyhow::{anyhow, Context, Result}; 48 use binder::wait_for_interface; 49 use bssl_crypto::digest; 50 use der::{DerOrd, Encode, asn1::OctetString, asn1::SetOfVec, Sequence}; 51 use keystore2_crypto::Password; 52 use rustutils::system_properties::PropertyWatcher; 53 use std::cmp::Ordering; 54 55 /// Reexport Domain for the benefit of DeleteListener 56 pub use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain; 57 58 #[cfg(test)] 59 mod tests; 60 61 /// Version number of KeyMint V4. 62 pub const KEYMINT_V4: i32 = 400; 63 64 /// Module information structure for DER-encoding. 65 #[derive(Sequence, Debug, PartialEq, Eq)] 66 struct ModuleInfo { 67 name: OctetString, 68 version: i64, 69 } 70 71 impl DerOrd for ModuleInfo { 72 // DER mandates "encodings of the component values of a set-of value shall appear in ascending 73 // order". `der_cmp` serves as a proxy for determining that ordering (though why the `der` crate 74 // requires this is unclear). Essentially, we just need to compare the `name` lengths, and then 75 // if those are equal, the `name`s themselves. (No need to consider `version`s since there can't 76 // be more than one `ModuleInfo` with the same `name` in the set-of `ModuleInfo`s.) We rely on 77 // `OctetString`'s `der_cmp` to do the aforementioned comparison. der_cmp(&self, other: &Self) -> std::result::Result<Ordering, der::Error>78 fn der_cmp(&self, other: &Self) -> std::result::Result<Ordering, der::Error> { 79 self.name.der_cmp(&other.name) 80 } 81 } 82 83 /// The Maintenance module takes a delete listener argument which observes user and namespace 84 /// deletion events. 85 pub trait DeleteListener { 86 /// Called by the maintenance module when an app/namespace is deleted. delete_namespace(&self, domain: Domain, namespace: i64) -> Result<()>87 fn delete_namespace(&self, domain: Domain, namespace: i64) -> Result<()>; 88 /// Called by the maintenance module when a user is deleted. delete_user(&self, user_id: u32) -> Result<()>89 fn delete_user(&self, user_id: u32) -> Result<()>; 90 } 91 92 /// This struct is defined to implement the aforementioned AIDL interface. 93 pub struct Maintenance { 94 delete_listener: Box<dyn DeleteListener + Send + Sync + 'static>, 95 } 96 97 impl Maintenance { 98 /// Create a new instance of Keystore Maintenance service. new_native_binder( delete_listener: Box<dyn DeleteListener + Send + Sync + 'static>, ) -> Result<Strong<dyn IKeystoreMaintenance>>99 pub fn new_native_binder( 100 delete_listener: Box<dyn DeleteListener + Send + Sync + 'static>, 101 ) -> Result<Strong<dyn IKeystoreMaintenance>> { 102 Ok(BnKeystoreMaintenance::new_binder( 103 Self { delete_listener }, 104 BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() }, 105 )) 106 } 107 add_or_remove_user(&self, user_id: i32) -> Result<()>108 fn add_or_remove_user(&self, user_id: i32) -> Result<()> { 109 // Check permission. Function should return if this failed. Therefore having '?' at the end 110 // is very important. 111 check_keystore_permission(KeystorePerm::ChangeUser).context(ks_err!())?; 112 113 DB.with(|db| { 114 SUPER_KEY.write().unwrap().remove_user( 115 &mut db.borrow_mut(), 116 &LEGACY_IMPORTER, 117 user_id as u32, 118 ) 119 }) 120 .context(ks_err!("Trying to delete keys from db."))?; 121 self.delete_listener 122 .delete_user(user_id as u32) 123 .context(ks_err!("While invoking the delete listener.")) 124 } 125 init_user_super_keys( &self, user_id: i32, password: Password, allow_existing: bool, ) -> Result<()>126 fn init_user_super_keys( 127 &self, 128 user_id: i32, 129 password: Password, 130 allow_existing: bool, 131 ) -> Result<()> { 132 // Permission check. Must return on error. Do not touch the '?'. 133 check_keystore_permission(KeystorePerm::ChangeUser).context(ks_err!())?; 134 135 let mut skm = SUPER_KEY.write().unwrap(); 136 DB.with(|db| { 137 skm.initialize_user( 138 &mut db.borrow_mut(), 139 &LEGACY_IMPORTER, 140 user_id as u32, 141 &password, 142 allow_existing, 143 ) 144 }) 145 .context(ks_err!("Failed to initialize user super keys")) 146 } 147 148 // Deletes all auth-bound keys when the user's LSKF is removed. on_user_lskf_removed(user_id: i32) -> Result<()>149 fn on_user_lskf_removed(user_id: i32) -> Result<()> { 150 // Permission check. Must return on error. Do not touch the '?'. 151 check_keystore_permission(KeystorePerm::ChangePassword).context(ks_err!())?; 152 153 LEGACY_IMPORTER 154 .bulk_delete_user(user_id as u32, true) 155 .context(ks_err!("Failed to delete legacy keys."))?; 156 157 DB.with(|db| db.borrow_mut().unbind_auth_bound_keys_for_user(user_id as u32)) 158 .context(ks_err!("Failed to delete auth-bound keys.")) 159 } 160 clear_namespace(&self, domain: Domain, nspace: i64) -> Result<()>161 fn clear_namespace(&self, domain: Domain, nspace: i64) -> Result<()> { 162 // Permission check. Must return on error. Do not touch the '?'. 163 check_keystore_permission(KeystorePerm::ClearUID).context("In clear_namespace.")?; 164 165 LEGACY_IMPORTER 166 .bulk_delete_uid(domain, nspace) 167 .context(ks_err!("Trying to delete legacy keys."))?; 168 DB.with(|db| db.borrow_mut().unbind_keys_for_namespace(domain, nspace)) 169 .context(ks_err!("Trying to delete keys from db."))?; 170 self.delete_listener 171 .delete_namespace(domain, nspace) 172 .context(ks_err!("While invoking the delete listener.")) 173 } 174 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<()>,175 fn call_with_watchdog<F>( 176 sec_level: SecurityLevel, 177 name: &'static str, 178 op: &F, 179 min_version: Option<i32>, 180 ) -> Result<()> 181 where 182 F: Fn(Strong<dyn IKeyMintDevice>) -> binder::Result<()>, 183 { 184 let (km_dev, hw_info, _) = 185 get_keymint_device(&sec_level).context(ks_err!("getting keymint device"))?; 186 187 if let Some(min_version) = min_version { 188 if hw_info.versionNumber < min_version { 189 log::info!("skipping {name} for {sec_level:?} since its keymint version {} is less than the minimum required version {min_version}", hw_info.versionNumber); 190 return Ok(()); 191 } 192 } 193 194 let _wp = wd::watch_millis_with("Maintenance::call_with_watchdog", 500, (sec_level, name)); 195 map_km_error(op(km_dev)).with_context(|| ks_err!("calling {}", name))?; 196 Ok(()) 197 } 198 call_on_all_security_levels<F>( name: &'static str, op: F, min_version: Option<i32>, ) -> Result<()> where F: Fn(Strong<dyn IKeyMintDevice>) -> binder::Result<()>,199 fn call_on_all_security_levels<F>( 200 name: &'static str, 201 op: F, 202 min_version: Option<i32>, 203 ) -> Result<()> 204 where 205 F: Fn(Strong<dyn IKeyMintDevice>) -> binder::Result<()>, 206 { 207 let sec_levels = [ 208 (SecurityLevel::TRUSTED_ENVIRONMENT, "TRUSTED_ENVIRONMENT"), 209 (SecurityLevel::STRONGBOX, "STRONGBOX"), 210 ]; 211 sec_levels.iter().try_fold((), |_result, (sec_level, sec_level_string)| { 212 let curr_result = Maintenance::call_with_watchdog(*sec_level, name, &op, min_version); 213 match curr_result { 214 Ok(()) => log::info!( 215 "Call to {} succeeded for security level {}.", 216 name, 217 &sec_level_string 218 ), 219 Err(ref e) => { 220 if *sec_level == SecurityLevel::STRONGBOX 221 && e.downcast_ref::<Error>() 222 == Some(&Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)) 223 { 224 log::info!("Call to {} failed for StrongBox as it is not available", name); 225 return Ok(()); 226 } else { 227 log::error!( 228 "Call to {} failed for security level {}: {}.", 229 name, 230 &sec_level_string, 231 e 232 ) 233 } 234 } 235 } 236 curr_result 237 }) 238 } 239 early_boot_ended() -> Result<()>240 fn early_boot_ended() -> Result<()> { 241 check_keystore_permission(KeystorePerm::EarlyBootEnded) 242 .context(ks_err!("Checking permission"))?; 243 log::info!("In early_boot_ended."); 244 245 if let Err(e) = 246 DB.with(|db| SuperKeyManager::set_up_boot_level_cache(&SUPER_KEY, &mut db.borrow_mut())) 247 { 248 log::error!("SUPER_KEY.set_up_boot_level_cache failed:\n{:?}\n:(", e); 249 } 250 Maintenance::call_on_all_security_levels("earlyBootEnded", |dev| dev.earlyBootEnded(), None) 251 } 252 253 /// Spawns a thread to send module info if it hasn't already been sent. The thread first waits 254 /// for the apex info to be available. 255 /// (Module info would have already been sent in the case of a Keystore restart.) 256 /// 257 /// # Panics 258 /// 259 /// This method, and methods it calls, panic on failure, because a failure to populate module 260 /// information will block the boot process from completing. In this method, this happens if: 261 /// - the `apexd.status` property is unable to be monitored 262 /// - the `keystore.module_hash.sent` property cannot be updated check_send_module_info()263 pub fn check_send_module_info() { 264 if rustutils::system_properties::read_bool("keystore.module_hash.sent", false) 265 .unwrap_or(false) 266 { 267 log::info!("Module info has already been sent."); 268 return; 269 } 270 if keystore2_flags::attest_modules() { 271 std::thread::spawn(move || { 272 // Wait for apex info to be available before populating. 273 Self::watch_apex_info().unwrap_or_else(|e| { 274 log::error!("failed to monitor apexd.status property: {e:?}"); 275 panic!("Terminating due to inaccessibility of apexd.status property, blocking boot: {e:?}"); 276 }); 277 }); 278 } else { 279 rustutils::system_properties::write("keystore.module_hash.sent", "true") 280 .unwrap_or_else(|e| { 281 log::error!("Failed to set keystore.module_hash.sent to true; this will therefore block boot: {e:?}"); 282 panic!("Crashing Keystore because it failed to set keystore.module_hash.sent to true (which blocks boot)."); 283 } 284 ); 285 } 286 } 287 288 /// Watch the `apexd.status` system property, and read apex module information once 289 /// it is `activated`. 290 /// 291 /// Blocks waiting for system property changes, so must be run in its own thread. watch_apex_info() -> Result<()>292 fn watch_apex_info() -> Result<()> { 293 let apex_prop = "apexd.status"; 294 log::info!("start monitoring '{apex_prop}' property"); 295 let mut w = 296 PropertyWatcher::new(apex_prop).context(ks_err!("PropertyWatcher::new failed"))?; 297 loop { 298 let value = w.read(|_name, value| Ok(value.to_string())); 299 log::info!("property '{apex_prop}' is now '{value:?}'"); 300 if matches!(value.as_deref(), Ok("activated")) { 301 Self::read_and_set_module_info(); 302 return Ok(()); 303 } 304 log::info!("await a change to '{apex_prop}'..."); 305 w.wait(None).context(ks_err!("property wait failed"))?; 306 log::info!("await a change to '{apex_prop}'...notified"); 307 } 308 } 309 310 /// Read apex information (which is assumed to be present) and propagate module 311 /// information to KeyMint instances. 312 /// 313 /// # Panics 314 /// 315 /// This method panics on failure, because a failure to populate module information 316 /// will block the boot process from completing. This happens if: 317 /// - apex information is not available (precondition) 318 /// - KeyMint instances fail to accept module information 319 /// - the `keystore.module_hash.sent` property cannot be updated read_and_set_module_info()320 fn read_and_set_module_info() { 321 let modules = Self::read_apex_info().unwrap_or_else(|e| { 322 log::error!("failed to read apex info: {e:?}"); 323 panic!("Terminating due to unavailability of apex info, blocking boot: {e:?}"); 324 }); 325 Self::set_module_info(modules).unwrap_or_else(|e| { 326 log::error!("failed to set module info: {e:?}"); 327 panic!("Terminating due to KeyMint not accepting module info, blocking boot: {e:?}"); 328 }); 329 rustutils::system_properties::write("keystore.module_hash.sent", "true").unwrap_or_else(|e| { 330 log::error!("failed to set keystore.module_hash.sent property: {e:?}"); 331 panic!("Terminating due to failure to set keystore.module_hash.sent property, blocking boot: {e:?}"); 332 }); 333 } 334 read_apex_info() -> Result<Vec<ModuleInfo>>335 fn read_apex_info() -> Result<Vec<ModuleInfo>> { 336 let _wp = wd::watch("read_apex_info via IApexService.getActivePackages()"); 337 let apexd: Strong<dyn IApexService> = 338 wait_for_interface("apexservice").context("failed to AIDL connect to apexd")?; 339 let packages = apexd.getActivePackages().context("failed to retrieve active packages")?; 340 packages 341 .into_iter() 342 .map(|pkg| { 343 log::info!("apex modules += {} version {}", pkg.moduleName, pkg.versionCode); 344 let name = OctetString::new(pkg.moduleName.as_bytes()).map_err(|e| { 345 anyhow!("failed to convert '{}' to OCTET_STRING: {e:?}", pkg.moduleName) 346 })?; 347 Ok(ModuleInfo { name, version: pkg.versionCode }) 348 }) 349 .collect() 350 } 351 migrate_key_namespace(source: &KeyDescriptor, destination: &KeyDescriptor) -> Result<()>352 fn migrate_key_namespace(source: &KeyDescriptor, destination: &KeyDescriptor) -> Result<()> { 353 let calling_uid = ThreadState::get_calling_uid(); 354 355 match source.domain { 356 Domain::SELINUX | Domain::KEY_ID | Domain::APP => (), 357 _ => { 358 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)) 359 .context(ks_err!("Source domain must be one of APP, SELINUX, or KEY_ID.")); 360 } 361 }; 362 363 match destination.domain { 364 Domain::SELINUX | Domain::APP => (), 365 _ => { 366 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)) 367 .context(ks_err!("Destination domain must be one of APP or SELINUX.")); 368 } 369 }; 370 371 let user_id = uid_to_android_user(calling_uid); 372 373 let super_key = SUPER_KEY.read().unwrap().get_after_first_unlock_key_by_user_id(user_id); 374 375 DB.with(|db| { 376 let (key_id_guard, _) = LEGACY_IMPORTER 377 .with_try_import(source, calling_uid, super_key, || { 378 db.borrow_mut().load_key_entry( 379 source, 380 KeyType::Client, 381 KeyEntryLoadBits::NONE, 382 calling_uid, 383 |k, av| { 384 check_key_permission(KeyPerm::Use, k, &av)?; 385 check_key_permission(KeyPerm::Delete, k, &av)?; 386 check_key_permission(KeyPerm::Grant, k, &av) 387 }, 388 ) 389 }) 390 .context(ks_err!("Failed to load key blob."))?; 391 { 392 db.borrow_mut().migrate_key_namespace(key_id_guard, destination, calling_uid, |k| { 393 check_key_permission(KeyPerm::Rebind, k, &None) 394 }) 395 } 396 }) 397 } 398 delete_all_keys() -> Result<()>399 fn delete_all_keys() -> Result<()> { 400 // Security critical permission check. This statement must return on fail. 401 check_keystore_permission(KeystorePerm::DeleteAllKeys) 402 .context(ks_err!("Checking permission"))?; 403 log::info!("In delete_all_keys."); 404 405 Maintenance::call_on_all_security_levels("deleteAllKeys", |dev| dev.deleteAllKeys(), None) 406 } 407 get_app_uids_affected_by_sid( user_id: i32, secure_user_id: i64, ) -> Result<std::vec::Vec<i64>>408 fn get_app_uids_affected_by_sid( 409 user_id: i32, 410 secure_user_id: i64, 411 ) -> Result<std::vec::Vec<i64>> { 412 // This method is intended to be called by Settings and discloses a list of apps 413 // associated with a user, so it requires the "android.permission.MANAGE_USERS" 414 // permission (to avoid leaking list of apps to unauthorized callers). 415 check_get_app_uids_affected_by_sid_permissions().context(ks_err!())?; 416 DB.with(|db| db.borrow_mut().get_app_uids_affected_by_sid(user_id, secure_user_id)) 417 .context(ks_err!("Failed to get app UIDs affected by SID")) 418 } 419 dump_state(&self, f: &mut dyn std::io::Write) -> std::io::Result<()>420 fn dump_state(&self, f: &mut dyn std::io::Write) -> std::io::Result<()> { 421 writeln!(f, "keystore2 running")?; 422 writeln!(f)?; 423 424 // Display underlying device information. 425 // 426 // Note that this chunk of output is parsed in a GTS test, so do not change the format 427 // without checking that the test still works. 428 for sec_level in &[SecurityLevel::TRUSTED_ENVIRONMENT, SecurityLevel::STRONGBOX] { 429 let Ok((_dev, hw_info, uuid)) = get_keymint_device(sec_level) else { continue }; 430 431 writeln!(f, "Device info for {sec_level:?} with {uuid:?}")?; 432 writeln!(f, " HAL version: {}", hw_info.versionNumber)?; 433 writeln!(f, " Implementation name: {}", hw_info.keyMintName)?; 434 writeln!(f, " Implementation author: {}", hw_info.keyMintAuthorName)?; 435 writeln!(f, " Timestamp token required: {}", hw_info.timestampTokenRequired)?; 436 } 437 writeln!(f)?; 438 439 // Display module attestation information 440 { 441 let info = ENCODED_MODULE_INFO.read().unwrap(); 442 if let Some(info) = info.as_ref() { 443 writeln!(f, "Attested module information (DER-encoded):")?; 444 writeln!(f, " {}", hex::encode(info))?; 445 writeln!(f)?; 446 } else { 447 writeln!(f, "Attested module information not set")?; 448 writeln!(f)?; 449 } 450 } 451 452 // Display database size information. 453 match crate::metrics_store::pull_storage_stats() { 454 Ok(atoms) => { 455 writeln!(f, "Database size information (in bytes):")?; 456 for atom in atoms { 457 if let StorageStats(stats) = &atom.payload { 458 let stype = format!("{:?}", stats.storage_type); 459 if stats.unused_size == 0 { 460 writeln!(f, " {:<40}: {:>12}", stype, stats.size)?; 461 } else { 462 writeln!( 463 f, 464 " {:<40}: {:>12} (unused {})", 465 stype, stats.size, stats.unused_size 466 )?; 467 } 468 } 469 } 470 } 471 Err(e) => { 472 writeln!(f, "Failed to retrieve storage stats: {e:?}")?; 473 } 474 } 475 writeln!(f)?; 476 477 // Display database config information. 478 writeln!(f, "Database configuration:")?; 479 DB.with(|db| -> std::io::Result<()> { 480 let pragma_str = |f: &mut dyn std::io::Write, name| -> std::io::Result<()> { 481 let mut db = db.borrow_mut(); 482 let value: String = db 483 .pragma(name) 484 .unwrap_or_else(|e| format!("unknown value for '{name}', failed: {e:?}")); 485 writeln!(f, " {name} = {value}") 486 }; 487 let pragma_i32 = |f: &mut dyn std::io::Write, name| -> std::io::Result<()> { 488 let mut db = db.borrow_mut(); 489 let value: i32 = db.pragma(name).unwrap_or_else(|e| { 490 log::error!("unknown value for '{name}', failed: {e:?}"); 491 -1 492 }); 493 writeln!(f, " {name} = {value}") 494 }; 495 pragma_i32(f, "auto_vacuum")?; 496 pragma_str(f, "journal_mode")?; 497 pragma_i32(f, "journal_size_limit")?; 498 pragma_i32(f, "synchronous")?; 499 pragma_i32(f, "schema_version")?; 500 pragma_i32(f, "user_version")?; 501 Ok(()) 502 })?; 503 writeln!(f)?; 504 505 // Display accumulated metrics. 506 writeln!(f, "Metrics information:")?; 507 writeln!(f)?; 508 write!(f, "{:?}", *crate::metrics_store::METRICS_STORE)?; 509 writeln!(f)?; 510 511 // Reminder: any additional information added to the `dump_state()` output needs to be 512 // careful not to include confidential information (e.g. key material). 513 514 Ok(()) 515 } 516 set_module_info(module_info: Vec<ModuleInfo>) -> Result<()>517 fn set_module_info(module_info: Vec<ModuleInfo>) -> Result<()> { 518 log::info!("set_module_info with {} modules", module_info.len()); 519 let encoding = Self::encode_module_info(module_info) 520 .map_err(|e| anyhow!({ e })) 521 .context(ks_err!("Failed to encode module_info"))?; 522 let hash = digest::Sha256::hash(&encoding).to_vec(); 523 524 { 525 let mut saved = ENCODED_MODULE_INFO.write().unwrap(); 526 if let Some(saved_encoding) = &*saved { 527 if *saved_encoding == encoding { 528 log::warn!( 529 "Module info already set, ignoring repeated attempt to set same info." 530 ); 531 return Ok(()); 532 } 533 return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(ks_err!( 534 "Failed to set module info as it is already set to a different value." 535 )); 536 } 537 *saved = Some(encoding); 538 } 539 540 let kps = 541 vec![KeyParameter { tag: Tag::MODULE_HASH, value: KeyParameterValue::Blob(hash) }]; 542 543 Maintenance::call_on_all_security_levels( 544 "setAdditionalAttestationInfo", 545 |dev| dev.setAdditionalAttestationInfo(&kps), 546 Some(KEYMINT_V4), 547 ) 548 } 549 encode_module_info(module_info: Vec<ModuleInfo>) -> Result<Vec<u8>, der::Error>550 fn encode_module_info(module_info: Vec<ModuleInfo>) -> Result<Vec<u8>, der::Error> { 551 SetOfVec::<ModuleInfo>::from_iter(module_info.into_iter())?.to_der() 552 } 553 } 554 555 impl Interface for Maintenance { dump( &self, f: &mut dyn std::io::Write, _args: &[&std::ffi::CStr], ) -> Result<(), binder::StatusCode>556 fn dump( 557 &self, 558 f: &mut dyn std::io::Write, 559 _args: &[&std::ffi::CStr], 560 ) -> Result<(), binder::StatusCode> { 561 log::info!("dump()"); 562 let _wp = wd::watch("IKeystoreMaintenance::dump"); 563 check_dump_permission().map_err(|_e| { 564 log::error!("dump permission denied"); 565 binder::StatusCode::PERMISSION_DENIED 566 })?; 567 568 self.dump_state(f).map_err(|e| { 569 log::error!("dump_state failed: {e:?}"); 570 binder::StatusCode::UNKNOWN_ERROR 571 }) 572 } 573 } 574 575 impl IKeystoreMaintenance for Maintenance { onUserAdded(&self, user_id: i32) -> BinderResult<()>576 fn onUserAdded(&self, user_id: i32) -> BinderResult<()> { 577 log::info!("onUserAdded(user={user_id})"); 578 let _wp = wd::watch("IKeystoreMaintenance::onUserAdded"); 579 self.add_or_remove_user(user_id).map_err(into_logged_binder) 580 } 581 initUserSuperKeys( &self, user_id: i32, password: &[u8], allow_existing: bool, ) -> BinderResult<()>582 fn initUserSuperKeys( 583 &self, 584 user_id: i32, 585 password: &[u8], 586 allow_existing: bool, 587 ) -> BinderResult<()> { 588 log::info!("initUserSuperKeys(user={user_id}, allow_existing={allow_existing})"); 589 let _wp = wd::watch("IKeystoreMaintenance::initUserSuperKeys"); 590 self.init_user_super_keys(user_id, password.into(), allow_existing) 591 .map_err(into_logged_binder) 592 } 593 onUserRemoved(&self, user_id: i32) -> BinderResult<()>594 fn onUserRemoved(&self, user_id: i32) -> BinderResult<()> { 595 log::info!("onUserRemoved(user={user_id})"); 596 let _wp = wd::watch("IKeystoreMaintenance::onUserRemoved"); 597 self.add_or_remove_user(user_id).map_err(into_logged_binder) 598 } 599 onUserLskfRemoved(&self, user_id: i32) -> BinderResult<()>600 fn onUserLskfRemoved(&self, user_id: i32) -> BinderResult<()> { 601 log::info!("onUserLskfRemoved(user={user_id})"); 602 let _wp = wd::watch("IKeystoreMaintenance::onUserLskfRemoved"); 603 Self::on_user_lskf_removed(user_id).map_err(into_logged_binder) 604 } 605 clearNamespace(&self, domain: Domain, nspace: i64) -> BinderResult<()>606 fn clearNamespace(&self, domain: Domain, nspace: i64) -> BinderResult<()> { 607 log::info!("clearNamespace({domain:?}, nspace={nspace})"); 608 let _wp = wd::watch("IKeystoreMaintenance::clearNamespace"); 609 self.clear_namespace(domain, nspace).map_err(into_logged_binder) 610 } 611 earlyBootEnded(&self) -> BinderResult<()>612 fn earlyBootEnded(&self) -> BinderResult<()> { 613 log::info!("earlyBootEnded()"); 614 let _wp = wd::watch("IKeystoreMaintenance::earlyBootEnded"); 615 Self::early_boot_ended().map_err(into_logged_binder) 616 } 617 migrateKeyNamespace( &self, source: &KeyDescriptor, destination: &KeyDescriptor, ) -> BinderResult<()>618 fn migrateKeyNamespace( 619 &self, 620 source: &KeyDescriptor, 621 destination: &KeyDescriptor, 622 ) -> BinderResult<()> { 623 log::info!("migrateKeyNamespace(src={source:?}, dest={destination:?})"); 624 let _wp = wd::watch("IKeystoreMaintenance::migrateKeyNamespace"); 625 Self::migrate_key_namespace(source, destination).map_err(into_logged_binder) 626 } 627 deleteAllKeys(&self) -> BinderResult<()>628 fn deleteAllKeys(&self) -> BinderResult<()> { 629 log::warn!("deleteAllKeys() invoked, indicating initial setup or post-factory reset"); 630 let _wp = wd::watch("IKeystoreMaintenance::deleteAllKeys"); 631 Self::delete_all_keys().map_err(into_logged_binder) 632 } 633 getAppUidsAffectedBySid( &self, user_id: i32, secure_user_id: i64, ) -> BinderResult<std::vec::Vec<i64>>634 fn getAppUidsAffectedBySid( 635 &self, 636 user_id: i32, 637 secure_user_id: i64, 638 ) -> BinderResult<std::vec::Vec<i64>> { 639 log::info!("getAppUidsAffectedBySid(secure_user_id={secure_user_id:?})"); 640 let _wp = wd::watch("IKeystoreMaintenance::getAppUidsAffectedBySid"); 641 Self::get_app_uids_affected_by_sid(user_id, secure_user_id).map_err(into_logged_binder) 642 } 643 } 644