Merge "Remove android.hardware.biometrics.last_authentication_time" into main
diff --git a/keystore2/aidl/android/security/metrics/HardwareAuthenticatorType.aidl b/keystore2/aidl/android/security/metrics/HardwareAuthenticatorType.aidl
index b13f6ea..d5cacfd 100644
--- a/keystore2/aidl/android/security/metrics/HardwareAuthenticatorType.aidl
+++ b/keystore2/aidl/android/security/metrics/HardwareAuthenticatorType.aidl
@@ -17,16 +17,41 @@
 package android.security.metrics;
 
 /**
- * HardwareAuthenticatorType enum as defined in Keystore2KeyCreationWithAuthInfo of
- * frameworks/proto_logging/stats/atoms.proto.
+ * AIDL enum representing the
+ * android.os.statsd.Keystore2KeyCreationWithAuthInfo.HardwareAuthenticatorType protocol buffer enum
+ * defined in frameworks/proto_logging/stats/atoms.proto.
+ *
+ * This enum is a mirror of
+ * hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
+ * except that:
+ *   - The enum tag number for the ANY value is set to 5,
+ *   - The enum tag numbers of all other values are incremented by 1, and
+ *   - Two new values are added: AUTH_TYPE_UNSPECIFIED and NO_AUTH_TYPE.
+ * The KeyMint AIDL enum is a bitmask, but since the enum tag numbers in this metrics-specific
+ * mirror were shifted, this enum can't behave as a bitmask. As a result, we have to explicitly add
+ * values to represent the bitwise OR of pairs of values that we expect to see in the wild.
  * @hide
  */
 @Backing(type="int")
 enum HardwareAuthenticatorType {
-    /** Unspecified takes 0. Other values are incremented by 1 compared to keymint spec. */
+    // Sentinel value to represent undefined enum tag numbers (which would represent combinations of
+    // values from the KeyMint enum that aren't explicitly represented here). We don't expect to see
+    // this value in the metrics, but if we do it means that an unexpected (bitwise OR) combination
+    // of KeyMint HardwareAuthenticatorType values is being used as the HardwareAuthenticatorType
+    // key parameter.
     AUTH_TYPE_UNSPECIFIED = 0,
+    // Corresponds to KeyMint's HardwareAuthenticatorType::NONE value (enum tag number 0).
     NONE = 1,
+    // Corresponds to KeyMint's HardwareAuthenticatorType::PASSWORD value (enum tag number 1 << 0).
     PASSWORD = 2,
+    // Corresponds to KeyMint's HardwareAuthenticatorType::FINGERPRINT value (enum tag number
+    // 1 << 1).
     FINGERPRINT = 3,
+    // Corresponds to the (bitwise OR) combination of KeyMint's HardwareAuthenticatorType::PASSWORD
+    // and HardwareAuthenticatorType::FINGERPRINT values.
+    PASSWORD_OR_FINGERPRINT = 4,
+    // Corresponds to KeyMint's HardwareAuthenticatorType::ANY value (enum tag number 0xFFFFFFFF).
     ANY = 5,
+    // No HardwareAuthenticatorType was specified in the key parameters.
+    NO_AUTH_TYPE = 6,
 }
\ No newline at end of file
diff --git a/keystore2/src/metrics_store.rs b/keystore2/src/metrics_store.rs
index fd1f9b5..72bbfe2 100644
--- a/keystore2/src/metrics_store.rs
+++ b/keystore2/src/metrics_store.rs
@@ -205,7 +205,7 @@
     };
 
     let mut key_creation_with_auth_info = KeyCreationWithAuthInfo {
-        user_auth_type: MetricsHardwareAuthenticatorType::AUTH_TYPE_UNSPECIFIED,
+        user_auth_type: MetricsHardwareAuthenticatorType::NO_AUTH_TYPE,
         log10_auth_key_timeout_seconds: -1,
         security_level: MetricsSecurityLevel::SECURITY_LEVEL_UNSPECIFIED,
     };
@@ -258,6 +258,12 @@
                     HardwareAuthenticatorType::FINGERPRINT => {
                         MetricsHardwareAuthenticatorType::FINGERPRINT
                     }
