Add deleteAllKeys to IKeystoreMaintenance Add a method to IKeystoreMaintenance which calls deleteAllKeys on every KM instance. This method will be called by vold when it detects a factory reset. Bug: 187105270 Test: booted Cuttlefish twice Ignore-AOSP-First: no merge path to this branch from AOSP. Merged-In: Id23f25c69a74a99bfebbf28429651d6fd647dbcd Change-Id: Id23f25c69a74a99bfebbf28429651d6fd647dbcd
diff --git a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl index 5f91e79..6a37c78 100644 --- a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl +++ b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
@@ -123,4 +123,12 @@ * `ResponseCode::SYSTEM_ERROR` - An unexpected system error occurred. */ void migrateKeyNamespace(in KeyDescriptor source, in KeyDescriptor destination); + + /** + * Deletes all keys in all hardware keystores. Used when keystore is reset completely. After + * this function is called all keys with Tag::ROLLBACK_RESISTANCE in their hardware-enforced + * authorization lists must be rendered permanently unusable. Keys without + * Tag::ROLLBACK_RESISTANCE may or may not be rendered unusable. + */ + void deleteAllKeys(); }
diff --git a/keystore2/src/maintenance.rs b/keystore2/src/maintenance.rs index 637fb61..3180e5d 100644 --- a/keystore2/src/maintenance.rs +++ b/keystore2/src/maintenance.rs
@@ -152,22 +152,50 @@ } } - fn early_boot_ended_help(sec_level: SecurityLevel) -> Result<()> { + fn call_with_watchdog<F>(sec_level: SecurityLevel, name: &'static str, op: &F) -> Result<()> + where + F: Fn(Strong<dyn IKeyMintDevice>) -> binder::public_api::Result<()>, + { let (dev, _, _) = get_keymint_device(&sec_level) - .context("In early_boot_ended: getting keymint device")?; - let km_dev: Strong<dyn IKeyMintDevice> = - dev.get_interface().context("In early_boot_ended: getting keymint device interface")?; + .context("In call_with_watchdog: getting keymint device")?; + let km_dev: Strong<dyn IKeyMintDevice> = dev + .get_interface() + .context("In call_with_watchdog: getting keymint device interface")?; - let _wp = wd::watch_millis_with( - "In early_boot_ended_help: calling earlyBootEnded()", - 500, - move || format!("Seclevel: {:?}", sec_level), - ); - map_km_error(km_dev.earlyBootEnded()) - .context("In keymint device: calling earlyBootEnded")?; + let _wp = wd::watch_millis_with("In call_with_watchdog", 500, move || { + format!("Seclevel: {:?} Op: {}", sec_level, name) + }); + map_km_error(op(km_dev)).with_context(|| format!("In keymint device: calling {}", name))?; Ok(()) } + fn call_on_all_security_levels<F>(name: &'static str, op: F) -> Result<()> + where + F: Fn(Strong<dyn IKeyMintDevice>) -> binder::public_api::Result<()>, + { + let sec_levels = [ + (SecurityLevel::TRUSTED_ENVIRONMENT, "TRUSTED_ENVIRONMENT"), + (SecurityLevel::STRONGBOX, "STRONGBOX"), + ]; + sec_levels.iter().fold(Ok(()), move |result, (sec_level, sec_level_string)| { + let curr_result = Maintenance::call_with_watchdog(*sec_level, name, &op); + match curr_result { + Ok(()) => log::info!( + "Call to {} succeeded for security level {}.", + name, + &sec_level_string + ), + Err(ref e) => log::error!( + "Call to {} failed for security level {}: {}.", + name, + &sec_level_string, + e + ), + } + result.and(curr_result) + }) + } + fn early_boot_ended() -> Result<()> { check_keystore_permission(KeystorePerm::early_boot_ended()) .context("In early_boot_ended. Checking permission")?; @@ -176,21 +204,7 @@ if let Err(e) = DB.with(|db| SUPER_KEY.set_up_boot_level_cache(&mut db.borrow_mut())) { log::error!("SUPER_KEY.set_up_boot_level_cache failed:\n{:?}\n:(", e); } - - let sec_levels = [ - (SecurityLevel::TRUSTED_ENVIRONMENT, "TRUSTED_ENVIRONMENT"), - (SecurityLevel::STRONGBOX, "STRONGBOX"), - ]; - sec_levels.iter().fold(Ok(()), |result, (sec_level, sec_level_string)| { - let curr_result = Maintenance::early_boot_ended_help(*sec_level); - if curr_result.is_err() { - log::error!( - "Call to earlyBootEnded failed for security level {}.", - &sec_level_string - ); - } - result.and(curr_result) - }) + Maintenance::call_on_all_security_levels("earlyBootEnded", |dev| dev.earlyBootEnded()) } fn on_device_off_body() -> Result<()> { @@ -238,6 +252,15 @@ }) }) } + + fn delete_all_keys() -> Result<()> { + // Security critical permission check. This statement must return on fail. + check_keystore_permission(KeystorePerm::delete_all_keys()) + .context("In delete_all_keys. Checking permission")?; + log::info!("In delete_all_keys."); + + Maintenance::call_on_all_security_levels("deleteAllKeys", |dev| dev.deleteAllKeys()) + } } impl Interface for Maintenance {} @@ -286,4 +309,9 @@ let _wp = wd::watch_millis("IKeystoreMaintenance::migrateKeyNamespace", 500); map_or_log_err(Self::migrate_key_namespace(source, destination), Ok) } + + fn deleteAllKeys(&self) -> BinderResult<()> { + let _wp = wd::watch_millis("IKeystoreMaintenance::deleteAllKeys", 500); + map_or_log_err(Self::delete_all_keys(), Ok) + } }
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs index 8343a29..4add899 100644 --- a/keystore2/src/permission.rs +++ b/keystore2/src/permission.rs
@@ -317,6 +317,8 @@ ReportOffBody = 0x1000, selinux name: report_off_body; /// Checked when IkeystoreMetrics::pullMetris is called. PullMetrics = 0x2000, selinux name: pull_metrics; + /// Checked when IKeystoreMaintenance::deleteAllKeys is called. + DeleteAllKeys = 0x4000, selinux name: delete_all_keys; } );