Merge "Adding tests using `MAX_USES_PER_BOOT`, `EARLY_BOOT_ONLY`, `BOOTLOADER_ONLY` and `USAGE_COUNT_LIMIT`" into main
diff --git a/identity/Android.bp b/identity/Android.bp
index 007a310..f7a540a 100644
--- a/identity/Android.bp
+++ b/identity/Android.bp
@@ -51,6 +51,7 @@
         "liblog",
         "libutils",
         "libutilscallstack",
+        "libkeystore-attestation-application-id",
     ],
     static_libs: [
         "android.hardware.keymaster-V3-cpp",
@@ -60,7 +61,6 @@
         "libcppbor_external",
         "libcredstore_aidl",
         "libkeymaster4support",
-        "libkeystore-attestation-application-id",
         "librkp_support",
     ],
 }
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 221ead9..c79d00b 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -69,19 +69,16 @@
     defaults: ["keystore_defaults"],
 
     srcs: [
-        ":IKeyAttestationApplicationIdProvider.aidl",
         "keystore_attestation_id.cpp",
-        "KeyAttestationApplicationId.cpp",
-        "KeyAttestationPackageInfo.cpp",
-        "Signature.cpp",
     ],
     shared_libs: [
+        "android.security.aaid_aidl-cpp",
         "libbase",
         "libbinder",
+        "libcrypto",
         "libhidlbase",
         "liblog",
         "libutils",
-        "libcrypto",
     ],
 
     export_include_dirs: ["include"],