+                    a if a.0
+                        == HardwareAuthenticatorType::PASSWORD.0
+                            | HardwareAuthenticatorType::FINGERPRINT.0 =>
+                    {
+                        MetricsHardwareAuthenticatorType::PASSWORD_OR_FINGERPRINT
+                    }
                     HardwareAuthenticatorType::ANY => MetricsHardwareAuthenticatorType::ANY,
                     _ => MetricsHardwareAuthenticatorType::AUTH_TYPE_UNSPECIFIED,
                 }
@@ -792,14 +798,14 @@
     SECURITY_LEVEL_KEYSTORE => "KEYSTORE",
 );
 
-// Metrics values for HardwareAuthenticatorType are broken -- the AIDL type is a bitmask
-// not an enum, so offseting the enum values by 1 doesn't work.
-impl_summary_enum!(MetricsHardwareAuthenticatorType, 6,
+impl_summary_enum!(MetricsHardwareAuthenticatorType, 8,
     AUTH_TYPE_UNSPECIFIED => "UNSPEC",
     NONE => "NONE",
     PASSWORD => "PASSWD",
     FINGERPRINT => "FPRINT",
+    PASSWORD_OR_FINGERPRINT => "PW_OR_FP",
     ANY => "ANY",
+    NO_AUTH_TYPE => "NOAUTH",
 );
 
 impl_summary_enum!(MetricsPurpose, 7,
diff --git a/keystore2/tests/keystore2_client_authorizations_tests.rs b/keystore2/tests/keystore2_client_authorizations_tests.rs
index a739efb..6d105cc 100644
--- a/keystore2/tests/keystore2_client_authorizations_tests.rs
+++ b/keystore2/tests/keystore2_client_authorizations_tests.rs
@@ -521,6 +521,10 @@
 #[test]
 fn keystore2_gen_key_auth_usage_count_limit() {
     let sl = SecLevel::tee();
+    if sl.is_keymaster() {
+        // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
+        return;
+    }
     const MAX_USES_COUNT: i32 = 3;
 
     let gen_params = authorizations::AuthSetBuilder::new()
@@ -545,6 +549,10 @@
 #[test]
 fn keystore2_gen_key_auth_usage_count_limit_one() {
     let sl = SecLevel::tee();
+    if sl.is_keymaster() {
+        // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
+        return;
+    }
     const MAX_USES_COUNT: i32 = 1;
 
     let gen_params = authorizations::AuthSetBuilder::new()
@@ -568,6 +576,10 @@
 #[test]
 fn keystore2_gen_non_attested_key_auth_usage_count_limit() {
     let sl = SecLevel::tee();
+    if sl.is_keymaster() {
+        // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
+        return;
+    }
     const MAX_USES_COUNT: i32 = 2;
 
     let gen_params = authorizations::AuthSetBuilder::new()
@@ -630,6 +642,12 @@
 #[test]
 fn keystore2_gen_key_auth_include_unique_id_success() {
     let sl = SecLevel::tee();
+    if sl.is_keymaster() {
+        // b/387208956 - Some older devices with Keymaster implementations fail to generate an
+        // attestation key with `INCLUDE_UNIQUE_ID`, but this was not previously tested. Skip this
+        // test on devices with Keymaster implementation.
+        return;
+    }
 
     let alias_first = "ks_test_auth_tags_test_1";
     if let Some(unique_id_first) = gen_key_including_unique_id(&sl, alias_first) {
@@ -984,6 +1002,11 @@
         // Module info is only populated if the flag is set.
         return;
     }
+
+    // Test should not run before MODULE_HASH supplementary info is populated.
+    assert!(rustutils::system_properties::read_bool("keystore.module_hash.sent", false)
+        .unwrap_or(false));
+
     let sl = SecLevel::tee();
 
     // Retrieve the input value that gets hashed into the attestation.
@@ -1002,6 +1025,11 @@
     assert!(result.is_err());
     assert_eq!(result.unwrap_err(), Error::Rc(ResponseCode::INVALID_ARGUMENT));
 
+    if sl.get_keymint_version() < 400 {
+        // Module hash will only be populated in KeyMint if the underlying device is KeyMint V4+.
+        return;
+    }
+
     // Generate an attestation.
     let alias = "ks_module_info_test";
     let params = authorizations::AuthSetBuilder::new()