Keystore 2.0: Add earlyBootEnded() to IKeystoreMaintenance
Introduce earlyBootEnded() to IKeystoreMaintenance - when called, this
method will inform all Keymint devices that early boot keys can no
longer be used. The early_boot_ended permission (in the keystore2 access
vector) is required to call this method.
Bug: 181821046
Bug: 181910578
Test: call IKeystoreMaintenance::earlyBootEnded() from vold
Change-Id: Ie1341626943c948bee002362ed7fc7f8f3abfc5b
diff --git a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
index 8bec0f7..280500c 100644
--- a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
+++ b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
@@ -90,6 +90,16 @@
UserState getState(in int userId);
/**
+ * This function notifies the Keymint device of the specified securityLevel that
+ * early boot has ended, so that they no longer allow early boot keys to be used.
+ * ## Error conditions:
+ * `ResponseCode::PERMISSION_DENIED` - if the caller does not have the 'EarlyBootEnded'
+ * permission.
+ * A KeyMint ErrorCode may be returned indicating a backend diagnosed error.
+ */
+ void earlyBootEnded();
+
+ /**
* Informs Keystore 2.0 that the an off body event was detected.
*
* ## Error conditions:
diff --git a/keystore2/src/maintenance.rs b/keystore2/src/maintenance.rs
index 1c206fc..47bd946 100644
--- a/keystore2/src/maintenance.rs
+++ b/keystore2/src/maintenance.rs
@@ -14,12 +14,16 @@
//! This module implements IKeystoreMaintenance AIDL interface.
+use crate::error::map_km_error;
use crate::error::Error as KeystoreError;
+use crate::globals::get_keymint_device;
use crate::globals::{DB, LEGACY_MIGRATOR, SUPER_KEY};
use crate::permission::KeystorePerm;
use crate::super_key::UserState;
use crate::utils::check_keystore_permission;
use crate::{database::MonotonicRawTime, error::map_or_log_err};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::IKeyMintDevice::IKeyMintDevice;
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
use android_security_maintenance::aidl::android::security::maintenance::{
IKeystoreMaintenance::{BnKeystoreMaintenance, IKeystoreMaintenance},
UserState::UserState as AidlUserState,
@@ -117,6 +121,36 @@
}
}
+ fn early_boot_ended_help(sec_level: &SecurityLevel) -> 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")?;
+ map_km_error(km_dev.earlyBootEnded())
+ .context("In keymint device: calling earlyBootEnded")?;
+ Ok(())
+ }
+
+ fn early_boot_ended() -> Result<()> {
+ check_keystore_permission(KeystorePerm::early_boot_ended())
+ .context("In early_boot_ended. Checking permission")?;
+
+ 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)
+ })
+ }
+
fn on_device_off_body() -> Result<()> {
// Security critical permission check. This statement must return on fail.
check_keystore_permission(KeystorePerm::report_off_body())
@@ -150,6 +184,10 @@
map_or_log_err(Self::get_state(user_id), Ok)
}
+ fn earlyBootEnded(&self) -> BinderResult<()> {
+ map_or_log_err(Self::early_boot_ended(), Ok)
+ }
+
fn onDeviceOffBody(&self) -> BinderResult<()> {
map_or_log_err(Self::on_device_off_body(), Ok)
}
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs
index f0a4c87..45c4dc1 100644
--- a/keystore2/src/permission.rs
+++ b/keystore2/src/permission.rs
@@ -311,6 +311,8 @@
ClearUID = 0x200, selinux name: clear_uid;
/// Checked when Credstore calls IKeystoreAuthorization to obtain auth tokens.
GetAuthToken = 0x400, selinux name: get_auth_token;
+ /// Checked when earlyBootEnded() is called.
+ EarlyBootEnded = 0x800, selinux name: early_boot_ended;
/// Checked when IKeystoreMaintenance::onDeviceOffBody is called.
ReportOffBody = 0x1000, selinux name: report_off_body;
}