Only fetch an attestation key if challenge present

Currently, KS2 will always fetch and provide an attestation key for a
key being generated. This behavior is currently hidden by the fact that
for a factory provisioned KM, the behavior to just generate or generate
and attest to a key is the same from the KS2 perspective. KM figures out
if it should actually attest to the key by checking if an
ATTESTATION_CHALLENGE tag is present.

Alternatively, KS2 provides a user provided attestation key, which
should only be used if an attestation challenge is present. This would
also fail, probably expectedly, if the user provided their own
attestation key during key generation and didn't specify a challenge.
The issue arrises when RKP is enabled, as KS2 will always assign and
fetch an RKP key for a process that's generating a key, even if
attestation isn't requested. This causes key generation to fail for
non-attested keys.

This patch first checks to see if an ATTESTATION_CHALLENGE is present
before attempting to attest to the key.

Fixes: 191951059
Test: atest com.android.keychain.tests.BasicKeyChainServiceTest
Change-Id: Ibf9d31ca6519477c1aba6ab4a8dfe98b4f1f0d81
Merged-In: Ibf9d31ca6519477c1aba6ab4a8dfe98b4f1f0d81
diff --git a/keystore2/src/attestation_key_utils.rs b/keystore2/src/attestation_key_utils.rs
index 425eec6..ca00539 100644
--- a/keystore2/src/attestation_key_utils.rs
+++ b/keystore2/src/attestation_key_utils.rs
@@ -22,7 +22,7 @@
 use crate::remote_provisioning::RemProvState;
 use crate::utils::check_key_permission;
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
-    AttestationKey::AttestationKey, Certificate::Certificate, KeyParameter::KeyParameter,
+    AttestationKey::AttestationKey, Certificate::Certificate, KeyParameter::KeyParameter, Tag::Tag,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
     Domain::Domain, KeyDescriptor::KeyDescriptor,
@@ -47,8 +47,8 @@
 }
 
 /// This function loads and, optionally, assigns the caller's remote provisioned
-/// attestation key or, if `attest_key_descriptor` is given, it loads the user
-/// generated attestation key from the database.
+/// attestation key if a challenge is present. Alternatively, if `attest_key_descriptor` is given,
+/// it loads the user generated attestation key from the database.
 pub fn get_attest_key_info(
     key: &KeyDescriptor,
     caller_uid: u32,
@@ -57,8 +57,9 @@
     rem_prov_state: &RemProvState,
     db: &mut KeystoreDB,
 ) -> Result<Option<AttestationKeyInfo>> {
+    let challenge_present = params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE);
     match attest_key_descriptor {
-        None => rem_prov_state
+        None if challenge_present => rem_prov_state
             .get_remotely_provisioned_attestation_key_and_certs(&key, caller_uid, params, db)
             .context(concat!(
                 "In get_attest_key_and_cert_chain: ",
@@ -69,6 +70,7 @@
                     AttestationKeyInfo::RemoteProvisioned { attestation_key, attestation_certs }
                 })
             }),
+        None => Ok(None),
         Some(attest_key) => get_user_generated_attestation_key(&attest_key, caller_uid, db)
             .context("In get_attest_key_and_cert_chain: Trying to load attest key")
             .map(Some),