From d2ce46b5f136a19b9c004f50f7a3ccbd1fb23baa Mon Sep 17 00:00:00 2001 From: Max Bires Date: Tue, 6 Jul 2021 02:54:47 -0700 Subject: [PATCH] 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 --- .../IRemoteProvisioning.aidl | 10 +++-- .../security/remoteprovisioning/ImplInfo.aidl | 37 +++++++++++++++++++ keystore2/src/remote_provisioning.rs | 27 +++++++++++--- 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl diff --git a/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl index 4a092af8..ecdc7901 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.DeviceInfo; 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 @@ interface IRemoteProvisioning { 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 00000000..9baeb24b --- /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 9e2424bf..8fef5069 100644 --- a/keystore2/src/remote_provisioning.rs +++ b/keystore2/src/remote_provisioning.rs @@ -30,7 +30,7 @@ use android_hardware_security_keymint::aidl::android::hardware::security::keymin }; 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 @@ impl RemProvState { #[derive(Default)] pub struct RemoteProvisioningService { device_by_sec_level: HashMap>, + curve_by_sec_level: HashMap, } impl RemoteProvisioningService { @@ -227,8 +228,20 @@ impl RemoteProvisioningService { 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 @@ impl RemoteProvisioningService { /// 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> { - Ok(self.device_by_sec_level.keys().cloned().collect()) + pub fn get_implementation_info(&self) -> Result> { + 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 @@ impl IRemoteProvisioning for RemoteProvisioningService { map_or_log_err(self.generate_key_pair(is_test_mode, sec_level), Ok) } - fn getSecurityLevels(&self) -> binder::public_api::Result> { + fn getImplementationInfo(&self) -> binder::public_api::Result> { 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 {