Merge changes from topic "get_attestation_input" into main

* changes:
  Add getSupplementaryAttestationInfo
  Bump KeyMint and Keystore version
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index e71ded9..c8f5674 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -101,6 +101,7 @@
         "framework-jobscheduler-job.flags-aconfig-java",
         "framework_graphics_flags_java_lib",
         "hwui_flags_java_lib",
+        "keystore2_flags_java-framework",
         "power_flags_lib",
         "sdk_sandbox_flags_lib",
         "surfaceflinger_flags_java_lib",
diff --git a/Android.bp b/Android.bp
index d2e8003..dc48668 100644
--- a/Android.bp
+++ b/Android.bp
@@ -105,7 +105,6 @@
         ":android.hardware.radio.data-V3-java-source",
         ":android.hardware.radio.network-V3-java-source",
         ":android.hardware.radio.voice-V3-java-source",
-        ":android.hardware.security.keymint-V3-java-source",
         ":android.hardware.security.secureclock-V1-java-source",
         ":android.hardware.thermal-V2-java-source",
         ":android.hardware.tv.tuner-V2-java-source",
@@ -114,7 +113,6 @@
         ":android.security.legacykeystore-java-source",
         ":android.security.maintenance-java-source",
         ":android.security.metrics-java-source",
-        ":android.system.keystore2-V4-java-source",
         ":android.hardware.cas-V1-java-source",
         ":credstore_aidl",
         ":dumpstate_aidl",
@@ -149,7 +147,16 @@
         ":framework-javastream-protos",
         ":statslog-framework-java-gen", // FrameworkStatsLog.java
         ":audio_policy_configuration_V7_0",
-    ],
+    ] + select(release_flag("RELEASE_ATTEST_MODULES"), {
+        true: [
+            ":android.hardware.security.keymint-V4-java-source",
+            ":android.system.keystore2-V5-java-source",
+        ],
+        default: [
+            ":android.hardware.security.keymint-V3-java-source",
+            ":android.system.keystore2-V4-java-source",
+        ],
+    }),
 }
 
 java_library {
diff --git a/core/api/current.txt b/core/api/current.txt
index 18be7e2..1f45289 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40035,8 +40035,10 @@
     method @NonNull public java.util.List<java.security.cert.X509Certificate> getGrantedCertificateChainFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
     method @NonNull public java.security.Key getGrantedKeyFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
     method @NonNull public java.security.KeyPair getGrantedKeyPairFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
+    method @FlaggedApi("android.security.keystore2.attest_modules") @NonNull public byte[] getSupplementaryAttestationInfo(int) throws android.security.KeyStoreException;
     method public long grantKeyAccess(@NonNull String, int) throws android.security.KeyStoreException, java.security.UnrecoverableKeyException;
     method public void revokeKeyAccess(@NonNull String, int) throws android.security.KeyStoreException, java.security.UnrecoverableKeyException;
+    field public static final int MODULE_HASH = -1879047468; // 0x900002d4
   }
 
   public class SecureKeyImportUnavailableException extends java.security.ProviderException {
diff --git a/keystore/java/Android.bp b/keystore/java/Android.bp
index 21edff1..264ac5ff 100644
--- a/keystore/java/Android.bp
+++ b/keystore/java/Android.bp
@@ -13,5 +13,13 @@
         "**/*.java",
         "**/*.aidl",
     ],
+    exclude_srcs: select(release_flag("RELEASE_ATTEST_MODULES"), {
+        true: [
+            "android/security/KeyStore2HalCurrent.java",
+        ],
+        default: [
+            "android/security/KeyStore2HalLatest.java",
+        ],
+    }),
     visibility: ["//frameworks/base"],
 }
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index dd703f5..f5cf571 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -101,7 +101,7 @@
         R execute(IKeystoreService service) throws RemoteException;
     }
 
-    private <R> R handleRemoteExceptionWithRetry(@NonNull CheckedRemoteRequest<R> request)
+    <R> R handleRemoteExceptionWithRetry(@NonNull CheckedRemoteRequest<R> request)
             throws KeyStoreException {
         IKeystoreService service = getService(false /* retryLookup */);
         boolean firstTry = true;
@@ -369,6 +369,18 @@
         }
     }
 
