Adding plumbing for supported EC curve on impl
This change replaces getSecurityLevels() with getImplementationInfo().
Instead of returning an array of integers that only indicates which
security levels the underlying implementations are running as, the new
method returns a parcelable with additional info. Specifically, the
supported EC curve is now sent back to the caller in this Parcelable as
well as the security level.
This change is part of the alterations necessary to support P256 EEKs.
The component sitting between the provisioning server and keystore2 will
need to know which signed EEK certificate chain to pass down to keystore
for a given security level.
Bug: 189018262
Test: atest RemoteProvisionerUnitTests
Change-Id: I416922edad6e0d0245b65fb02983210e790c1221
diff --git a/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
index 4a092af..ecdc790 100644
--- a/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
+++ b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
@@ -20,6 +20,7 @@
import android.hardware.security.keymint.ProtectedData;
import android.hardware.security.keymint.SecurityLevel;
import android.security.remoteprovisioning.AttestationPoolStatus;
+import android.security.remoteprovisioning.ImplInfo;
/**
* `IRemoteProvisioning` is the interface provided to use the remote provisioning functionality
@@ -127,13 +128,14 @@
void generateKeyPair(in boolean is_test_mode, in SecurityLevel secLevel);
/**
- * This method returns the SecurityLevels of whichever instances of
+ * This method returns implementation information for whichever instances of
* IRemotelyProvisionedComponent are running on the device. The RemoteProvisioner app needs to
- * know which KM instances it should be generating and managing attestation keys for.
+ * know which KM instances it should be generating and managing attestation keys for, and which
+ * EC curves are supported in those instances.
*
- * @return The array of security levels.
+ * @return The array of ImplInfo parcelables.
*/
- SecurityLevel[] getSecurityLevels();
+ ImplInfo[] getImplementationInfo();
/**
* This method deletes all remotely provisioned attestation keys in the database, regardless
diff --git a/keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl b/keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl
new file mode 100644
index 0000000..9baeb24
--- /dev/null
+++ b/keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.remoteprovisioning;
+
+import android.hardware.security.keymint.SecurityLevel;
+
+/**
+ * This parcelable provides information about the underlying IRemotelyProvisionedComponent
+ * implementation.
+ * @hide
+ */
+parcelable ImplInfo {
+ /**
+ * The security level of the underlying implementation: TEE or StrongBox.
+ */
+ SecurityLevel secLevel;
+ /**
+ * An integer denoting which EC curve is supported in the underlying implementation. The current
+ * options are either P256 or 25519, with values defined in
+ * hardware/interfaces/security/keymint/aidl/.../RpcHardwareInfo.aidl
+ */
+ int supportedCurve;
+}
diff --git a/keystore2/src/remote_provisioning.rs b/keystore2/src/remote_provisioning.rs
index 9e2424b..8fef506 100644
--- a/keystore2/src/remote_provisioning.rs
+++ b/keystore2/src/remote_provisioning.rs
@@ -30,7 +30,7 @@
};
use android_security_remoteprovisioning::aidl::android::security::remoteprovisioning::{
AttestationPoolStatus::AttestationPoolStatus, IRemoteProvisioning::BnRemoteProvisioning,
- IRemoteProvisioning::IRemoteProvisioning,
+ IRemoteProvisioning::IRemoteProvisioning, ImplInfo::ImplInfo,
};
use android_security_remoteprovisioning::binder::{BinderFeatures, Strong};
use android_system_keystore2::aidl::android::system::keystore2::{
@@ -205,6 +205,7 @@
#[derive(Default)]
pub struct RemoteProvisioningService {
device_by_sec_level: HashMap<SecurityLevel, Strong<dyn IRemotelyProvisionedComponent>>,
+ curve_by_sec_level: HashMap<SecurityLevel, i32>,
}
impl RemoteProvisioningService {
@@ -227,8 +228,20 @@
let mut result: Self = Default::default();
let dev = get_remotely_provisioned_component(&SecurityLevel::TRUSTED_ENVIRONMENT)
.context("In new_native_binder: Failed to get TEE Remote Provisioner instance.")?;
+ result.curve_by_sec_level.insert(
+ SecurityLevel::TRUSTED_ENVIRONMENT,
+ dev.getHardwareInfo()
+ .context("In new_native_binder: Failed to get hardware info for the TEE.")?
+ .supportedEekCurve,
+ );
result.device_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, dev);
if let Ok(dev) = get_remotely_provisioned_component(&SecurityLevel::STRONGBOX) {
+ result.curve_by_sec_level.insert(
+ SecurityLevel::STRONGBOX,
+ dev.getHardwareInfo()
+ .context("In new_native_binder: Failed to get hardware info for StrongBox.")?
+ .supportedEekCurve,
+ );
result.device_by_sec_level.insert(SecurityLevel::STRONGBOX, dev);
}
Ok(BnRemoteProvisioning::new_binder(result, BinderFeatures::default()))
@@ -375,8 +388,12 @@
/// Checks the security level of each available IRemotelyProvisionedComponent hal and returns
/// all levels in an array to the caller.
- pub fn get_security_levels(&self) -> Result<Vec<SecurityLevel>> {
- Ok(self.device_by_sec_level.keys().cloned().collect())
+ pub fn get_implementation_info(&self) -> Result<Vec<ImplInfo>> {
+ Ok(self
+ .curve_by_sec_level
+ .iter()
+ .map(|(sec_level, curve)| ImplInfo { secLevel: *sec_level, supportedCurve: *curve })
+ .collect())
}
/// Deletes all attestation keys generated by the IRemotelyProvisionedComponent from the device,
@@ -452,9 +469,9 @@
map_or_log_err(self.generate_key_pair(is_test_mode, sec_level), Ok)
}
- fn getSecurityLevels(&self) -> binder::public_api::Result<Vec<SecurityLevel>> {
+ fn getImplementationInfo(&self) -> binder::public_api::Result<Vec<ImplInfo>> {
let _wp = wd::watch_millis("IRemoteProvisioning::getSecurityLevels", 500);
- map_or_log_err(self.get_security_levels(), Ok)
+ map_or_log_err(self.get_implementation_info(), Ok)
}
fn deleteAllKeys(&self) -> binder::public_api::Result<i64> {