Return OUT_OF_KEYS if system is rkp only

This change leverages the ro.remote_provisioning.rkp_only system
property in order to determine whether or not the system has fallback
keys. If there are no fallback keys, then ks2 will now return
OUT_OF_KEYS as a ResponseCode to the caller over the binder interface.

This will allow the caller to call generateKey() on the
RemoteProvisioner AIDL interface, blocking until the call is returned.
At this point, keys will either have been provisioned, or an actionable
error can be routed back to the developer.

Bug: 227306369
Test: atest RemoteProvisionerUnitTests
Change-Id: I8f5bc5add4ab895ab95c9e4e70e6fc9fa4422da5
This commit is contained in:
Max Bires 2022-03-29 23:58:08 -07:00 committed by Seth Moore
parent b174ed0494
commit 65207b5f10

View file

@ -60,6 +60,7 @@ pub struct RemProvState {
security_level: SecurityLevel,
km_uuid: Uuid,
is_hal_present: AtomicBool,
is_rkp_only: bool,
}
static COSE_KEY_XCOORD: Value = Value::Integer(-2);
@ -70,7 +71,12 @@ static COSE_MAC0_PAYLOAD: usize = 2;
impl RemProvState {
/// Creates a RemProvState struct.
pub fn new(security_level: SecurityLevel, km_uuid: Uuid) -> Self {
Self { security_level, km_uuid, is_hal_present: AtomicBool::new(true) }
Self {
security_level,
km_uuid,
is_hal_present: AtomicBool::new(true),
is_rkp_only: Self::read_is_rkp_only_property(security_level),
}
}
/// Returns the uuid for the KM instance attached to this RemProvState struct.
@ -78,6 +84,19 @@ impl RemProvState {
self.km_uuid
}
fn read_is_rkp_only_property(security_level: SecurityLevel) -> bool {
let default_value = false;
let property_name = match security_level {
SecurityLevel::STRONGBOX => "ro.remote_provisioning.strongbox.rkp_only",
SecurityLevel::TRUSTED_ENVIRONMENT => "ro.remote_provisioning.tee.rkp_only",
_ => return default_value,
};
rustutils::system_properties::read_bool(property_name, default_value)
.unwrap_or(default_value)
}
/// Checks if remote provisioning is enabled and partially caches the result. On a hybrid system
/// remote provisioning can flip from being disabled to enabled depending on responses from the
/// server, so unfortunately caching the presence or absence of the HAL is not enough to fully
@ -137,12 +156,12 @@ impl RemProvState {
match get_rem_prov_attest_key(key.domain, caller_uid, db, &self.km_uuid) {
Err(e) => {
log::error!(
concat!(
"In get_remote_provisioning_key_and_certs: Failed to get ",
"attestation key. {:?}"
),
"In get_remote_provisioning_key_and_certs: Error occurred: {:?}",
e
);
if self.is_rkp_only {
return Err(e);
}
log_rkp_error_stats(MetricsRkpError::FALL_BACK_DURING_HYBRID);
Ok(None)
}