Merge changes from topic "permissions_UM_aidl"

* changes:
  Keystore 2.0: Implement legacy blob support.
  Make 'password unlock' depend on user management infrastructure.
  Super encrypted keys
  Implement user manager AIDL.
  Populate user states.
  Add keystore permissions required by user manager AIDL.
diff --git a/Android.bp b/Android.bp
index b44c296..4a0253c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1 +1,31 @@
+package {
+    default_applicable_licenses: ["system_security_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+    name: "system_security_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 subdirs = ["*"]
diff --git a/fsverity_init/Android.bp b/fsverity_init/Android.bp
index 3c9ade0..39d4e6b 100644
--- a/fsverity_init/Android.bp
+++ b/fsverity_init/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 cc_binary {
     name: "fsverity_init",
     srcs: [
diff --git a/identity/Android.bp b/identity/Android.bp
index e6d77c8..ed8ff2f 100644
--- a/identity/Android.bp
+++ b/identity/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 cc_defaults {
     name: "identity_defaults",
     cflags: [
diff --git a/keystore-engine/Android.bp b/keystore-engine/Android.bp
index 6512c66..b8127d3 100644
--- a/keystore-engine/Android.bp
+++ b/keystore-engine/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-BSD
+    default_applicable_licenses: ["system_security_license"],
+}
+
 cc_library_shared {
     name: "libkeystore-engine",
 
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 45b721b..7278cee 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -1,3 +1,13 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    default_applicable_licenses: ["system_security_license"],
+}
+
 cc_defaults {
     name: "keystore_defaults",
 
diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp
index 883e020..327eb93 100644
--- a/keystore/tests/Android.bp
+++ b/keystore/tests/Android.bp
@@ -1,5 +1,14 @@
 // Unit test for AuthTokenTable
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 cc_test {
     cflags: [
         "-Wall",
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index fec74f6..812d5e6 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 rust_library {
     name: "libkeystore2",
     crate_name: "keystore2",
diff --git a/keystore2/TEST_MAPPING b/keystore2/TEST_MAPPING
index 33d157e..d4e20de 100644
--- a/keystore2/TEST_MAPPING
+++ b/keystore2/TEST_MAPPING
@@ -4,9 +4,6 @@
       "name": "keystore2_certificate_test"
     },
     {
-      "name": "keystore2_km_compat_test"
-    },
-    {
       "name": "keystore2_test"
     }
   ]
diff --git a/keystore2/aaid/Android.bp b/keystore2/aaid/Android.bp
index 2329400..d27fdf6 100644
--- a/keystore2/aaid/Android.bp
+++ b/keystore2/aaid/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 cc_library {
     name: "libkeystore2_aaid",
     srcs: [
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index 9af5d6a..d529fa9 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 aidl_interface {
     name: "android.security.attestationmanager",
     srcs: [ "android/security/attestationmanager/*.aidl", ],
diff --git a/keystore2/apc_compat/Android.bp b/keystore2/apc_compat/Android.bp
index 405e9b8..9519c8e 100644
--- a/keystore2/apc_compat/Android.bp
+++ b/keystore2/apc_compat/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 cc_library {
     name: "libkeystore2_apc_compat",
     srcs: [
diff --git a/keystore2/selinux/Android.bp b/keystore2/selinux/Android.bp
index acbf5ef..18063d3 100644
--- a/keystore2/selinux/Android.bp
+++ b/keystore2/selinux/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 rust_library {
     name: "libkeystore2_selinux",
     crate_name: "keystore2_selinux",
diff --git a/keystore2/src/crypto/Android.bp b/keystore2/src/crypto/Android.bp
index 9ecd823..e386735 100644
--- a/keystore2/src/crypto/Android.bp
+++ b/keystore2/src/crypto/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 rust_library {
     name: "libkeystore2_crypto_rust",
     crate_name: "keystore2_crypto",
@@ -65,6 +74,7 @@
         "--whitelist-function", "ECPOINTOct2Point",
         "--whitelist-function", "EC_KEY_free",
         "--whitelist-function", "EC_POINT_free",
+        "--whitelist-function", "extractSubjectFromCertificate",
         "--whitelist-type", "EC_KEY",
         "--whitelist-type", "EC_POINT",
         "--whitelist-var", "EC_MAX_BYTES",
diff --git a/keystore2/src/crypto/crypto.cpp b/keystore2/src/crypto/crypto.cpp
index 3cc19c5..2e613fd 100644
--- a/keystore2/src/crypto/crypto.cpp
+++ b/keystore2/src/crypto/crypto.cpp
@@ -26,6 +26,7 @@
 #include <openssl/evp.h>
 #include <openssl/hkdf.h>
 #include <openssl/rand.h>
+#include <openssl/x509.h>
 
 #include <vector>
 
@@ -261,3 +262,42 @@
     }
     return point;
 }
+
+int extractSubjectFromCertificate(const uint8_t* cert_buf, size_t cert_len, uint8_t* subject_buf,
+                                  size_t subject_buf_len) {
+    if (!cert_buf || !subject_buf) {
+        ALOGE("extractSubjectFromCertificate: received null pointer");
+        return 0;
+    }
+
+    const uint8_t* p = cert_buf;
+    bssl::UniquePtr<X509> cert(d2i_X509(nullptr /* Allocate X509 struct */, &p, cert_len));
+    if (!cert) {
+        ALOGE("extractSubjectFromCertificate: failed to parse certificate");
+        return 0;
+    }
+
+    X509_NAME* subject = X509_get_subject_name(cert.get());
+    if (!subject) {
+        ALOGE("extractSubjectFromCertificate: failed to retrieve subject name");
+        return 0;
+    }
+
+    int subject_len = i2d_X509_NAME(subject, nullptr /* Don't copy the data */);
+    if (subject_len < 0) {
+        ALOGE("extractSubjectFromCertificate: error obtaining encoded subject name length");
+        return 0;
+    }
+
+    if (subject_len > subject_buf_len) {
+        // Return the subject length, negated, so the caller knows how much
+        // buffer space is required.
+        ALOGI("extractSubjectFromCertificate: needed %d bytes for subject, caller provided %zu",
+              subject_len, subject_buf_len);
+        return -subject_len;
+    }
+
+    // subject_buf has enough space.
+    uint8_t* tmp = subject_buf;
+    return i2d_X509_NAME(subject, &tmp);
+}
diff --git a/keystore2/src/crypto/crypto.hpp b/keystore2/src/crypto/crypto.hpp
index 9bd7758..1b8971f 100644
--- a/keystore2/src/crypto/crypto.hpp
+++ b/keystore2/src/crypto/crypto.hpp
@@ -60,6 +60,29 @@
   size_t ECPOINTPoint2Oct(const EC_POINT *point, uint8_t *buf, size_t len);
 
   EC_POINT* ECPOINTOct2Point(const uint8_t *buf, size_t len);
+
 }
 
+// Parse a DER-encoded X.509 certificate contained in cert_buf, with length
+// cert_len, extract the subject, DER-encode it and write the result to
+// subject_buf, which has subject_buf_len capacity.
+//
+// Because the length of the issuer is unknown, and becaue we'd like to (a) be
+// able to handle subjects of any size and (b) avoid parsing the certificate
+// twice most of the time, once to discover the length and once to parse it, the
+// return value is overloaded.
+//
+// If the return value > 0 it specifies the number of bytes written into
+// subject_buf; the operation was successful.
+//
+// If the return value == 0, certificate parsing failed unrecoverably.  The
+// reason will be logged.
+//
+// If the return value < 0, the operation failed because the subject size >
+// subject_buf_len.  The return value is -(subject_size), where subject_size is
+// the size of the extracted DER-encoded subject field.  Call
+// extractSubjectFromCertificate again with a sufficiently-large buffer.
+int extractSubjectFromCertificate(const uint8_t* cert_buf, size_t cert_len,
+                                  uint8_t* subject_buf, size_t subject_buf_len);
+
 #endif  //  __CRYPTO_H__
diff --git a/keystore2/src/crypto/error.rs b/keystore2/src/crypto/error.rs
index 1e84fc6..1eec321 100644
--- a/keystore2/src/crypto/error.rs
+++ b/keystore2/src/crypto/error.rs
@@ -85,4 +85,8 @@
     /// This is returned if the C implementation of ECPOINTOct2Point returned null.
     #[error("Failed to convert oct to point.")]
     ECOct2PointFailed,
+
+    /// This is returned if the C implementation of extractSubjectFromCertificate failed.
+    #[error("Failed to extract certificate subject.")]
+    ExtractSubjectFailed,
 }
diff --git a/keystore2/src/crypto/lib.rs b/keystore2/src/crypto/lib.rs
index 92b257c..f23778c 100644
--- a/keystore2/src/crypto/lib.rs
+++ b/keystore2/src/crypto/lib.rs
@@ -19,11 +19,12 @@
 mod zvec;
 pub use error::Error;
 use keystore2_crypto_bindgen::{
-    generateKeyFromPassword, randomBytes, AES_gcm_decrypt, AES_gcm_encrypt, ECDHComputeKey,
-    ECKEYDeriveFromSecret, ECKEYGenerateKey, ECPOINTOct2Point, ECPOINTPoint2Oct, EC_KEY_free,
-    EC_KEY_get0_public_key, EC_POINT_free, HKDFExpand, HKDFExtract, EC_KEY, EC_MAX_BYTES, EC_POINT,
-    EVP_MAX_MD_SIZE,
+    extractSubjectFromCertificate, generateKeyFromPassword, randomBytes, AES_gcm_decrypt,
+    AES_gcm_encrypt, ECDHComputeKey, ECKEYDeriveFromSecret, ECKEYGenerateKey, ECPOINTOct2Point,
+    ECPOINTPoint2Oct, EC_KEY_free, EC_KEY_get0_public_key, EC_POINT_free, HKDFExpand, HKDFExtract,
+    EC_KEY, EC_MAX_BYTES, EC_POINT, EVP_MAX_MD_SIZE,
 };
+use std::convert::TryFrom;
 use std::convert::TryInto;
 use std::marker::PhantomData;
 pub use zvec::ZVec;
@@ -353,6 +354,59 @@
     Ok(OwnedECPoint(result))
 }
 
+/// Uses BoringSSL to extract the DER-encoded issuer subject from a
+/// DER-encoded X.509 certificate.
+pub fn parse_issuer_subject_from_certificate(cert_buf: &[u8]) -> Result<Vec<u8>, Error> {
+    // Try with a 200-byte output buffer, should be enough in all but bizarre cases.
+    let mut retval = vec![0; 200];
+    let mut size = unsafe {
+        extractSubjectFromCertificate(
+            cert_buf.as_ptr(),
+            cert_buf.len(),
+            retval.as_mut_ptr(),
+            retval.len(),
+        )
+    };
+
+    if size == 0 {
+        return Err(Error::ExtractSubjectFailed);
+    }
+
+    if size < 0 {
+        // Our buffer wasn't big enough.  Make one that is just the right size and try again.
+        let negated_size = usize::try_from(-size);
+        retval = match negated_size.ok() {
+            None => return Err(Error::ExtractSubjectFailed),
+            Some(size) => vec![0; size],
+        };
+
+        size = unsafe {
+            extractSubjectFromCertificate(
+                cert_buf.as_ptr(),
+                cert_buf.len(),
+                retval.as_mut_ptr(),
+                retval.len(),
+            )
+        };
+
+        if size <= 0 {
+            return Err(Error::ExtractSubjectFailed);
+        }
+    }
+
+    // Reduce buffer size to the amount written.
+    let safe_size = usize::try_from(size);
+    retval.resize(
+        match safe_size.ok() {
+            None => return Err(Error::ExtractSubjectFailed),
+            Some(size) => size,
+        },
+        0,
+    );
+
+    Ok(retval)
+}
+
 #[cfg(test)]
 mod tests {
 
diff --git a/keystore2/src/km_compat/Android.bp b/keystore2/src/km_compat/Android.bp
index 2180935..fa214a7 100644
--- a/keystore2/src/km_compat/Android.bp
+++ b/keystore2/src/km_compat/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 rust_library {
     name: "libkeystore2_km_compat",
     crate_name: "keystore2_km_compat",
diff --git a/keystore2/src/km_compat/certificate_test.cpp b/keystore2/src/km_compat/certificate_test.cpp
index d6bece7..de1d60a 100644
--- a/keystore2/src/km_compat/certificate_test.cpp
+++ b/keystore2/src/km_compat/certificate_test.cpp
@@ -50,7 +50,7 @@
         return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
     }
     KeyCreationResult creationResult;
-    auto status = device->generateKey(keyParams, &creationResult);
+    auto status = device->generateKey(keyParams, std::nullopt /* attest_key */, &creationResult);
     if (!status.isOk()) {
         return status;
     }
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index dedca6d..812f513 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -333,8 +333,10 @@
     return convertErrorCode(result);
 }
 
-ScopedAStatus KeyMintDevice::generateKey(const std::vector<KeyParameter>& inKeyParams,
-                                         KeyCreationResult* out_creationResult) {
+ScopedAStatus
+KeyMintDevice::generateKey(const std::vector<KeyParameter>& inKeyParams,
+                           const std::optional<AttestationKey>& /* in_attestationKey */,
+                           KeyCreationResult* out_creationResult) {
     auto legacyKeyGenParams = convertKeyParametersToLegacy(extractGenerationParams(inKeyParams));
     KMV1::ErrorCode errorCode;
     auto result = mDevice->generateKey(
@@ -368,6 +370,7 @@
 ScopedAStatus KeyMintDevice::importKey(const std::vector<KeyParameter>& inKeyParams,
                                        KeyFormat in_inKeyFormat,
                                        const std::vector<uint8_t>& in_inKeyData,
+                                       const std::optional<AttestationKey>& /* in_attestationKey */,
                                        KeyCreationResult* out_creationResult) {
     auto legacyKeyGENParams = convertKeyParametersToLegacy(extractGenerationParams(inKeyParams));
     auto legacyKeyFormat = convertKeyFormatToLegacy(in_inKeyFormat);
@@ -401,11 +404,13 @@
     return convertErrorCode(errorCode);
 }
 
-ScopedAStatus KeyMintDevice::importWrappedKey(
-    const std::vector<uint8_t>& in_inWrappedKeyData,
-    const std::vector<uint8_t>& in_inWrappingKeyBlob, const std::vector<uint8_t>& in_inMaskingKey,
-    const std::vector<KeyParameter>& in_inUnwrappingParams, int64_t in_inPasswordSid,
-    int64_t in_inBiometricSid, KeyCreationResult* out_creationResult) {
+ScopedAStatus
+KeyMintDevice::importWrappedKey(const std::vector<uint8_t>& in_inWrappedKeyData,
+                                const std::vector<uint8_t>& in_inWrappingKeyBlob,  //
+                                const std::vector<uint8_t>& in_inMaskingKey,
+                                const std::vector<KeyParameter>& in_inUnwrappingParams,
+                                int64_t in_inPasswordSid, int64_t in_inBiometricSid,
+                                KeyCreationResult* out_creationResult) {
     auto legacyUnwrappingParams = convertKeyParametersToLegacy(in_inUnwrappingParams);
     KMV1::ErrorCode errorCode;
     auto result = mDevice->importWrappedKey(
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index 7abccde..57a7bbd 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -28,6 +28,7 @@
 
 #include "certificate_utils.h"
 
+using ::aidl::android::hardware::security::keymint::AttestationKey;
 using ::aidl::android::hardware::security::keymint::BeginResult;
 using ::aidl::android::hardware::security::keymint::ByteArray;
 using ::aidl::android::hardware::security::keymint::Certificate;
@@ -90,9 +91,11 @@
     ScopedAStatus getHardwareInfo(KeyMintHardwareInfo* _aidl_return) override;
     ScopedAStatus addRngEntropy(const std::vector<uint8_t>& in_data) override;
     ScopedAStatus generateKey(const std::vector<KeyParameter>& in_keyParams,
+                              const std::optional<AttestationKey>& in_attestationKey,
                               KeyCreationResult* out_creationResult) override;
     ScopedAStatus importKey(const std::vector<KeyParameter>& in_inKeyParams,
                             KeyFormat in_inKeyFormat, const std::vector<uint8_t>& in_inKeyData,
+                            const std::optional<AttestationKey>& in_attestationKey,
                             KeyCreationResult* out_creationResult) override;
     ScopedAStatus importWrappedKey(const std::vector<uint8_t>& in_inWrappedKeyData,
                                    const std::vector<uint8_t>& in_inWrappingKeyBlob,
diff --git a/keystore2/src/km_compat/lib.rs b/keystore2/src/km_compat/lib.rs
index eca0a85..9be329f 100644
--- a/keystore2/src/km_compat/lib.rs
+++ b/keystore2/src/km_compat/lib.rs
@@ -71,7 +71,8 @@
 
     // TODO: If I only need the key itself, don't return the other things.
     fn generate_key(legacy: &dyn IKeyMintDevice, kps: Vec<KeyParameter>) -> KeyCreationResult {
-        let creation_result = legacy.generateKey(&kps).expect("Failed to generate key");
+        let creation_result =
+            legacy.generateKey(&kps, None /* attest_key */).expect("Failed to generate key");
         assert_ne!(creation_result.keyBlob.len(), 0);
         creation_result
     }
@@ -163,7 +164,8 @@
         }];
         let kf = KeyFormat::RAW;
         let kd = [0; 16];
-        let creation_result = legacy.importKey(&kps, kf, &kd).expect("Failed to import key");
+        let creation_result =
+            legacy.importKey(&kps, kf, &kd, None /* attest_key */).expect("Failed to import key");
         assert_ne!(creation_result.keyBlob.len(), 0);
         assert_eq!(creation_result.certificateChain.len(), 0);
     }
diff --git a/keystore2/src/km_compat/slot_test.cpp b/keystore2/src/km_compat/slot_test.cpp
index 0859ddf..72d944c 100644
--- a/keystore2/src/km_compat/slot_test.cpp
+++ b/keystore2/src/km_compat/slot_test.cpp
@@ -47,7 +47,7 @@
         KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::DECRYPT),
     });
     KeyCreationResult creationResult;
-    auto status = device->generateKey(keyParams, &creationResult);
+    auto status = device->generateKey(keyParams, std::nullopt /* attest_key */, &creationResult);
     if (!status.isOk()) {
         return {};
     }
@@ -150,13 +150,13 @@
         KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED, true),
     });
     KeyCreationResult creationResult;
-    status = device->generateKey(kps, &creationResult);
+    status = device->generateKey(kps, std::nullopt /* attest_key */, &creationResult);
     ASSERT_TRUE(!status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(),
               static_cast<int32_t>(ErrorCode::TOO_MANY_OPERATIONS));
     // But generating a certificate with signCert does not use a slot.
     kps.pop_back();
-    status = device->generateKey(kps, &creationResult);
+    status = device->generateKey(kps, std::nullopt /* attest_key */, &creationResult);
     ASSERT_TRUE(status.isOk());
 
     // Destructing operations should free up their slots.
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index 6b033f1..5e1ce84 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -18,8 +18,9 @@
 
 use crate::globals::get_keymint_device;
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
-    Algorithm::Algorithm, HardwareAuthenticatorType::HardwareAuthenticatorType,
-    IKeyMintDevice::IKeyMintDevice, KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat,
+    Algorithm::Algorithm, AttestationKey::AttestationKey,
+    HardwareAuthenticatorType::HardwareAuthenticatorType, IKeyMintDevice::IKeyMintDevice,
+    KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat,
     KeyMintHardwareInfo::KeyMintHardwareInfo, KeyParameter::KeyParameter,
     KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, Tag::Tag,
 };
@@ -52,6 +53,7 @@
 };
 use anyhow::{anyhow, Context, Result};
 use binder::{IBinder, Strong, ThreadState};
+use keystore2_crypto::parse_issuer_subject_from_certificate;
 
 /// Implementation of the IKeystoreSecurityLevel Interface.
 pub struct KeystoreSecurityLevel {
@@ -379,7 +381,7 @@
     fn generate_key(
         &self,
         key: &KeyDescriptor,
-        attestation_key: Option<&KeyDescriptor>,
+        attest_key_descriptor: Option<&KeyDescriptor>,
         params: &[KeyParameter],
         flags: i32,
         entropy: &[u8],
@@ -403,19 +405,78 @@
         // generate_key requires the rebind permission.
         check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
 
+        let attest_key = match attest_key_descriptor {
+            None => None,
+            Some(key) => Some(
+                self.get_attest_key(key, caller_uid)
+                    .context("In generate_key: Trying to load attest key")?,
+            ),
+        };
+
         let params = Self::add_certificate_parameters(caller_uid, params, &key)
             .context("In generate_key: Trying to get aaid.")?;
 
         let km_dev: Strong<dyn IKeyMintDevice> = self.keymint.get_interface()?;
         map_km_error(km_dev.addRngEntropy(entropy))
             .context("In generate_key: Trying to add entropy.")?;
-        let creation_result = map_km_error(km_dev.generateKey(&params))
+        let creation_result = map_km_error(km_dev.generateKey(&params, attest_key.as_ref()))
             .context("In generate_key: While generating Key")?;
 
         let user_id = uid_to_android_user(caller_uid);
         self.store_new_key(key, creation_result, user_id, Some(flags)).context("In generate_key.")
     }
 
+    fn get_attest_key(&self, key: &KeyDescriptor, caller_uid: u32) -> Result<AttestationKey> {
+        let (km_blob, cert) = self
+            .load_attest_key_blob_and_cert(&key, caller_uid)
+            .context("In get_attest_key: Failed to load blob and cert")?;
+
+        let issuer_subject: Vec<u8> = parse_issuer_subject_from_certificate(&cert)
+            .context("In get_attest_key: Failed to parse subject from certificate.")?;
+
+        Ok(AttestationKey {
+            keyBlob: km_blob.to_vec(),
+            attestKeyParams: [].to_vec(),
+            issuerSubjectName: issuer_subject,
+        })
+    }
+
+    fn load_attest_key_blob_and_cert(
+        &self,
+        key: &KeyDescriptor,
+        caller_uid: u32,
+    ) -> Result<(Vec<u8>, Vec<u8>)> {
+        match key.domain {
+            Domain::BLOB => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
+                "In load_attest_key_blob_and_cert: Domain::BLOB attestation keys not supported",
+            ),
+            _ => {
+                let (key_id_guard, mut key_entry) = DB
+                    .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
+                        db.borrow_mut().load_key_entry(
+                            &key,
+                            KeyType::Client,
+                            KeyEntryLoadBits::BOTH,
+                            caller_uid,
+                            |k, av| check_key_permission(KeyPerm::use_(), k, &av),
+                        )
+                    })
+                    .context("In load_attest_key_blob_and_cert: Failed to load key.")?;
+
+                let (blob, _) =
+                    key_entry.take_key_blob_info().ok_or_else(Error::sys).context(concat!(
+                        "In load_attest_key_blob_and_cert: Successfully loaded key entry,",
+                        " but KM blob was missing."
+                    ))?;
+                let cert = key_entry.take_cert().ok_or_else(Error::sys).context(concat!(
+                    "In load_attest_key_blob_and_cert: Successfully loaded key entry,",
+                    " but cert was missing."
+                ))?;
+                Ok((blob, cert))
+            }
+        }
+    }
+
     fn import_key(
         &self,
         key: &KeyDescriptor,
@@ -464,8 +525,9 @@
 
         let km_dev: Strong<dyn IKeyMintDevice> =
             self.keymint.get_interface().context("In import_key: Trying to get the KM device")?;
-        let creation_result = map_km_error(km_dev.importKey(&params, format, key_data))
-            .context("In import_key: Trying to call importKey")?;
+        let creation_result =
+            map_km_error(km_dev.importKey(&params, format, key_data, None /* attestKey */))
+                .context("In import_key: Trying to call importKey")?;
 
         let user_id = uid_to_android_user(caller_uid);
         self.store_new_key(key, creation_result, user_id, Some(flags)).context("In import_key.")
diff --git a/ondevice-signing/Android.bp b/ondevice-signing/Android.bp
index 8da28f2..d47a04f 100644
--- a/ondevice-signing/Android.bp
+++ b/ondevice-signing/Android.bp
@@ -14,6 +14,15 @@
 // List of clang-tidy checks that are reported as errors.
 // Please keep this list ordered lexicographically.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 tidy_errors = [
   "cert-err34-c",
   "google-default-arguments",
diff --git a/provisioner/Android.bp b/provisioner/Android.bp
index c1c8d15..d3f06fe 100644
--- a/provisioner/Android.bp
+++ b/provisioner/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
 aidl_interface {
     name: "android.security.provisioner",
     unstable: true,