Merge changes from topic "full_spec_upgrade"

* changes:
  Always fall back to factory key on any RKP error
  Adding plumbing for supported EC curve on impl
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 e54842f..ead24da 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::{
@@ -180,23 +180,34 @@
             // and therefore will not be attested.
             Ok(None)
         } else {
-            match self.get_rem_prov_attest_key(&key, caller_uid, db).context(concat!(
-                "In get_remote_provisioning_key_and_certs: Failed to get ",
-                "attestation key"
-            ))? {
-                Some(cert_chain) => Ok(Some((
-                    AttestationKey {
-                        keyBlob: cert_chain.private_key.to_vec(),
-                        attestKeyParams: vec![],
-                        issuerSubjectName: parse_subject_from_certificate(&cert_chain.batch_cert)
+            match self.get_rem_prov_attest_key(&key, caller_uid, db) {
+                Err(e) => {
+                    log::error!(
+                        concat!(
+                            "In get_remote_provisioning_key_and_certs: Failed to get ",
+                            "attestation key. {:?}"
+                        ),
+                        e
+                    );
+                    Ok(None)
+                }
+                Ok(v) => match v {
+                    Some(cert_chain) => Ok(Some((
+                        AttestationKey {
+                            keyBlob: cert_chain.private_key.to_vec(),
+                            attestKeyParams: vec![],
+                            issuerSubjectName: parse_subject_from_certificate(
+                                &cert_chain.batch_cert,
+                            )
                             .context(concat!(
-                            "In get_remote_provisioning_key_and_certs: Failed to ",
-                            "parse subject."
-                        ))?,
-                    },
-                    Certificate { encodedCertificate: cert_chain.cert_chain },
-                ))),
-                None => Ok(None),
+                                "In get_remote_provisioning_key_and_certs: Failed to ",
+                                "parse subject."
+                            ))?,
+                        },
+                        Certificate { encodedCertificate: cert_chain.cert_chain },
+                    ))),
+                    None => Ok(None),
+                },
             }
         }
     }
@@ -205,6 +216,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 +239,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()))
@@ -355,8 +379,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,
@@ -448,9 +476,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> {