+    /**
+     * Returns tag-specific info required to interpret a tag's attested value.
+     * @see IKeystoreService#getSupplementaryAttestationInfo(Tag) for more details.
+     * @param tag
+     * @return
+     * @throws KeyStoreException
+     * @hide
+     */
+    public byte[] getSupplementaryAttestationInfo(int tag) throws KeyStoreException {
+        return KeyStore2HalVersion.getSupplementaryAttestationInfoHelper(tag, this);
+    }
+
     static KeyStoreException getKeyStoreException(int errorCode, String serviceErrorMessage) {
         if (errorCode > 0) {
             // KeyStore layer error
diff --git a/keystore/java/android/security/KeyStore2HalCurrent.java b/keystore/java/android/security/KeyStore2HalCurrent.java
new file mode 100644
index 0000000..f4d8fe6
--- /dev/null
+++ b/keystore/java/android/security/KeyStore2HalCurrent.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 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;
+
+/**
+ * @hide This class is necessary to allow the version of the AIDL interface for Keystore and
+* KeyMint used in KeyStore2.java to differ by BUILD flag `RELEASE_ATTEST_MODULES`. When
+* `RELEASE_ATTEST_MODULES` is not set, this file is included, and the current HALs for Keystore
+* (V4) and KeyMint (V3) are used.
+*/
+class KeyStore2HalVersion {
+    public static byte[] getSupplementaryAttestationInfoHelper(int tag, KeyStore2 ks)
+            throws KeyStoreException {
+        return new byte[0];
+    }
+}
diff --git a/keystore/java/android/security/KeyStore2HalLatest.java b/keystore/java/android/security/KeyStore2HalLatest.java
new file mode 100644
index 0000000..b6e1cbb
--- /dev/null
+++ b/keystore/java/android/security/KeyStore2HalLatest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 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;
+
+/**
+ * @hide This class is necessary to allow the version of the AIDL interface for Keystore and
+* KeyMint used in KeyStore2.java to differ by BUILD flag `RELEASE_ATTEST_MODULES`. When
+* `RELEASE_ATTEST_MODULES` is set, this file is included, and the latest HALs for Keystore (V5)
+* and KeyMint (V4) are used.
+*/
+class KeyStore2HalVersion {
+    public byte[] getSupplementaryAttestationInfoHelper(int tag, KeyStore2 ks)
+            throws KeyStoreException {
+        return ks.handleRemoteExceptionWithRetry(
+            (service) -> service.getSupplementaryAttestationInfo(tag));
+    }
+}
diff --git a/keystore/java/android/security/keystore/KeyStoreManager.java b/keystore/java/android/security/keystore/KeyStoreManager.java
index e6091c1d..740ccb5 100644
--- a/keystore/java/android/security/keystore/KeyStoreManager.java
+++ b/keystore/java/android/security/keystore/KeyStoreManager.java
@@ -17,9 +17,11 @@
 package android.security.keystore;
 
 import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.hardware.security.keymint.TagType;
 import android.security.KeyStore2;
 import android.security.KeyStoreException;
 import android.security.keystore2.AndroidKeyStoreProvider;
@@ -32,6 +34,8 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.ByteArrayInputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.security.Key;
 import java.security.KeyPair;
 import java.security.PublicKey;
@@ -299,6 +303,37 @@
         return Collections.emptyList();
     }
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {MODULE_HASH})
+    public @interface SupplementaryAttestationInfoTagEnum {}
+
+    /**
+     * When passed into getSupplementaryAttestationInfo, getSupplementaryAttestationInfo returns the
+     * DER-encoded structure corresponding to the `Modules` schema described in the KeyMint HAL's
+     * KeyCreationResult.aidl. The SHA-256 hash of this encoded structure is what's included with
+     * the tag in attestations.
+     */
+    // TODO(b/369375199): Replace with Tag.MODULE_HASH when flagging is removed.
+    public static final int MODULE_HASH = TagType.BYTES | 724;
+
+    /**
+     * Returns tag-specific data required to interpret a tag's attested value.
+     *
+     * When performing key attestation, the obtained attestation certificate contains a list of tags
+     * and their corresponding attested values. For some tags, additional information about the
+     * attested value can be queried via this API. See individual tags for specifics.
+     *
+     * @param tag tag for which info is being requested
+     * @return tag-specific info
+     * @throws KeyStoreException if the requested info is not available
+     */
+    @FlaggedApi(android.security.keystore2.Flags.FLAG_ATTEST_MODULES)
+    public @NonNull byte[] getSupplementaryAttestationInfo(
+            @SupplementaryAttestationInfoTagEnum int tag) throws KeyStoreException {
+        return mKeyStore2.getSupplementaryAttestationInfo(tag);
+    }
+
     /**
      * Returns a new {@link KeyDescriptor} instance in the app domain / namespace with the {@code
      * alias} set to the provided value.