diff --git a/keystore/KeyAttestationApplicationId.cpp b/keystore/KeyAttestationApplicationId.cpp
deleted file mode 100644
index 1838b07..0000000
--- a/keystore/KeyAttestationApplicationId.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-**
-** Copyright 2016, 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.
-*/
-
-#include "include/keystore/KeyAttestationApplicationId.h"
-
-#include <binder/Parcel.h>
-
-namespace android {
-namespace security {
-namespace keymaster {
-
-KeyAttestationApplicationId::KeyAttestationApplicationId() = default;
-
-KeyAttestationApplicationId::KeyAttestationApplicationId(
-    std::optional<KeyAttestationPackageInfo> package)
-    : packageInfos_(new std::vector<std::optional<KeyAttestationPackageInfo>>()) {
-    packageInfos_->push_back(std::move(package));
-}
-
-KeyAttestationApplicationId::KeyAttestationApplicationId(PackageInfoVector packages)
-    : packageInfos_(std::make_shared<PackageInfoVector>(std::move(packages))) {}
-
-status_t KeyAttestationApplicationId::writeToParcel(Parcel* parcel) const {
-    return parcel->writeParcelableVector(packageInfos_);
-}
-
-status_t KeyAttestationApplicationId::readFromParcel(const Parcel* parcel) {
-    std::optional<std::vector<std::optional<KeyAttestationPackageInfo>>> temp_vector;
-    auto rc = parcel->readParcelableVector(&temp_vector);
-    if (rc != NO_ERROR) return rc;
-    packageInfos_.reset();
-    if (temp_vector) {
-        packageInfos_ = std::make_shared<PackageInfoVector>(std::move(*temp_vector));
-    }
-    return NO_ERROR;
-}
-
-}  // namespace keymaster
-}  // namespace security
-}  // namespace android
diff --git a/keystore/KeyAttestationPackageInfo.cpp b/keystore/KeyAttestationPackageInfo.cpp
deleted file mode 100644
index 8e9a36a..0000000
--- a/keystore/KeyAttestationPackageInfo.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-**
-** Copyright 2016, 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.
-*/
-
-#include "include/keystore/KeyAttestationPackageInfo.h"
-
-#include <binder/Parcel.h>
-
-namespace android {
-namespace security {
-namespace keymaster {
-
-KeyAttestationPackageInfo::KeyAttestationPackageInfo() = default;
-
-KeyAttestationPackageInfo::KeyAttestationPackageInfo(const String16& packageName,
-                                                     int64_t versionCode,
-                                                     SharedSignaturesVector signatures)
-    : packageName_(packageName), versionCode_(versionCode), signatures_(signatures) {}
-
-status_t KeyAttestationPackageInfo::writeToParcel(Parcel* parcel) const {
-    auto rc = parcel->writeString16(packageName_);
-    if (rc != NO_ERROR) return rc;
-    rc = parcel->writeInt64(versionCode_);
-    if (rc != NO_ERROR) return rc;
-    return parcel->writeParcelableVector(signatures_);
-}
-
-status_t KeyAttestationPackageInfo::readFromParcel(const Parcel* parcel) {
-    auto rc = parcel->readString16(&packageName_);
-    if (rc != NO_ERROR) return rc;
-    rc = parcel->readInt64(&versionCode_);
-    if (rc != NO_ERROR) return rc;
-
-    std::optional<SignaturesVector> temp_vector;
-    rc = parcel->readParcelableVector(&temp_vector);
-    if (rc != NO_ERROR) return rc;
-    signatures_.reset();
-    if (temp_vector) {
-        signatures_ = std::make_shared<SignaturesVector>(std::move(*temp_vector));
-    }
-    return NO_ERROR;
-}
-
-}  // namespace keymaster
-}  // namespace security
-}  // namespace android
diff --git a/keystore/Signature.cpp b/keystore/Signature.cpp
deleted file mode 100644
index 284f358..0000000
--- a/keystore/Signature.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-**
-** Copyright 2016, 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.
-*/
-
-#include "include/keystore/Signature.h"
-
-#include <binder/Parcel.h>
-
-namespace android {
-namespace content {
-namespace pm {
-
-status_t Signature::writeToParcel(Parcel* parcel) const {
-    return parcel->writeByteVector(sig_data_);
-}
-
-status_t Signature::readFromParcel(const Parcel* parcel) {
-    return parcel->readByteVector(&sig_data_);
-}
-
-Signature::Signature(std::vector<uint8_t> signature_data) : sig_data_(std::move(signature_data)) {}
-
-}  // namespace pm
-}  // namespace content
-}  // namespace android
diff --git a/keystore/include/keystore/KeyAttestationApplicationId.h b/keystore/include/keystore/KeyAttestationApplicationId.h
deleted file mode 100644
index 0bf1aad..0000000
--- a/keystore/include/keystore/KeyAttestationApplicationId.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2016 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.
-
-#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
-#define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
-
-#include <memory>
-#include <optional>
-#include <vector>
-
-#include <binder/Parcelable.h>
-
-#include "KeyAttestationPackageInfo.h"
-
-namespace android {
-namespace security {
-namespace keymaster {
-
-class KeyAttestationApplicationId : public Parcelable {
-  public:
-    typedef SharedNullableIterator<const KeyAttestationPackageInfo, std::vector>
-        ConstKeyAttestationPackageInfoIterator;
-    typedef std::vector<std::optional<KeyAttestationPackageInfo>> PackageInfoVector;
-    KeyAttestationApplicationId();
-    // Following c'tors are for initializing instances containing test data.
-    explicit KeyAttestationApplicationId(std::optional<KeyAttestationPackageInfo> package);
-    explicit KeyAttestationApplicationId(PackageInfoVector packages);
-
-    status_t writeToParcel(Parcel*) const override;
-    status_t readFromParcel(const Parcel* parcel) override;
-
-    ConstKeyAttestationPackageInfoIterator pinfos_begin() const {
-        return ConstKeyAttestationPackageInfoIterator(packageInfos_);
-    }
-    ConstKeyAttestationPackageInfoIterator pinfos_end() const {
-        return ConstKeyAttestationPackageInfoIterator();
-    }
-
-  private:
-    std::shared_ptr<PackageInfoVector> packageInfos_;
-};
-
-}  // namespace keymaster
-}  // namespace security
-}  // namespace android
-
-#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
diff --git a/keystore/include/keystore/KeyAttestationPackageInfo.h b/keystore/include/keystore/KeyAttestationPackageInfo.h
deleted file mode 100644
index fa638f9..0000000
--- a/keystore/include/keystore/KeyAttestationPackageInfo.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2016 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.
-
-#ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
-#define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <optional>
-#include <vector>
-
-#include <binder/Parcelable.h>
-
-#include "Signature.h"
-#include "utils.h"
-
-namespace android {
-namespace security {
-namespace keymaster {
-
-class KeyAttestationPackageInfo : public Parcelable {
-  public:
-    typedef SharedNullableIterator<const content::pm::Signature, std::vector>
-        ConstSignatureIterator;
-    typedef std::vector<std::optional<content::pm::Signature>> SignaturesVector;
-    typedef std::shared_ptr<SignaturesVector> SharedSignaturesVector;
-
-    KeyAttestationPackageInfo(const String16& packageName, int64_t versionCode,
-                              SharedSignaturesVector signatures);
-    KeyAttestationPackageInfo();
-
-    status_t writeToParcel(Parcel*) const override;
-    status_t readFromParcel(const Parcel* parcel) override;
-
-    const std::optional<String16>& package_name() const { return packageName_; }
-    int64_t version_code() const { return versionCode_; }
-
-    ConstSignatureIterator sigs_begin() const { return ConstSignatureIterator(signatures_); }
-    ConstSignatureIterator sigs_end() const { return ConstSignatureIterator(); }
-
-  private:
-    std::optional<String16> packageName_;
-    int64_t versionCode_;
-    SharedSignaturesVector signatures_;
-};
-
-}  // namespace keymaster
-}  // namespace security
-}  // namespace android
-
-#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
diff --git a/keystore/include/keystore/Signature.h b/keystore/include/keystore/Signature.h
deleted file mode 100644
index f39acec..0000000
--- a/keystore/include/keystore/Signature.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 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.
-
-#ifndef KEYSTORE_INCLUDE_KEYSTORE_SIGNATURE_H_
-#define KEYSTORE_INCLUDE_KEYSTORE_SIGNATURE_H_
-
-#include <vector>
-
-#include <binder/Parcelable.h>
-
-namespace android {
-namespace content {
-namespace pm {
-
-class Signature : public Parcelable {
-  public:
-    Signature() = default;
-    // Intended for initializing instances containing test data.
-    explicit Signature(std::vector<uint8_t> signature_data);
-
-    status_t writeToParcel(Parcel*) const override;
-    status_t readFromParcel(const Parcel* parcel) override;
-
-    const std::vector<uint8_t>& data() const & { return sig_data_; }
-    std::vector<uint8_t>& data() & { return sig_data_; }
-    std::vector<uint8_t>&& data() && { return std::move(sig_data_); }
-
-  private:
-    std::vector<uint8_t> sig_data_;
-};
-
-}  // namespace pm
-}  // namespace content
-}  // namespace android
-
-#endif  // KEYSTORE_INCLUDE_KEYSTORE_SIGNATURE_H_
diff --git a/keystore/include/keystore/keystore_attestation_id.h b/keystore/include/keystore/keystore_attestation_id.h
index 238f4b1..a0d43ad 100644
--- a/keystore/include/keystore/keystore_attestation_id.h
+++ b/keystore/include/keystore/keystore_attestation_id.h
@@ -25,11 +25,11 @@
 
 constexpr size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
 
-namespace keymaster {
+namespace keystore {
 
 class KeyAttestationApplicationId;
 
-}  // namespace keymaster
+}  // namespace keystore
 
 template <typename T> class StatusOr {
   public:
@@ -77,7 +77,7 @@
  */
 
 StatusOr<std::vector<uint8_t>> build_attestation_application_id(
-    const ::android::security::keymaster::KeyAttestationApplicationId& key_attestation_id);
+    const ::android::security::keystore::KeyAttestationApplicationId& key_attestation_id);
 
 }  // namespace security
 }  // namespace android
diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
index 8eade97..1534be1 100644
--- a/keystore/keystore_attestation_id.cpp
+++ b/keystore/keystore_attestation_id.cpp
@@ -29,11 +29,11 @@
 #include <binder/Parcelable.h>
 #include <binder/PersistableBundle.h>
 
-#include <android/security/keymaster/BpKeyAttestationApplicationIdProvider.h>
-#include <android/security/keymaster/IKeyAttestationApplicationIdProvider.h>
-#include <keystore/KeyAttestationApplicationId.h>
-#include <keystore/KeyAttestationPackageInfo.h>
-#include <keystore/Signature.h>
+#include <android/security/keystore/BpKeyAttestationApplicationIdProvider.h>
+#include <android/security/keystore/IKeyAttestationApplicationIdProvider.h>
+#include <android/security/keystore/KeyAttestationApplicationId.h>
+#include <android/security/keystore/KeyAttestationPackageInfo.h>
+#include <android/security/keystore/Signature.h>
 
 #include <private/android_filesystem_config.h> /* for AID_SYSTEM */
 
@@ -50,13 +50,13 @@
 constexpr const char* kAttestationSystemPackageName = "AndroidSystem";
 constexpr const char* kUnknownPackageName = "UnknownPackage";
 
-std::vector<uint8_t> signature2SHA256(const content::pm::Signature& sig) {
+std::vector<uint8_t> signature2SHA256(const security::keystore::Signature& sig) {
     std::vector<uint8_t> digest_buffer(SHA256_DIGEST_LENGTH);
-    SHA256(sig.data().data(), sig.data().size(), digest_buffer.data());
+    SHA256(sig.data.data(), sig.data.size(), digest_buffer.data());
     return digest_buffer;
 }
 
-using ::android::security::keymaster::BpKeyAttestationApplicationIdProvider;
+using ::android::security::keystore::BpKeyAttestationApplicationIdProvider;
 
 class KeyAttestationApplicationIdProvider : public BpKeyAttestationApplicationIdProvider {
   public:
@@ -141,8 +141,8 @@
 namespace security {
 namespace {
 
-using ::android::security::keymaster::KeyAttestationApplicationId;
-using ::android::security::keymaster::KeyAttestationPackageInfo;
+using ::android::security::keystore::KeyAttestationApplicationId;
+using ::android::security::keystore::KeyAttestationPackageInfo;
 
 status_t build_attestation_package_info(const KeyAttestationPackageInfo& pinfo,
     std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO>* attestation_package_info_ptr) {
@@ -153,12 +153,12 @@
     attestation_package_info.reset(KM_ATTESTATION_PACKAGE_INFO_new());
     if (!attestation_package_info.get()) return NO_MEMORY;
 
-    if (!pinfo.package_name()) {
+    if (!pinfo.packageName) {
         ALOGE("Key attestation package info lacks package name");
         return BAD_VALUE;
     }
 
-    std::string pkg_name(String8(*pinfo.package_name()).c_str());
+    std::string pkg_name(String8(pinfo.packageName).c_str());
     if (!ASN1_OCTET_STRING_set(attestation_package_info->package_name,
                                reinterpret_cast<const unsigned char*>(pkg_name.data()),
                                pkg_name.size())) {
@@ -169,7 +169,7 @@
     if (bn_version == nullptr) {
         return NO_MEMORY;
     }
-    if (BN_set_u64(bn_version, static_cast<uint64_t>(pinfo.version_code())) != 1) {
+    if (BN_set_u64(bn_version, static_cast<uint64_t>(pinfo.versionCode)) != 1) {
         BN_free(bn_version);
         return UNKNOWN_ERROR;
     }
@@ -201,15 +201,16 @@
 
     auto attestation_pinfo_stack = reinterpret_cast<_STACK*>(attestation_id->package_infos);
 
-    if (key_attestation_id.pinfos_begin() == key_attestation_id.pinfos_end()) return BAD_VALUE;
+    if (key_attestation_id.packageInfos.begin() == key_attestation_id.packageInfos.end())
+        return BAD_VALUE;
 
-    for (auto pinfo = key_attestation_id.pinfos_begin(); pinfo != key_attestation_id.pinfos_end();
-         ++pinfo) {
-        if (!pinfo->package_name()) {
+    for (auto pinfo = key_attestation_id.packageInfos.begin();
+         pinfo != key_attestation_id.packageInfos.end(); ++pinfo) {
+        if (!pinfo->packageName) {
             ALOGE("Key attestation package info lacks package name");
             return BAD_VALUE;
         }
-        std::string package_name(String8(*pinfo->package_name()).c_str());
+        std::string package_name(String8(pinfo->packageName).c_str());
         std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO> attestation_package_info;
         auto rc = build_attestation_package_info(*pinfo, &attestation_package_info);
         if (rc != NO_ERROR) {
@@ -231,10 +232,10 @@
      *  signature field actually holds the signing certificate, rather than a signature, we can
      *  simply use the set of signature digests of the first package info.
      */
-    const auto& pinfo = *key_attestation_id.pinfos_begin();
+    const auto& pinfo = *key_attestation_id.packageInfos.begin();
     std::vector<std::vector<uint8_t>> signature_digests;
 
-    for (auto sig = pinfo.sigs_begin(); sig != pinfo.sigs_end(); ++sig) {
+    for (auto sig = pinfo.signatures.begin(); sig != pinfo.signatures.end(); ++sig) {
         signature_digests.push_back(signature2SHA256(*sig));
     }
 
@@ -271,10 +272,10 @@
 
     if (uid == AID_SYSTEM) {
         /* Use a fixed ID for system callers */
-        auto pinfo = std::make_optional<KeyAttestationPackageInfo>(
-            String16(kAttestationSystemPackageName), 1 /* version code */,
-            std::make_shared<KeyAttestationPackageInfo::SignaturesVector>());
-        key_attestation_id = KeyAttestationApplicationId(std::move(pinfo));
+        auto pinfo = KeyAttestationPackageInfo();
+        pinfo.packageName = String16(kAttestationSystemPackageName);
+        pinfo.versionCode = 1;
+        key_attestation_id.packageInfos.push_back(std::move(pinfo));
     } else {
         /* Get the attestation application ID from package manager */
         auto& pm = KeyAttestationApplicationIdProvider::get();
@@ -284,10 +285,11 @@
         if (!status.isOk()) {
             ALOGW("package manager request for key attestation ID failed with: %s %d",
                   status.exceptionMessage().c_str(), status.exceptionCode());
-            auto pinfo = std::make_optional<KeyAttestationPackageInfo>(
-                String16(kUnknownPackageName), 1 /* version code */,
-                std::make_shared<KeyAttestationPackageInfo::SignaturesVector>());
-            key_attestation_id = KeyAttestationApplicationId(std::move(pinfo));
+
+            auto pinfo = KeyAttestationPackageInfo();
+            pinfo.packageName = String16(kUnknownPackageName);
+            pinfo.versionCode = 1;
+            key_attestation_id.packageInfos.push_back(std::move(pinfo));
         }
     }
 
diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp
index f51cc2f..e641f44 100644
--- a/keystore/tests/Android.bp
+++ b/keystore/tests/Android.bp
@@ -35,6 +35,7 @@
         "libutils",
     ],
     shared_libs: [
+        "android.security.aaid_aidl-cpp",
         "libbinder",
         "libkeymaster_messages",
         "libkeystore-attestation-application-id",
diff --git a/keystore/tests/aaid_truncation_test.cpp b/keystore/tests/aaid_truncation_test.cpp
index fa4d769..3a94ec1 100644
--- a/keystore/tests/aaid_truncation_test.cpp
+++ b/keystore/tests/aaid_truncation_test.cpp
@@ -22,14 +22,14 @@
 #include <keymaster/logger.h>
 #include <keystore/keystore_attestation_id.h>
 
-#include <keystore/KeyAttestationApplicationId.h>
-#include <keystore/KeyAttestationPackageInfo.h>
-#include <keystore/Signature.h>
+#include <android/security/keystore/KeyAttestationApplicationId.h>
+#include <android/security/keystore/KeyAttestationPackageInfo.h>
+#include <android/security/keystore/Signature.h>
 
 using ::android::String16;
 using ::android::security::KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE;
-using ::android::security::keymaster::KeyAttestationApplicationId;
-using ::android::security::keymaster::KeyAttestationPackageInfo;
+using ::android::security::keystore::KeyAttestationApplicationId;
+using ::android::security::keystore::KeyAttestationPackageInfo;
 using std::vector;
 
 namespace keystore {
@@ -72,24 +72,27 @@
 
 }  // namespace
 
-using ::android::content::pm::Signature;
 using ::android::security::build_attestation_application_id;
+using ::android::security::keystore::Signature;
 
-std::optional<KeyAttestationPackageInfo>
-make_package_info_with_signatures(const char* package_name,
-                                  KeyAttestationPackageInfo::SignaturesVector signatures) {
-    return std::make_optional<KeyAttestationPackageInfo>(
-        String16(package_name), 1 /* version code */,
-        std::make_shared<KeyAttestationPackageInfo::SignaturesVector>(std::move(signatures)));
+KeyAttestationPackageInfo make_package_info_with_signatures(const char* package_name,
+                                                            std::vector<Signature> signatures) {
+    auto pInfo = KeyAttestationPackageInfo();
+    pInfo.packageName = String16(package_name);
+    pInfo.versionCode = 1;
+    std::move(signatures.begin(), signatures.end(), std::back_inserter(pInfo.signatures));
+
+    return pInfo;
 }
 
-std::optional<KeyAttestationPackageInfo> make_package_info(const char* package_name) {
-    return make_package_info_with_signatures(package_name,
-                                             KeyAttestationPackageInfo::SignaturesVector());
+KeyAttestationPackageInfo make_package_info(const char* package_name) {
+    return make_package_info_with_signatures(package_name, std::vector<Signature>());
 }
 
 TEST(AaidTruncationTest, shortPackageInfoTest) {
-    KeyAttestationApplicationId app_id(make_package_info(kDummyPackageName));
+    KeyAttestationApplicationId app_id;
+    auto pInfo = make_package_info(kDummyPackageName);
+    app_id.packageInfos.push_back(std::move(pInfo));
 
     auto result = build_attestation_application_id(app_id);
     ASSERT_TRUE(result.isOk());
@@ -98,7 +101,9 @@
 }
 
 TEST(AaidTruncationTest, tooLongPackageNameTest) {
-    KeyAttestationApplicationId app_id(make_package_info(kLongPackageName));
+    KeyAttestationApplicationId app_id;
+    auto pInfo = make_package_info(kLongPackageName);
+    app_id.packageInfos.push_back(std::move(pInfo));
 
     auto result = build_attestation_application_id(app_id);
     ASSERT_TRUE(result.isOk());
@@ -108,14 +113,17 @@
 
 TEST(AaidTruncationTest, tooManySignaturesTest) {
     std::vector<uint8_t> dummy_sig_data(kDummySignature, kDummySignature + 32);
-    KeyAttestationPackageInfo::SignaturesVector signatures;
+    std::vector<Signature> signatures;
     // Add 35 signatures which will surely exceed the 1K limit.
     for (size_t i = 0; i < kTooManySignatures; ++i) {
-        signatures.push_back(std::make_optional<Signature>(dummy_sig_data));
+        auto sign = Signature();
+        sign.data = dummy_sig_data;
+        signatures.push_back(std::move(sign));
     }
 
-    KeyAttestationApplicationId app_id(
-        make_package_info_with_signatures(kDummyPackageName, std::move(signatures)));
+    auto pInfo = make_package_info_with_signatures(kDummyPackageName, std::move(signatures));
+    KeyAttestationApplicationId app_id;
+    app_id.packageInfos.push_back(std::move(pInfo));
 
     auto result = build_attestation_application_id(app_id);
     ASSERT_TRUE(result.isOk());
@@ -125,19 +133,22 @@
 
 TEST(AaidTruncationTest, combinedPackagesAndSignaturesTest) {
     std::vector<uint8_t> dummy_sig_data(kDummySignature, kDummySignature + 32);
-    KeyAttestationApplicationId::PackageInfoVector packages;
+    ::std::vector<KeyAttestationPackageInfo> packages;
 
     for (size_t i = 0; i < kTooManyPackages; ++i) {
-        KeyAttestationPackageInfo::SignaturesVector signatures;
+        std::vector<Signature> signatures;
         // Add a few signatures for each package
         for (int j = 0; j < 3; ++j) {
-            signatures.push_back(std::make_optional<Signature>(dummy_sig_data));
+            auto sign = Signature();
+            sign.data = dummy_sig_data;
+            signatures.push_back(std::move(sign));
         }
-        packages.push_back(
-            make_package_info_with_signatures(kReasonablePackageName, std::move(signatures)));
+        packages.push_back(std::move(
+            make_package_info_with_signatures(kReasonablePackageName, std::move(signatures))));
     }
+    KeyAttestationApplicationId app_id;
+    std::move(packages.begin(), packages.end(), std::back_inserter(app_id.packageInfos));
 
-    KeyAttestationApplicationId app_id(std::move(packages));
     auto result = build_attestation_application_id(app_id);
     ASSERT_TRUE(result.isOk());
     std::vector<uint8_t>& encoded_app_id = result;
diff --git a/keystore/tests/fuzzer/Android.bp b/keystore/tests/fuzzer/Android.bp
index 4116ae1..5df5c7a 100644
--- a/keystore/tests/fuzzer/Android.bp
+++ b/keystore/tests/fuzzer/Android.bp
@@ -55,6 +55,7 @@
         "libhidlbase",
     ],
     shared_libs: [
+        "android.security.aaid_aidl-cpp",
         "libbinder",
         "libcrypto",
         "libutils",
diff --git a/keystore/tests/fuzzer/keystoreApplicationId_fuzzer.cpp b/keystore/tests/fuzzer/keystoreApplicationId_fuzzer.cpp
index 0eddb9a..9388001 100644
--- a/keystore/tests/fuzzer/keystoreApplicationId_fuzzer.cpp
+++ b/keystore/tests/fuzzer/keystoreApplicationId_fuzzer.cpp
@@ -15,9 +15,9 @@
  */
 
 #include "keystoreCommon.h"
-#include <keystore/KeyAttestationApplicationId.h>
+#include <android/security/keystore/KeyAttestationApplicationId.h>
 
-using ::security::keymaster::KeyAttestationApplicationId;
+using ::android::security::keystore::KeyAttestationApplicationId;
 
 constexpr size_t kPackageVectorSizeMin = 1;
 constexpr size_t kPackageVectorSizeMax = 10;
@@ -33,26 +33,37 @@
 };
 
 void KeystoreApplicationId::invokeApplicationId() {
-    std::optional<KeyAttestationApplicationId> applicationId;
+    KeyAttestationApplicationId applicationId;
     bool shouldUsePackageInfoVector = mFdp->ConsumeBool();
     if (shouldUsePackageInfoVector) {
-        KeyAttestationApplicationId::PackageInfoVector packageInfoVector;
+        ::std::vector<KeyAttestationPackageInfo> packageInfoVector;
         int32_t packageVectorSize =
             mFdp->ConsumeIntegralInRange<int32_t>(kPackageVectorSizeMin, kPackageVectorSizeMax);
         for (int32_t packageSize = 0; packageSize < packageVectorSize; ++packageSize) {
             auto packageInfoData = initPackageInfoData(mFdp.get());
-            packageInfoVector.push_back(make_optional<KeyAttestationPackageInfo>(
-                String16((packageInfoData.packageName).c_str()), packageInfoData.versionCode,
-                packageInfoData.sharedSignaturesVector));
+            auto pInfo = KeyAttestationPackageInfo();
+            pInfo.packageName = String16((packageInfoData.packageName).c_str());
+            pInfo.versionCode = packageInfoData.versionCode;
+            std::move(packageInfoData.sharedSignaturesVector->begin(),
+                      packageInfoData.sharedSignaturesVector->end(),
+                      std::back_inserter(pInfo.signatures));
+
+            packageInfoVector.push_back(std::move(pInfo));
         }
-        applicationId = KeyAttestationApplicationId(std::move(packageInfoVector));
+
+        std::move(packageInfoVector.begin(), packageInfoVector.end(),
+                  std::back_inserter(applicationId.packageInfos));
     } else {
         auto packageInfoData = initPackageInfoData(mFdp.get());
-        applicationId = KeyAttestationApplicationId(make_optional<KeyAttestationPackageInfo>(
-            String16((packageInfoData.packageName).c_str()), packageInfoData.versionCode,
-            packageInfoData.sharedSignaturesVector));
+        auto pInfo = KeyAttestationPackageInfo();
+        pInfo.packageName = String16((packageInfoData.packageName).c_str());
+        pInfo.versionCode = packageInfoData.versionCode;
+        std::move(packageInfoData.sharedSignaturesVector->begin(),
+                  packageInfoData.sharedSignaturesVector->end(),
+                  std::back_inserter(pInfo.signatures));
+        applicationId.packageInfos.push_back(std::move(pInfo));
     }
-    invokeReadWriteParcel(&applicationId.value());
+    invokeReadWriteParcel(&applicationId);
 }
 
 void KeystoreApplicationId::process(const uint8_t* data, size_t size) {
diff --git a/keystore/tests/fuzzer/keystoreCommon.h b/keystore/tests/fuzzer/keystoreCommon.h
index e1265bf..77d39e0 100644
--- a/keystore/tests/fuzzer/keystoreCommon.h
+++ b/keystore/tests/fuzzer/keystoreCommon.h
@@ -16,18 +16,18 @@
 #ifndef KEYSTORECOMMON_H
 #define KEYSTORECOMMON_H
 
+#include <android/security/keystore/KeyAttestationPackageInfo.h>
+#include <android/security/keystore/Signature.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
-#include <keystore/KeyAttestationPackageInfo.h>
-#include <keystore/Signature.h>
 #include <vector>
 
 #include "fuzzer/FuzzedDataProvider.h"
 
 using namespace android;
 using namespace std;
-using ::content::pm::Signature;
-using ::security::keymaster::KeyAttestationPackageInfo;
+using ::android::security::keystore::KeyAttestationPackageInfo;
+using ::android::security::keystore::Signature;
 
 constexpr size_t kSignatureSizeMin = 1;
 constexpr size_t kSignatureSizeMax = 1000;
@@ -38,7 +38,7 @@
 struct PackageInfoData {
     string packageName;
     int64_t versionCode;
-    KeyAttestationPackageInfo::SharedSignaturesVector sharedSignaturesVector;
+    std::shared_ptr<std::vector<Signature>> sharedSignaturesVector;
 };
 
 inline void invokeReadWriteParcel(Parcelable* obj) {
@@ -60,18 +60,20 @@
     packageInfoData.versionCode = fdp->ConsumeIntegral<int64_t>();
     size_t signatureVectorSize =
         fdp->ConsumeIntegralInRange(kSignatureVectorSizeMin, kSignatureVectorSizeMax);
-    KeyAttestationPackageInfo::SignaturesVector signatureVector;
+    std::vector<Signature> signatureVector;
     for (size_t size = 0; size < signatureVectorSize; ++size) {
         bool shouldUseParameterizedConstructor = fdp->ConsumeBool();
         if (shouldUseParameterizedConstructor) {
             vector<uint8_t> signatureData = initSignatureData(fdp);
-            signatureVector.push_back(make_optional<Signature>(signatureData));
+            auto sign = Signature();
+            sign.data = signatureData;
+            signatureVector.push_back(std::move(sign));
         } else {
-            signatureVector.push_back(std::nullopt);
+            signatureVector.push_back(Signature());
         }
     }
     packageInfoData.sharedSignaturesVector =
-        make_shared<KeyAttestationPackageInfo::SignaturesVector>(std::move(signatureVector));
+        make_shared<std::vector<Signature>>(std::move(signatureVector));
     return packageInfoData;
 }
 #endif  // KEYSTORECOMMON_H
diff --git a/keystore/tests/fuzzer/keystorePackageInfo_fuzzer.cpp b/keystore/tests/fuzzer/keystorePackageInfo_fuzzer.cpp
index 63899ff..f1e4204 100644
--- a/keystore/tests/fuzzer/keystorePackageInfo_fuzzer.cpp
+++ b/keystore/tests/fuzzer/keystorePackageInfo_fuzzer.cpp
@@ -28,9 +28,12 @@
 
 void KeystorePackageInfoFuzzer::invokePackageInfo() {
     auto packageInfoData = initPackageInfoData(mFdp.get());
-    KeyAttestationPackageInfo packageInfo(String16((packageInfoData.packageName).c_str()),
-                                          packageInfoData.versionCode,
-                                          packageInfoData.sharedSignaturesVector);
+    auto packageInfo = KeyAttestationPackageInfo();
+    packageInfo.packageName = String16((packageInfoData.packageName).c_str());
+    packageInfo.versionCode = packageInfoData.versionCode;
+    std::move(packageInfoData.sharedSignaturesVector->begin(),
+              packageInfoData.sharedSignaturesVector->end(),
+              std::back_inserter(packageInfo.signatures));
     invokeReadWriteParcel(&packageInfo);
 }
 
diff --git a/keystore/tests/fuzzer/keystoreSignature_fuzzer.cpp b/keystore/tests/fuzzer/keystoreSignature_fuzzer.cpp
index b8f8a73..aab1f25 100644
--- a/keystore/tests/fuzzer/keystoreSignature_fuzzer.cpp
+++ b/keystore/tests/fuzzer/keystoreSignature_fuzzer.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 #include "keystoreCommon.h"
-#include <keystore/Signature.h>
+#include <android/security/keystore/Signature.h>
+
+using ::android::security::keystore::Signature;
 
 class KeystoreSignatureFuzzer {
   public:
@@ -27,15 +29,15 @@
 };
 
 void KeystoreSignatureFuzzer::invokeSignature() {
-    std::optional<Signature> signature;
+    Signature signature;
     bool shouldUseParameterizedConstructor = mFdp->ConsumeBool();
     if (shouldUseParameterizedConstructor) {
         std::vector<uint8_t> signatureData = initSignatureData(mFdp.get());
-        signature = Signature(signatureData);
+        signature.data = signatureData;
     } else {
         signature = Signature();
     }
-    invokeReadWriteParcel(&signature.value());
+    invokeReadWriteParcel(&signature);
 }
 
 void KeystoreSignatureFuzzer::process(const uint8_t* data, size_t size) {
diff --git a/keystore2/src/km_compat.rs b/keystore2/src/km_compat.rs
index 035edd9..8eba02d 100644
--- a/keystore2/src/km_compat.rs
+++ b/keystore2/src/km_compat.rs
@@ -32,6 +32,11 @@
 use anyhow::Context;
 use keystore2_crypto::{hmac_sha256, HMAC_SHA256_LEN};
 
+/// Magic prefix used by the km_compat C++ code to mark a key that is owned by an
+/// underlying Keymaster hardware device that has been wrapped by km_compat. (The
+/// final zero byte indicates that the blob is not software emulated.)
+pub const KEYMASTER_BLOB_HW_PREFIX: &[u8] = b"pKMblob\x00";
+
 /// Key data associated with key generation/import.
 #[derive(Debug, PartialEq, Eq)]
 pub enum KeyImportData<'a> {
diff --git a/keystore2/src/legacy_importer.rs b/keystore2/src/legacy_importer.rs
index 325c213..159e936 100644
--- a/keystore2/src/legacy_importer.rs
+++ b/keystore2/src/legacy_importer.rs
@@ -914,11 +914,12 @@
     uuid: &Uuid,
     blob: &[u8],
 ) -> Result<(Vec<KeyParameter>, Option<Vec<u8>>)> {
-    let (km_dev, _) = crate::globals::get_keymint_dev_by_uuid(uuid)
+    let (km_dev, info) = crate::globals::get_keymint_dev_by_uuid(uuid)
         .with_context(|| ks_err!("Trying to get km device for id {:?}", uuid))?;
 
     let (characteristics, upgraded_blob) = upgrade_keyblob_if_required_with(
         &*km_dev,
+        info.versionNumber,
         blob,
         &[],
         |blob| {
diff --git a/keystore2/src/raw_device.rs b/keystore2/src/raw_device.rs
index fa9872a..44d805c 100644
--- a/keystore2/src/raw_device.rs
+++ b/keystore2/src/raw_device.rs
@@ -263,35 +263,31 @@
     where
         F: Fn(&[u8]) -> Result<T, Error>,
     {
-        match f(&key_blob) {
-            Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
-                let upgraded_blob = map_km_error({
-                    let _wp = wd::watch_millis(
-                        "In KeyMintDevice::upgrade_keyblob_if_required_with: calling upgradeKey.",
-                        500,
-                    );
-                    self.km_dev.upgradeKey(&key_blob, &[])
-                })
-                .context(ks_err!("Upgrade failed"))?;
-
+        let (f_result, upgraded_blob) = crate::utils::upgrade_keyblob_if_required_with(
+            &*self.km_dev,
+            self.version(),
+            &key_blob,
+            &[],
+            f,
+            |upgraded_blob| {
                 let mut new_blob_metadata = BlobMetaData::new();
                 new_blob_metadata.add(BlobMetaEntry::KmUuid(self.km_uuid));
 
                 db.set_blob(
                     key_id_guard,
                     SubComponentType::KEY_BLOB,
-                    Some(&upgraded_blob),
+                    Some(upgraded_blob),
                     Some(&new_blob_metadata),
                 )
                 .context(ks_err!("Failed to insert upgraded blob into the database"))?;
-
-                Ok((
-                    f(&upgraded_blob).context(ks_err!("Closure failed after upgrade"))?,
-                    KeyBlob::NonSensitive(upgraded_blob),
-                ))
-            }
-            result => Ok((result.context(ks_err!("Closure failed"))?, key_blob)),
-        }
+                Ok(())
+            },
+        )?;
+        let returned_blob = match upgraded_blob {
+            None => key_blob,
+            Some(upgraded_blob) => KeyBlob::NonSensitive(upgraded_blob),
+        };
+        Ok((f_result, returned_blob))
     }
 
     /// Use the created key in an operation that can be done with
diff --git a/keystore2/src/rkpd_client.rs b/keystore2/src/rkpd_client.rs
index 938d389..7b4131d 100644
--- a/keystore2/src/rkpd_client.rs
+++ b/keystore2/src/rkpd_client.rs
@@ -666,7 +666,7 @@
     fn test_rkpd_attestation_key_upgrade() {
         binder::ProcessState::start_thread_pool();
         let security_level = SecurityLevel::TRUSTED_ENVIRONMENT;
-        let (keymint, _, _) = get_keymint_device(&security_level).unwrap();
+        let (keymint, info, _) = get_keymint_device(&security_level).unwrap();
         let key_id = get_next_key_id();
         let mut key_upgraded = false;
 
@@ -676,6 +676,7 @@
 
         upgrade_keyblob_if_required_with(
             &*keymint,
+            info.versionNumber,
             &key.keyBlob,
             /*upgrade_params=*/ &[],
             /*km_op=*/
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index db44d4b..44ca4c8 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -317,7 +317,6 @@
 
         let (begin_result, upgraded_blob) = self
             .upgrade_keyblob_if_required_with(
-                &*self.keymint,
                 key_id_guard,
                 &km_blob,
                 blob_metadata.km_uuid().copied(),
@@ -561,7 +560,6 @@
                 issuer_subject,
             }) => self
                 .upgrade_keyblob_if_required_with(
-                    &*self.keymint,
                     Some(key_id_guard),
                     &KeyBlob::Ref(&blob),
                     blob_metadata.km_uuid().copied(),
@@ -786,7 +784,6 @@
 
         let (creation_result, _) = self
             .upgrade_keyblob_if_required_with(
-                &*self.keymint,
                 Some(wrapping_key_id_guard),
                 &wrapping_key_blob,
                 wrapping_blob_metadata.km_uuid().copied(),
@@ -842,7 +839,6 @@
 
     fn upgrade_keyblob_if_required_with<T, F>(
         &self,
-        km_dev: &dyn IKeyMintDevice,
         mut key_id_guard: Option<KeyIdGuard>,
         key_blob: &KeyBlob,
         km_uuid: Option<Uuid>,
@@ -853,7 +849,8 @@
         F: Fn(&[u8]) -> Result<T, Error>,
     {
         let (v, upgraded_blob) = crate::utils::upgrade_keyblob_if_required_with(
-            km_dev,
+            &*self.keymint,
+            self.hw_info.versionNumber,
             key_blob,
             params,
             f,
@@ -893,6 +890,7 @@
     {
         crate::utils::upgrade_keyblob_if_required_with(
             &*self.keymint,
+            self.hw_info.versionNumber,
             key_blob,
             params,
             f,
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
index 584a51c..80aa7c3 100644
--- a/keystore2/src/utils.rs
+++ b/keystore2/src/utils.rs
@@ -23,6 +23,8 @@
 use crate::{
     database::{KeyType, KeystoreDB},
     globals::LEGACY_IMPORTER,
+    km_compat,
+    raw_device::KeyMintDevice,
 };
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     IKeyMintDevice::IKeyMintDevice, KeyCharacteristics::KeyCharacteristics,
@@ -163,13 +165,9 @@
         .collect()
 }
 
-/// This function can be used to upgrade key blobs on demand. The return value of
-/// `km_op` is inspected and if ErrorCode::KEY_REQUIRES_UPGRADE is encountered,
-/// an attempt is made to upgrade the key blob. On success `new_blob_handler` is called
-/// with the upgraded blob as argument. Then `km_op` is called a second time with the
-/// upgraded blob as argument. On success a tuple of the `km_op`s result and the
-/// optional upgraded blob is returned.
-pub fn upgrade_keyblob_if_required_with<T, KmOp, NewBlobHandler>(
+/// Upgrade a keyblob then invoke both the `new_blob_handler` and the `km_op` closures.  On success
+/// a tuple of the `km_op`s result and the optional upgraded blob is returned.
+fn upgrade_keyblob_and_perform_op<T, KmOp, NewBlobHandler>(
     km_dev: &dyn IKeyMintDevice,
     key_blob: &[u8],
     upgrade_params: &[KmKeyParameter],
@@ -180,22 +178,75 @@
     KmOp: Fn(&[u8]) -> Result<T, Error>,
     NewBlobHandler: FnOnce(&[u8]) -> Result<()>,
 {
+    let upgraded_blob = {
+        let _wp = watchdog::watch_millis(
+            "In utils::upgrade_keyblob_and_perform_op: calling upgradeKey.",
+            500,
+        );
+        map_km_error(km_dev.upgradeKey(key_blob, upgrade_params))
+    }
+    .context(ks_err!("Upgrade failed."))?;
+
+    new_blob_handler(&upgraded_blob).context(ks_err!("calling new_blob_handler."))?;
+
+    km_op(&upgraded_blob)
+        .map(|v| (v, Some(upgraded_blob)))
+        .context(ks_err!("Calling km_op after upgrade."))
+}
+
+/// This function can be used to upgrade key blobs on demand. The return value of
+/// `km_op` is inspected and if ErrorCode::KEY_REQUIRES_UPGRADE is encountered,
+/// an attempt is made to upgrade the key blob. On success `new_blob_handler` is called
+/// with the upgraded blob as argument. Then `km_op` is called a second time with the
+/// upgraded blob as argument. On success a tuple of the `km_op`s result and the
+/// optional upgraded blob is returned.
+pub fn upgrade_keyblob_if_required_with<T, KmOp, NewBlobHandler>(
+    km_dev: &dyn IKeyMintDevice,
+    km_dev_version: i32,
+    key_blob: &[u8],
+    upgrade_params: &[KmKeyParameter],
+    km_op: KmOp,
+    new_blob_handler: NewBlobHandler,
+) -> Result<(T, Option<Vec<u8>>)>
+where
+    KmOp: Fn(&[u8]) -> Result<T, Error>,
+    NewBlobHandler: FnOnce(&[u8]) -> Result<()>,
+{
     match km_op(key_blob) {
-        Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
-            let upgraded_blob = {
-                let _wp = watchdog::watch_millis(
-                    "In utils::upgrade_keyblob_if_required_with: calling upgradeKey.",
-                    500,
-                );
-                map_km_error(km_dev.upgradeKey(key_blob, upgrade_params))
-            }
-            .context(ks_err!("Upgrade failed."))?;
-
-            new_blob_handler(&upgraded_blob).context(ks_err!("calling new_blob_handler."))?;
-
-            km_op(&upgraded_blob)
-                .map(|v| (v, Some(upgraded_blob)))
-                .context(ks_err!("Calling km_op after upgrade."))
+        Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => upgrade_keyblob_and_perform_op(
+            km_dev,
+            key_blob,
+            upgrade_params,
+            km_op,
+            new_blob_handler,
+        ),
+        // Some devices have been known to upgrade their Keymaster device to be a KeyMint
+        // device with a new release of Android.  If this is the case, then any pre-upgrade
+        // keyblobs will have the km_compat prefix attached to them.
+        //
+        // This prefix gets stripped by the km_compat layer when used pre-upgrade, but after
+        // the upgrade the keyblob will be passed as-is to the KeyMint device, which probably
+        // won't expect to see the km_compat prefix.
+        //
+        // So if a keyblob:
+        //   a) gets rejected with INVALID_KEY_BLOB
+        //   b) when sent to a KeyMint (not km_compat) device
+        //   c) and has the km_compat magic prefix
+        //   d) and was not a software-emulated key pre-upgrade
+        // then strip the prefix and attempt a key upgrade.
+        Err(Error::Km(ErrorCode::INVALID_KEY_BLOB))
+            if km_dev_version >= KeyMintDevice::KEY_MINT_V1
+                && key_blob.starts_with(km_compat::KEYMASTER_BLOB_HW_PREFIX) =>
+        {
+            log::info!("found apparent km_compat(Keymaster) blob, attempt strip-and-upgrade");
+            let inner_keyblob = &key_blob[km_compat::KEYMASTER_BLOB_HW_PREFIX.len()..];
+            upgrade_keyblob_and_perform_op(
+                km_dev,
+                inner_keyblob,
+                upgrade_params,
+                km_op,
+                new_blob_handler,
+            )
         }
         r => r.map(|v| (v, None)).context(ks_err!("Calling km_op.")),
     }