diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..99cf5ff
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.*~
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/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+  license_type: NOTICE
+}
diff --git a/OWNERS b/OWNERS
index 684cca3..bb51005 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,6 @@
 swillden@google.com
 cbrubaker@google.com
 jdanis@google.com
+hasinitg@google.com
 kroot@google.com
-bdc@google.com
+zeuthen@google.com
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index dcf92be..9b96f36 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,8 +1,10 @@
 [Builtin Hooks]
 clang_format = true
+rustfmt = true
 
 [Builtin Hooks Options]
 clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+rustfmt = --config-path=rustfmt.toml
 
 [Hook Scripts]
 aosp_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "."
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/fsverity_init/fsverity_init.cpp b/fsverity_init/fsverity_init.cpp
index 4ed25cd..7ab4097 100644
--- a/fsverity_init/fsverity_init.cpp
+++ b/fsverity_init/fsverity_init.cpp
@@ -37,48 +37,87 @@
     return true;
 }
 
-void LoadKeyFromDirectory(key_serial_t keyring_id, const char* keyname, const char* dir) {
+void LoadKeyFromStdin(key_serial_t keyring_id, const char* keyname) {
+    std::string content;
+    if (!android::base::ReadFdToString(STDIN_FILENO, &content)) {
+        LOG(ERROR) << "Failed to read key from stdin";
+        return;
+    }
+    if (!LoadKeyToKeyring(keyring_id, keyname, content.c_str(), content.size())) {
+        LOG(ERROR) << "Failed to load key from stdin";
+    }
+}
+
+void LoadKeyFromFile(key_serial_t keyring_id, const char* keyname, const std::string& path) {
+    LOG(INFO) << "LoadKeyFromFile path=" << path << " keyname=" << keyname;
+    std::string content;
+    if (!android::base::ReadFileToString(path, &content)) {
+        LOG(ERROR) << "Failed to read key from " << path;
+        return;
+    }
+    if (!LoadKeyToKeyring(keyring_id, keyname, content.c_str(), content.size())) {
+        LOG(ERROR) << "Failed to load key from " << path;
+    }
+}
+
+void LoadKeyFromDirectory(key_serial_t keyring_id, const char* keyname_prefix, const char* dir) {
     if (!std::filesystem::exists(dir)) {
         return;
     }
+    int counter = 0;
     for (const auto& entry : std::filesystem::directory_iterator(dir)) {
         if (!android::base::EndsWithIgnoreCase(entry.path().c_str(), ".der")) continue;
-        std::string content;
-        if (!android::base::ReadFileToString(entry.path(), &content)) {
-            continue;
-        }
-        if (!LoadKeyToKeyring(keyring_id, keyname, content.c_str(), content.size())) {
-            LOG(ERROR) << "Failed to load key from " << entry.path();
-        }
+        std::string keyname = keyname_prefix + std::to_string(counter);
+        counter++;
+        LoadKeyFromFile(keyring_id, keyname.c_str(), entry.path());
     }
 }
 
 void LoadKeyFromVerifiedPartitions(key_serial_t keyring_id) {
     // NB: Directories need to be synced with FileIntegrityService.java in
     // frameworks/base.
-    LoadKeyFromDirectory(keyring_id, "fsv_system", "/system/etc/security/fsverity");
-    LoadKeyFromDirectory(keyring_id, "fsv_product", "/product/etc/security/fsverity");
+    LoadKeyFromDirectory(keyring_id, "fsv_system_", "/system/etc/security/fsverity");
+    LoadKeyFromDirectory(keyring_id, "fsv_product_", "/product/etc/security/fsverity");
 }
 
-int main(int /*argc*/, const char** /*argv*/) {
+int main(int argc, const char** argv) {
+    if (argc < 2) {
+        LOG(ERROR) << "Not enough arguments";
+        return -1;
+    }
+
     key_serial_t keyring_id = android::GetKeyringId(".fs-verity");
     if (keyring_id < 0) {
         LOG(ERROR) << "Failed to find .fs-verity keyring id";
         return -1;
     }
 
-    // Requires files backed by fs-verity to be verified with a key in .fs-verity
-    // keyring.
-    if (!android::base::WriteStringToFile("1", "/proc/sys/fs/verity/require_signatures")) {
-        PLOG(ERROR) << "Failed to enforce fs-verity signature";
-    }
+    const std::string_view command = argv[1];
 
-    LoadKeyFromVerifiedPartitions(keyring_id);
-
-    if (!android::base::GetBoolProperty("ro.debuggable", false)) {
-        if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
-            PLOG(ERROR) << "Cannot restrict .fs-verity keyring";
+    if (command == "--load-verified-keys") {
+        LoadKeyFromVerifiedPartitions(keyring_id);
+    } else if (command == "--load-extra-key") {
+        if (argc != 3) {
+            LOG(ERROR) << "--load-extra-key requires <key_name> argument.";
+            return -1;
         }
+        LoadKeyFromStdin(keyring_id, argv[2]);
+    } else if (command == "--lock") {
+        // Requires files backed by fs-verity to be verified with a key in .fs-verity
+        // keyring.
+        if (!android::base::WriteStringToFile("1", "/proc/sys/fs/verity/require_signatures")) {
+            PLOG(ERROR) << "Failed to enforce fs-verity signature";
+        }
+
+        if (!android::base::GetBoolProperty("ro.debuggable", false)) {
+            if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
+                PLOG(ERROR) << "Cannot restrict .fs-verity keyring";
+            }
+        }
+    } else {
+        LOG(ERROR) << "Unknown argument(s).";
+        return -1;
     }
+
     return 0;
 }
diff --git a/identity/Android.bp b/identity/Android.bp
index c0f1635..8267a6b 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: [
@@ -5,6 +14,7 @@
         // "-Werror",
         "-Wextra",
         "-Wunused",
+        "-Wno-deprecated-declarations",
     ],
     sanitize: {
         misc_undefined : ["integer"],
@@ -29,18 +39,22 @@
     shared_libs: [
         "libbase",
         "libbinder",
-        "libkeystore_aidl",
+        "libbinder_ndk",
+        "android.hardware.keymaster@4.0",
         "libcredstore_aidl",
+        "libcrypto",
         "libutils",
         "libhidlbase",
         "android.hardware.identity-support-lib",
         "libkeymaster4support",
         "libkeystore-attestation-application-id",
+        "android.hardware.security.keymint-V1-ndk_platform",
+        "android.security.authorization-ndk_platform",
     ],
     static_libs: [
-        "android.hardware.identity-cpp",
-        "android.hardware.keymaster-cpp",
-        "libcppbor",
+        "android.hardware.identity-V3-cpp",
+        "android.hardware.keymaster-V3-cpp",
+        "libcppbor_external",
     ]
 }
 
diff --git a/identity/Credential.cpp b/identity/Credential.cpp
index 28ba752..7c75d8a 100644
--- a/identity/Credential.cpp
+++ b/identity/Credential.cpp
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "Credential"
+#define LOG_TAG "credstore"
 
 #include <android-base/logging.h>
-
+#include <android/binder_manager.h>
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
 
 #include <android/security/identity/ICredentialStore.h>
 
-#include <android/security/keystore/BnCredstoreTokenCallback.h>
-#include <android/security/keystore/IKeystoreService.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <keymasterV4_0/keymaster_utils.h>
@@ -33,9 +31,15 @@
 #include <future>
 #include <tuple>
 
+#include <aidl/android/hardware/security/keymint/HardwareAuthToken.h>
+#include <aidl/android/hardware/security/secureclock/TimeStampToken.h>
+#include <aidl/android/security/authorization/AuthorizationTokens.h>
+#include <aidl/android/security/authorization/IKeystoreAuthorization.h>
+
 #include "Credential.h"
 #include "CredentialData.h"
 #include "Util.h"
+#include "WritableCredential.h"
 
 namespace android {
 namespace security {
@@ -45,38 +49,45 @@
 using std::promise;
 using std::tuple;
 
-using android::security::keystore::IKeystoreService;
+using ::android::hardware::identity::IWritableIdentityCredential;
 
 using ::android::hardware::identity::support::ecKeyPairGetPkcs12;
 using ::android::hardware::identity::support::ecKeyPairGetPrivateKey;
 using ::android::hardware::identity::support::ecKeyPairGetPublicKey;
 using ::android::hardware::identity::support::sha256;
 
+using android::hardware::keymaster::SecurityLevel;
 using android::hardware::keymaster::V4_0::HardwareAuthToken;
 using android::hardware::keymaster::V4_0::VerificationToken;
 using AidlHardwareAuthToken = android::hardware::keymaster::HardwareAuthToken;
 using AidlVerificationToken = android::hardware::keymaster::VerificationToken;
 
+using KeyMintAuthToken = ::aidl::android::hardware::security::keymint::HardwareAuthToken;
+using ::aidl::android::hardware::security::secureclock::TimeStampToken;
+using ::aidl::android::security::authorization::AuthorizationTokens;
+using ::aidl::android::security::authorization::IKeystoreAuthorization;
+
 Credential::Credential(CipherSuite cipherSuite, const std::string& dataPath,
-                       const std::string& credentialName)
-    : cipherSuite_(cipherSuite), dataPath_(dataPath), credentialName_(credentialName) {}
+                       const std::string& credentialName, uid_t callingUid,
+                       HardwareInformation hwInfo, sp<IIdentityCredentialStore> halStoreBinder,
+                       int halApiVersion)
+    : cipherSuite_(cipherSuite), dataPath_(dataPath), credentialName_(credentialName),
+      callingUid_(callingUid), hwInfo_(std::move(hwInfo)), halStoreBinder_(halStoreBinder),
+      halApiVersion_(halApiVersion) {}
 
 Credential::~Credential() {}
 
-Status Credential::loadCredential(sp<IIdentityCredentialStore> halStoreBinder) {
-    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
-    sp<CredentialData> data = new CredentialData(dataPath_, callingUid, credentialName_);
+Status Credential::ensureOrReplaceHalBinder() {
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
     if (!data->loadFromDisk()) {
         LOG(ERROR) << "Error loading data for credential";
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
                                                 "Error loading data for credential");
     }
 
-    data_ = data;
-
     sp<IIdentityCredential> halBinder;
     Status status =
-        halStoreBinder->getCredential(cipherSuite_, data_->getCredentialData(), &halBinder);
+        halStoreBinder_->getCredential(cipherSuite_, data->getCredentialData(), &halBinder);
     if (!status.isOk() && status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) {
         int code = status.serviceSpecificErrorCode();
         if (code == IIdentityCredentialStore::STATUS_CIPHER_SUITE_NOT_SUPPORTED) {
@@ -87,103 +98,143 @@
         LOG(ERROR) << "Error getting HAL binder";
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC);
     }
-
     halBinder_ = halBinder;
 
     return Status::ok();
 }
 
 Status Credential::getCredentialKeyCertificateChain(std::vector<uint8_t>* _aidl_return) {
-    *_aidl_return = data_->getAttestationCertificate();
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+    *_aidl_return = data->getAttestationCertificate();
     return Status::ok();
 }
 
 // Returns operation handle
-Status Credential::selectAuthKey(bool allowUsingExhaustedKeys, int64_t* _aidl_return) {
+Status Credential::selectAuthKey(bool allowUsingExhaustedKeys, bool allowUsingExpiredKeys,
+                                 int64_t* _aidl_return) {
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
 
-    selectedAuthKey_ = data_->selectAuthKey(allowUsingExhaustedKeys);
-    if (selectedAuthKey_ == nullptr) {
+    // We just check if a key is available, we actually don't store it since we
+    // don't keep CredentialData around between binder calls.
+    const AuthKeyData* authKey =
+        data->selectAuthKey(allowUsingExhaustedKeys, allowUsingExpiredKeys);
+    if (authKey == nullptr) {
         return Status::fromServiceSpecificError(
             ICredentialStore::ERROR_NO_AUTHENTICATION_KEY_AVAILABLE,
             "No suitable authentication key available");
     }
 
-    int64_t challenge;
-    Status status = halBinder_->createAuthChallenge(&challenge);
-    if (!status.isOk()) {
-        return halStatusToGenericError(status);
-    }
-    if (challenge == 0) {
+    if (!ensureChallenge()) {
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
-                                                "Returned challenge is 0 (bug in HAL or TA)");
+                                                "Error getting challenge (bug in HAL or TA)");
     }
-
-    selectedChallenge_ = challenge;
-    *_aidl_return = challenge;
+    *_aidl_return = selectedChallenge_;
     return Status::ok();
 }
 
-class CredstoreTokenCallback : public android::security::keystore::BnCredstoreTokenCallback,
-                               public promise<tuple<bool, vector<uint8_t>, vector<uint8_t>>> {
-  public:
-    CredstoreTokenCallback() {}
-    virtual Status onFinished(bool success, const vector<uint8_t>& authToken,
-                              const vector<uint8_t>& verificationToken) override {
-        this->set_value({success, authToken, verificationToken});
-        return Status::ok();
+bool Credential::ensureChallenge() {
+    if (selectedChallenge_ != 0) {
+        return true;
     }
-};
+
+    int64_t challenge;
+    Status status = halBinder_->createAuthChallenge(&challenge);
+    if (!status.isOk()) {
+        LOG(ERROR) << "Error getting challenge: " << status.exceptionMessage();
+        return false;
+    }
+    if (challenge == 0) {
+        LOG(ERROR) << "Returned challenge is 0 (bug in HAL or TA)";
+        return false;
+    }
+
+    selectedChallenge_ = challenge;
+    return true;
+}
 
 // Returns false if an error occurred communicating with keystore.
 //
-bool getTokensFromKeystore(uint64_t challenge, uint64_t secureUserId,
-                           unsigned int authTokenMaxAgeMillis, vector<uint8_t>& authToken,
-                           vector<uint8_t>& verificationToken) {
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> keystore = interface_cast<IKeystoreService>(binder);
-    if (keystore == nullptr) {
-        return false;
-    }
+bool getTokensFromKeystore2(uint64_t challenge, uint64_t secureUserId,
+                            unsigned int authTokenMaxAgeMillis,
+                            AidlHardwareAuthToken& aidlAuthToken,
+                            AidlVerificationToken& aidlVerificationToken) {
+    // try to connect to IKeystoreAuthorization AIDL service first.
+    AIBinder* authzAIBinder = AServiceManager_checkService("android.security.authorization");
+    ::ndk::SpAIBinder authzBinder(authzAIBinder);
+    auto authzService = IKeystoreAuthorization::fromBinder(authzBinder);
+    if (authzService) {
+        AuthorizationTokens authzTokens;
+        auto result = authzService->getAuthTokensForCredStore(challenge, secureUserId,
+                                                              authTokenMaxAgeMillis, &authzTokens);
+        // Convert KeyMint auth token to KeyMaster authtoken, only if tokens are
+        // returned
+        if (result.isOk()) {
+            KeyMintAuthToken keymintAuthToken = authzTokens.authToken;
+            aidlAuthToken.challenge = keymintAuthToken.challenge;
+            aidlAuthToken.userId = keymintAuthToken.userId;
+            aidlAuthToken.authenticatorId = keymintAuthToken.authenticatorId;
+            aidlAuthToken.authenticatorType =
+                ::android::hardware::keymaster::HardwareAuthenticatorType(
+                    int32_t(keymintAuthToken.authenticatorType));
+            aidlAuthToken.timestamp.milliSeconds = keymintAuthToken.timestamp.milliSeconds;
+            aidlAuthToken.mac = keymintAuthToken.mac;
 
-    sp<CredstoreTokenCallback> callback = new CredstoreTokenCallback();
-    auto future = callback->get_future();
-
-    Status status =
-        keystore->getTokensForCredstore(challenge, secureUserId, authTokenMaxAgeMillis, callback);
-    if (!status.isOk()) {
+            // Convert timestamp token to KeyMaster verification token
+            TimeStampToken timestampToken = authzTokens.timestampToken;
+            aidlVerificationToken.challenge = timestampToken.challenge;
+            aidlVerificationToken.timestamp.milliSeconds = timestampToken.timestamp.milliSeconds;
+            // Legacy verification tokens were always minted by TEE.
+            aidlVerificationToken.securityLevel = SecurityLevel::TRUSTED_ENVIRONMENT;
+            aidlVerificationToken.mac = timestampToken.mac;
+        } else {
+            if (result.getServiceSpecificError() == 0) {
+                // Here we differentiate the errors occurred during communication
+                // from the service specific errors.
+                LOG(ERROR) << "Error getting tokens from keystore2: " << result.getDescription();
+                return false;
+            } else {
+                // Log the reason for not receiving auth tokens from keystore2.
+                LOG(INFO) << "Auth tokens were not received due to: " << result.getDescription();
+            }
+        }
+        return true;
+    } else {
+        LOG(ERROR) << "Error connecting to IKeystoreAuthorization service";
         return false;
     }
-
-    auto fstatus = future.wait_for(std::chrono::milliseconds(5000));
-    if (fstatus != std::future_status::ready) {
-        LOG(ERROR) << "Waited 5 seconds from tokens for credstore, aborting";
-        return false;
-    }
-    auto [success, returnedAuthToken, returnedVerificationToken] = future.get();
-    if (!success) {
-        LOG(ERROR) << "Error getting tokens from credstore";
-        return false;
-    }
-    authToken = returnedAuthToken;
-    verificationToken = returnedVerificationToken;
-    return true;
 }
 
 Status Credential::getEntries(const vector<uint8_t>& requestMessage,
                               const vector<RequestNamespaceParcel>& requestNamespaces,
                               const vector<uint8_t>& sessionTranscript,
                               const vector<uint8_t>& readerSignature, bool allowUsingExhaustedKeys,
-                              GetEntriesResultParcel* _aidl_return) {
+                              bool allowUsingExpiredKeys, GetEntriesResultParcel* _aidl_return) {
     GetEntriesResultParcel ret;
 
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+
     // Calculate requestCounts ahead of time and be careful not to include
     // elements that don't exist.
     //
     // Also go through and figure out which access control profiles to include
     // in the startRetrieval() call.
     vector<int32_t> requestCounts;
-    const vector<SecureAccessControlProfile>& allProfiles = data_->getSecureAccessControlProfiles();
+    const vector<SecureAccessControlProfile>& allProfiles = data->getSecureAccessControlProfiles();
 
     // We don't support ACP identifiers which isn't in the range 0 to 31. This
     // guarantee exists so it's feasible to implement the TA part of an Identity
@@ -202,13 +253,13 @@
     for (const RequestNamespaceParcel& rns : requestNamespaces) {
         size_t numEntriesInNsToRequest = 0;
         for (const RequestEntryParcel& rep : rns.entries) {
-            if (data_->hasEntryData(rns.namespaceName, rep.name)) {
+            if (data->hasEntryData(rns.namespaceName, rep.name)) {
                 numEntriesInNsToRequest++;
             }
 
-            optional<EntryData> data = data_->getEntryData(rns.namespaceName, rep.name);
-            if (data) {
-                for (int32_t id : data.value().accessControlProfileIds) {
+            optional<EntryData> eData = data->getEntryData(rns.namespaceName, rep.name);
+            if (eData) {
+                for (int32_t id : eData.value().accessControlProfileIds) {
                     if (id < 0 || id >= 32) {
                         LOG(ERROR) << "Invalid accessControlProfileId " << id << " for "
                                    << rns.namespaceName << ": " << rep.name;
@@ -256,13 +307,6 @@
         }
     }
 
-    // If requesting a challenge-based authToken the idea is that authentication
-    // happens as part of the transaction. As such, authTokenMaxAgeMillis should
-    // be nearly zero. We'll use 10 seconds for this.
-    if (userAuthNeeded && selectedChallenge_ != 0) {
-        authTokenMaxAgeMillis = 10 * 1000;
-    }
-
     // Reset tokens and only get them if they're actually needed, e.g. if user authentication
     // is needed in any of the access control profiles for data items being requested.
     //
@@ -280,63 +324,58 @@
     aidlVerificationToken.securityLevel = ::android::hardware::keymaster::SecurityLevel::SOFTWARE;
     aidlVerificationToken.mac.clear();
     if (userAuthNeeded) {
-        vector<uint8_t> authTokenBytes;
-        vector<uint8_t> verificationTokenBytes;
-        if (!getTokensFromKeystore(selectedChallenge_, data_->getSecureUserId(),
-                                   authTokenMaxAgeMillis, authTokenBytes, verificationTokenBytes)) {
-            LOG(ERROR) << "Error getting tokens from keystore";
+        // If user authentication is needed, always get a challenge from the
+        // HAL/TA since it'll need it to check the returned VerificationToken
+        // for freshness.
+        if (!ensureChallenge()) {
             return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
-                                                    "Error getting tokens from keystore");
+                                                    "Error getting challenge (bug in HAL or TA)");
         }
 
-        // It's entirely possible getTokensFromKeystore() succeeded but didn't
-        // return any tokens (in which case the returned byte-vectors are
-        // empty). For example, this can happen if no auth token is available
-        // which satifies e.g. |authTokenMaxAgeMillis|.
+        // Note: if all selected profiles require auth-on-every-presentation
+        // then authTokenMaxAgeMillis will be 0 (because timeoutMillis for each
+        // profile is 0). Which means that keystore will only return an
+        // AuthToken if its challenge matches what we pass, regardless of its
+        // age. This is intended b/c the HAL/TA will check not care about
+        // the age in this case, it only cares that the challenge matches.
         //
-        if (authTokenBytes.size() > 0) {
-            HardwareAuthToken authToken =
-                android::hardware::keymaster::V4_0::support::hidlVec2AuthToken(authTokenBytes);
-            // Convert from HIDL to AIDL...
-            aidlAuthToken.challenge = int64_t(authToken.challenge);
-            aidlAuthToken.userId = int64_t(authToken.userId);
-            aidlAuthToken.authenticatorId = int64_t(authToken.authenticatorId);
-            aidlAuthToken.authenticatorType =
-                ::android::hardware::keymaster::HardwareAuthenticatorType(
-                    int32_t(authToken.authenticatorType));
-            aidlAuthToken.timestamp.milliSeconds = int64_t(authToken.timestamp);
-            aidlAuthToken.mac = authToken.mac;
-        }
+        // Otherwise, if one or more of the profiles is auth-with-a-timeout then
+        // authTokenMaxAgeMillis will be set to the largest of those
+        // timeouts. We'll get an AuthToken which satisfies this deadline if it
+        // exists. This authToken _may_ have the requested challenge but it's
+        // not a guarantee and it's also not required.
+        //
 
-        if (verificationTokenBytes.size() > 0) {
-            optional<VerificationToken> token =
-                android::hardware::keymaster::V4_0::support::deserializeVerificationToken(
-                    verificationTokenBytes);
-            if (!token) {
-                LOG(ERROR) << "Error deserializing verification token";
-                return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
-                                                        "Error deserializing verification token");
-            }
-            aidlVerificationToken.challenge = token->challenge;
-            aidlVerificationToken.timestamp.milliSeconds = token->timestamp;
-            aidlVerificationToken.securityLevel =
-                ::android::hardware::keymaster::SecurityLevel(token->securityLevel);
-            aidlVerificationToken.mac = token->mac;
+        if (!getTokensFromKeystore2(selectedChallenge_, data->getSecureUserId(),
+                                    authTokenMaxAgeMillis, aidlAuthToken, aidlVerificationToken)) {
+            LOG(ERROR) << "Error getting tokens from keystore2";
+            return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                    "Error getting tokens from keystore2");
         }
     }
 
     // Note that the selectAuthKey() method is only called if a CryptoObject is involved at
     // the Java layer. So we could end up with no previously selected auth key and we may
     // need one.
-    const AuthKeyData* authKey = selectedAuthKey_;
-    if (sessionTranscript.size() > 0) {
-        if (authKey == nullptr) {
-            authKey = data_->selectAuthKey(allowUsingExhaustedKeys);
-            if (authKey == nullptr) {
-                return Status::fromServiceSpecificError(
-                    ICredentialStore::ERROR_NO_AUTHENTICATION_KEY_AVAILABLE,
-                    "No suitable authentication key available");
-            }
+    //
+    const AuthKeyData* authKey =
+        data->selectAuthKey(allowUsingExhaustedKeys, allowUsingExpiredKeys);
+    if (authKey == nullptr) {
+        // If no authKey is available, consider it an error only when a
+        // SessionTranscript was provided.
+        //
+        // We allow no SessionTranscript to be provided because it makes
+        // the API simpler to deal with insofar it can be used without having
+        // to generate any authentication keys.
+        //
+        // In this "no SessionTranscript is provided" mode we don't return
+        // DeviceNameSpaces nor a MAC over DeviceAuthentication so we don't
+        // need a device key.
+        //
+        if (sessionTranscript.size() > 0) {
+            return Status::fromServiceSpecificError(
+                ICredentialStore::ERROR_NO_AUTHENTICATION_KEY_AVAILABLE,
+                "No suitable authentication key available and one is needed");
         }
     }
     vector<uint8_t> signingKeyBlob;
@@ -351,7 +390,7 @@
         RequestNamespace ns;
         ns.namespaceName = rns.namespaceName;
         for (const RequestEntryParcel& rep : rns.entries) {
-            optional<EntryData> entryData = data_->getEntryData(rns.namespaceName, rep.name);
+            optional<EntryData> entryData = data->getEntryData(rns.namespaceName, rep.name);
             if (entryData) {
                 RequestDataItem di;
                 di.name = rep.name;
@@ -406,16 +445,16 @@
             ResultEntryParcel resultEntryParcel;
             resultEntryParcel.name = rep.name;
 
-            optional<EntryData> data = data_->getEntryData(rns.namespaceName, rep.name);
-            if (!data) {
+            optional<EntryData> eData = data->getEntryData(rns.namespaceName, rep.name);
+            if (!eData) {
                 resultEntryParcel.status = STATUS_NO_SUCH_ENTRY;
                 resultNamespaceParcel.entries.push_back(resultEntryParcel);
                 continue;
             }
 
             status =
-                halBinder_->startRetrieveEntryValue(rns.namespaceName, rep.name, data.value().size,
-                                                    data.value().accessControlProfileIds);
+                halBinder_->startRetrieveEntryValue(rns.namespaceName, rep.name, eData.value().size,
+                                                    eData.value().accessControlProfileIds);
             if (!status.isOk() && status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) {
                 int code = status.serviceSpecificErrorCode();
                 if (code == IIdentityCredentialStore::STATUS_USER_AUTHENTICATION_FAILED) {
@@ -441,7 +480,7 @@
             }
 
             vector<uint8_t> value;
-            for (const auto& encryptedChunk : data.value().encryptedChunks) {
+            for (const auto& encryptedChunk : eData.value().encryptedChunks) {
                 vector<uint8_t> chunk;
                 status = halBinder_->retrieveEntryValue(encryptedChunk, &chunk);
                 if (!status.isOk()) {
@@ -467,7 +506,7 @@
 
     // Ensure useCount is updated on disk.
     if (authKey != nullptr) {
-        if (!data_->saveToDisk()) {
+        if (!data->saveToDisk()) {
             return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
                                                     "Error saving data");
         }
@@ -479,11 +518,19 @@
 
 Status Credential::deleteCredential(vector<uint8_t>* _aidl_return) {
     vector<uint8_t> proofOfDeletionSignature;
+
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+
     Status status = halBinder_->deleteCredential(&proofOfDeletionSignature);
     if (!status.isOk()) {
         return halStatusToGenericError(status);
     }
-    if (!data_->deleteCredential()) {
+    if (!data->deleteCredential()) {
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
                                                 "Error deleting credential data on disk");
     }
@@ -491,6 +538,47 @@
     return Status::ok();
 }
 
+Status Credential::deleteWithChallenge(const vector<uint8_t>& challenge,
+                                       vector<uint8_t>* _aidl_return) {
+    if (halApiVersion_ < 3) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_NOT_SUPPORTED,
+                                                "Not implemented by HAL");
+    }
+    vector<uint8_t> proofOfDeletionSignature;
+
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+
+    Status status = halBinder_->deleteCredentialWithChallenge(challenge, &proofOfDeletionSignature);
+    if (!status.isOk()) {
+        return halStatusToGenericError(status);
+    }
+    if (!data->deleteCredential()) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error deleting credential data on disk");
+    }
+    *_aidl_return = proofOfDeletionSignature;
+    return Status::ok();
+}
+
+Status Credential::proveOwnership(const vector<uint8_t>& challenge, vector<uint8_t>* _aidl_return) {
+    if (halApiVersion_ < 3) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_NOT_SUPPORTED,
+                                                "Not implemented by HAL");
+    }
+    vector<uint8_t> proofOfOwnershipSignature;
+    Status status = halBinder_->proveOwnership(challenge, &proofOfOwnershipSignature);
+    if (!status.isOk()) {
+        return halStatusToGenericError(status);
+    }
+    *_aidl_return = proofOfOwnershipSignature;
+    return Status::ok();
+}
+
 Status Credential::createEphemeralKeyPair(vector<uint8_t>* _aidl_return) {
     vector<uint8_t> keyPair;
     Status status = halBinder_->createEphemeralKeyPair(&keyPair);
@@ -522,8 +610,14 @@
 }
 
 Status Credential::setAvailableAuthenticationKeys(int32_t keyCount, int32_t maxUsesPerKey) {
-    data_->setAvailableAuthenticationKeys(keyCount, maxUsesPerKey);
-    if (!data_->saveToDisk()) {
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+    data->setAvailableAuthenticationKeys(keyCount, maxUsesPerKey);
+    if (!data->saveToDisk()) {
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
                                                 "Error saving data");
     }
@@ -531,8 +625,14 @@
 }
 
 Status Credential::getAuthKeysNeedingCertification(vector<AuthKeyParcel>* _aidl_return) {
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
     optional<vector<vector<uint8_t>>> keysNeedingCert =
-        data_->getAuthKeysNeedingCertification(halBinder_);
+        data->getAuthKeysNeedingCertification(halBinder_);
     if (!keysNeedingCert) {
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
                                                 "Error getting auth keys neededing certification");
@@ -543,7 +643,7 @@
         authKeyParcel.x509cert = key;
         authKeyParcels.push_back(authKeyParcel);
     }
-    if (!data_->saveToDisk()) {
+    if (!data->saveToDisk()) {
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
                                                 "Error saving data");
     }
@@ -553,13 +653,48 @@
 
 Status Credential::storeStaticAuthenticationData(const AuthKeyParcel& authenticationKey,
                                                  const vector<uint8_t>& staticAuthData) {
-    if (!data_->storeStaticAuthenticationData(authenticationKey.x509cert, staticAuthData)) {
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+    if (!data->storeStaticAuthenticationData(authenticationKey.x509cert,
+                                             std::numeric_limits<int64_t>::max(), staticAuthData)) {
         return Status::fromServiceSpecificError(
             ICredentialStore::ERROR_AUTHENTICATION_KEY_NOT_FOUND,
             "Error finding authentication key to store static "
             "authentication data for");
     }
-    if (!data_->saveToDisk()) {
+    if (!data->saveToDisk()) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error saving data");
+    }
+    return Status::ok();
+}
+
+Status
+Credential::storeStaticAuthenticationDataWithExpiration(const AuthKeyParcel& authenticationKey,
+                                                        int64_t expirationDateMillisSinceEpoch,
+                                                        const vector<uint8_t>& staticAuthData) {
+    if (halApiVersion_ < 3) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_NOT_SUPPORTED,
+                                                "Not implemented by HAL");
+    }
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+    if (!data->storeStaticAuthenticationData(authenticationKey.x509cert,
+                                             expirationDateMillisSinceEpoch, staticAuthData)) {
+        return Status::fromServiceSpecificError(
+            ICredentialStore::ERROR_AUTHENTICATION_KEY_NOT_FOUND,
+            "Error finding authentication key to store static "
+            "authentication data for");
+    }
+    if (!data->saveToDisk()) {
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
                                                 "Error saving data");
     }
@@ -567,7 +702,13 @@
 }
 
 Status Credential::getAuthenticationDataUsageCount(vector<int32_t>* _aidl_return) {
-    const vector<AuthKeyData>& authKeyDatas = data_->getAuthKeyDatas();
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+    const vector<AuthKeyData>& authKeyDatas = data->getAuthKeyDatas();
     vector<int32_t> ret;
     for (const AuthKeyData& authKeyData : authKeyDatas) {
         ret.push_back(authKeyData.useCount);
@@ -576,6 +717,85 @@
     return Status::ok();
 }
 
+optional<string> extractDocType(const vector<uint8_t>& credentialData) {
+    auto [item, _ /* newPos */, message] = cppbor::parse(credentialData);
+    if (item == nullptr) {
+        LOG(ERROR) << "CredentialData is not valid CBOR: " << message;
+        return {};
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr || array->size() < 1) {
+        LOG(ERROR) << "CredentialData array with at least one element";
+        return {};
+    }
+    const cppbor::Tstr* tstr = ((*array)[0])->asTstr();
+    if (tstr == nullptr) {
+        LOG(ERROR) << "First item in CredentialData is not a string";
+        return {};
+    }
+    return tstr->value();
+}
+
+Status Credential::update(sp<IWritableCredential>* _aidl_return) {
+    if (halApiVersion_ < 3) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_NOT_SUPPORTED,
+                                                "Not implemented by HAL");
+    }
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid_, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+
+    sp<IWritableIdentityCredential> halWritableCredential;
+    Status status = halBinder_->updateCredential(&halWritableCredential);
+    if (!status.isOk()) {
+        return halStatusToGenericError(status);
+    }
+
+    optional<string> docType = extractDocType(data->getCredentialData());
+    if (!docType) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Unable to extract DocType from CredentialData");
+    }
+
+    // NOTE: The caller is expected to call WritableCredential::personalize() which will
+    // write brand new data to disk, specifically it will overwrite any data already
+    // have _including_ authentication keys.
+    //
+    // It is because of this we need to set the CredentialKey certificate chain,
+    // keyCount, and maxUsesPerKey below.
+    sp<WritableCredential> writableCredential = new WritableCredential(
+        dataPath_, credentialName_, docType.value(), true, hwInfo_, halWritableCredential);
+
+    writableCredential->setAttestationCertificate(data->getAttestationCertificate());
+    auto [keyCount, maxUsesPerKey] = data->getAvailableAuthenticationKeys();
+    writableCredential->setAvailableAuthenticationKeys(keyCount, maxUsesPerKey);
+
+    // Because its data has changed, we need to replace the binder for the
+    // IIdentityCredential when the credential has been updated... otherwise the
+    // remote object will have stale data for future calls, for example
+    // getAuthKeysNeedingCertification().
+    //
+    // The way this is implemented is that setCredentialToReloadWhenUpdated()
+    // instructs the WritableCredential to call writableCredentialPersonalized()
+    // on |this|.
+    //
+    //
+    writableCredential->setCredentialToReloadWhenUpdated(this);
+
+    *_aidl_return = writableCredential;
+    return Status::ok();
+}
+
+void Credential::writableCredentialPersonalized() {
+    Status status = ensureOrReplaceHalBinder();
+    if (!status.isOk()) {
+        LOG(ERROR) << "Error reloading credential";
+    }
+}
+
 }  // namespace identity
 }  // namespace security
 }  // namespace android
diff --git a/identity/Credential.h b/identity/Credential.h
index e2880d9..a76f3cc 100644
--- a/identity/Credential.h
+++ b/identity/Credential.h
@@ -36,6 +36,7 @@
 using ::std::vector;
 
 using ::android::hardware::identity::CipherSuite;
+using ::android::hardware::identity::HardwareInformation;
 using ::android::hardware::identity::IIdentityCredential;
 using ::android::hardware::identity::IIdentityCredentialStore;
 using ::android::hardware::identity::RequestDataItem;
@@ -43,10 +44,13 @@
 
 class Credential : public BnCredential {
   public:
-    Credential(CipherSuite cipherSuite, const string& dataPath, const string& credentialName);
+    Credential(CipherSuite cipherSuite, const string& dataPath, const string& credentialName,
+               uid_t callingUid, HardwareInformation hwInfo,
+               sp<IIdentityCredentialStore> halStoreBinder, int halApiVersion);
     ~Credential();
 
-    Status loadCredential(sp<IIdentityCredentialStore> halStoreBinder);
+    Status ensureOrReplaceHalBinder();
+    void writableCredentialPersonalized();
 
     // ICredential overrides
     Status createEphemeralKeyPair(vector<uint8_t>* _aidl_return) override;
@@ -55,33 +59,48 @@
 
     Status deleteCredential(vector<uint8_t>* _aidl_return) override;
 
+    Status deleteWithChallenge(const vector<uint8_t>& challenge,
+                               vector<uint8_t>* _aidl_return) override;
+
+    Status proveOwnership(const vector<uint8_t>& challenge, vector<uint8_t>* _aidl_return) override;
+
     Status getCredentialKeyCertificateChain(vector<uint8_t>* _aidl_return) override;
 
-    Status selectAuthKey(bool allowUsingExhaustedKeys, int64_t* _aidl_return) override;
+    Status selectAuthKey(bool allowUsingExhaustedKeys, bool allowUsingExpiredKeys,
+                         int64_t* _aidl_return) override;
 
     Status getEntries(const vector<uint8_t>& requestMessage,
                       const vector<RequestNamespaceParcel>& requestNamespaces,
                       const vector<uint8_t>& sessionTranscript,
                       const vector<uint8_t>& readerSignature, bool allowUsingExhaustedKeys,
-                      GetEntriesResultParcel* _aidl_return) override;
+                      bool allowUsingExpiredKeys, GetEntriesResultParcel* _aidl_return) override;
 
     Status setAvailableAuthenticationKeys(int32_t keyCount, int32_t maxUsesPerKey) override;
     Status getAuthKeysNeedingCertification(vector<AuthKeyParcel>* _aidl_return) override;
     Status storeStaticAuthenticationData(const AuthKeyParcel& authenticationKey,
                                          const vector<uint8_t>& staticAuthData) override;
+    Status
+    storeStaticAuthenticationDataWithExpiration(const AuthKeyParcel& authenticationKey,
+                                                int64_t expirationDateMillisSinceEpoch,
+                                                const vector<uint8_t>& staticAuthData) override;
     Status getAuthenticationDataUsageCount(vector<int32_t>* _aidl_return) override;
 
+    Status update(sp<IWritableCredential>* _aidl_return) override;
+
   private:
     CipherSuite cipherSuite_;
     string dataPath_;
     string credentialName_;
+    uid_t callingUid_;
+    HardwareInformation hwInfo_;
+    sp<IIdentityCredentialStore> halStoreBinder_;
 
-    const AuthKeyData* selectedAuthKey_ = nullptr;
     uint64_t selectedChallenge_ = 0;
 
-    sp<CredentialData> data_;
-
     sp<IIdentityCredential> halBinder_;
+    int halApiVersion_;
+
+    bool ensureChallenge();
 
     ssize_t
     calcExpectedDeviceNameSpacesSize(const vector<uint8_t>& requestMessage,
diff --git a/identity/CredentialData.cpp b/identity/CredentialData.cpp
index b4e6641..74b995d 100644
--- a/identity/CredentialData.cpp
+++ b/identity/CredentialData.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CredentialData"
+#define LOG_TAG "credstore"
+
+#include <chrono>
 
 #include <fcntl.h>
 #include <stdlib.h>
@@ -119,12 +121,15 @@
     cppbor::Array authKeyDatasArray;
     for (const AuthKeyData& data : authKeyDatas_) {
         cppbor::Array array;
+        // Fields 0-6 was in the original version in Android 11
         array.add(data.certificate);
         array.add(data.keyBlob);
         array.add(data.staticAuthenticationData);
         array.add(data.pendingCertificate);
         array.add(data.pendingKeyBlob);
         array.add(data.useCount);
+        // Field 7 was added in Android 12
+        array.add(data.expirationDateMillisSinceEpoch);
         authKeyDatasArray.add(std::move(array));
     }
     map.add("authKeyData", std::move(authKeyDatasArray));
@@ -183,9 +188,17 @@
         LOG(ERROR) << "One or more items in AuthKeyData array in CBOR is of wrong type";
         return {};
     }
+    // expirationDateMillisSinceEpoch was added as the 7th element for Android 12. If not
+    // present, default to longest possible expiration date.
+    int64_t expirationDateMillisSinceEpoch = INT64_MAX;
+    if (array->size() >= 7) {
+        const cppbor::Int* itemExpirationDateMillisSinceEpoch = ((*array)[6])->asInt();
+        expirationDateMillisSinceEpoch = itemExpirationDateMillisSinceEpoch->value();
+    }
     AuthKeyData authKeyData;
     authKeyData.certificate = itemCertificate->value();
     authKeyData.keyBlob = itemKeyBlob->value();
+    authKeyData.expirationDateMillisSinceEpoch = expirationDateMillisSinceEpoch;
     authKeyData.staticAuthenticationData = itemStaticAuthenticationData->value();
     authKeyData.pendingCertificate = itemPendingCertificate->value();
     authKeyData.pendingKeyBlob = itemPendingKeyBlob->value();
@@ -232,7 +245,6 @@
 }
 
 bool CredentialData::loadFromDisk() {
-
     // Reset all data.
     credentialData_.clear();
     attestationCertificate_.clear();
@@ -261,7 +273,7 @@
     }
 
     for (size_t n = 0; n < map->size(); n++) {
-        auto [keyItem, valueItem] = (*map)[n];
+        auto& [keyItem, valueItem] = (*map)[n];
         const cppbor::Tstr* tstr = keyItem->asTstr();
         if (tstr == nullptr) {
             LOG(ERROR) << "Key item in top-level map is not a tstr";
@@ -313,7 +325,7 @@
                 return false;
             }
             for (size_t m = 0; m < map->size(); m++) {
-                auto [ecKeyItem, ecValueItem] = (*map)[m];
+                auto& [ecKeyItem, ecValueItem] = (*map)[m];
                 const cppbor::Tstr* ecTstr = ecKeyItem->asTstr();
                 if (ecTstr == nullptr) {
                     LOG(ERROR) << "Key item in encryptedChunks map is not a tstr";
@@ -487,16 +499,28 @@
     return authKeyDatas_;
 }
 
-const AuthKeyData* CredentialData::selectAuthKey(bool allowUsingExhaustedKeys) {
+pair<int /* keyCount */, int /*maxUsersPerKey */> CredentialData::getAvailableAuthenticationKeys() {
+    return std::make_pair(keyCount_, maxUsesPerKey_);
+}
+
+AuthKeyData* CredentialData::findAuthKey_(bool allowUsingExhaustedKeys,
+                                          bool allowUsingExpiredKeys) {
     AuthKeyData* candidate = nullptr;
 
+    int64_t nowMilliSeconds =
+        std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) * 1000;
+
     int n = 0;
-    int candidateNum = -1;
     for (AuthKeyData& data : authKeyDatas_) {
+        if (nowMilliSeconds > data.expirationDateMillisSinceEpoch) {
+            if (!allowUsingExpiredKeys) {
+                continue;
+            }
+        }
         if (data.certificate.size() != 0) {
+            // Not expired, include in normal check
             if (candidate == nullptr || data.useCount < candidate->useCount) {
                 candidate = &data;
-                candidateNum = n;
             }
         }
         n++;
@@ -510,6 +534,28 @@
         return nullptr;
     }
 
+    return candidate;
+}
+
+const AuthKeyData* CredentialData::selectAuthKey(bool allowUsingExhaustedKeys,
+                                                 bool allowUsingExpiredKeys) {
+    AuthKeyData* candidate;
+
+    // First try to find a un-expired key..
+    candidate = findAuthKey_(allowUsingExhaustedKeys, false);
+    if (candidate == nullptr) {
+        // That didn't work, there are no un-expired keys and we don't allow using expired keys.
+        if (!allowUsingExpiredKeys) {
+            return nullptr;
+        }
+
+        // See if there's an expired key then...
+        candidate = findAuthKey_(allowUsingExhaustedKeys, true);
+        if (candidate == nullptr) {
+            return nullptr;
+        }
+    }
+
     candidate->useCount += 1;
     return candidate;
 }
@@ -519,8 +565,14 @@
 
     vector<vector<uint8_t>> keysNeedingCert;
 
+    int64_t nowMilliSeconds =
+        std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) * 1000;
+
     for (AuthKeyData& data : authKeyDatas_) {
-        bool newKeyNeeded = (data.certificate.size() == 0) || (data.useCount >= maxUsesPerKey_);
+        bool keyExceedUseCount = (data.useCount >= maxUsesPerKey_);
+        bool keyBeyondExpirationDate = (nowMilliSeconds > data.expirationDateMillisSinceEpoch);
+        bool newKeyNeeded =
+            (data.certificate.size() == 0) || keyExceedUseCount || keyBeyondExpirationDate;
         bool certificationPending = (data.pendingCertificate.size() > 0);
         if (newKeyNeeded && !certificationPending) {
             vector<uint8_t> signingKeyBlob;
@@ -543,11 +595,13 @@
 }
 
 bool CredentialData::storeStaticAuthenticationData(const vector<uint8_t>& authenticationKey,
+                                                   int64_t expirationDateMillisSinceEpoch,
                                                    const vector<uint8_t>& staticAuthData) {
     for (AuthKeyData& data : authKeyDatas_) {
         if (data.pendingCertificate == authenticationKey) {
             data.certificate = data.pendingCertificate;
             data.keyBlob = data.pendingKeyBlob;
+            data.expirationDateMillisSinceEpoch = expirationDateMillisSinceEpoch;
             data.staticAuthenticationData = staticAuthData;
             data.pendingCertificate.clear();
             data.pendingKeyBlob.clear();
diff --git a/identity/CredentialData.h b/identity/CredentialData.h
index 7995828..24b55d3 100644
--- a/identity/CredentialData.h
+++ b/identity/CredentialData.h
@@ -55,6 +55,7 @@
 
     vector<uint8_t> certificate;
     vector<uint8_t> keyBlob;
+    int64_t expirationDateMillisSinceEpoch = 0;
     vector<uint8_t> staticAuthenticationData;
     vector<uint8_t> pendingCertificate;
     vector<uint8_t> pendingKeyBlob;
@@ -106,17 +107,22 @@
 
     const vector<AuthKeyData>& getAuthKeyDatas() const;
 
+    pair<int /* keyCount */, int /*maxUsersPerKey */> getAvailableAuthenticationKeys();
+
     // Returns |nullptr| if a suitable key cannot be found. Otherwise returns
     // the authentication and increases its use-count.
-    const AuthKeyData* selectAuthKey(bool allowUsingExhaustedKeys);
+    const AuthKeyData* selectAuthKey(bool allowUsingExhaustedKeys, bool allowUsingExpiredKeys);
 
     optional<vector<vector<uint8_t>>>
     getAuthKeysNeedingCertification(const sp<IIdentityCredential>& halBinder);
 
     bool storeStaticAuthenticationData(const vector<uint8_t>& authenticationKey,
+                                       int64_t expirationDateMillisSinceEpoch,
                                        const vector<uint8_t>& staticAuthData);
 
   private:
+    AuthKeyData* findAuthKey_(bool allowUsingExhaustedKeys, bool allowUsingExpiredKeys);
+
     // Set by constructor.
     //
     string dataPath_;
diff --git a/identity/CredentialStore.cpp b/identity/CredentialStore.cpp
index e3a825b..071cf24 100644
--- a/identity/CredentialStore.cpp
+++ b/identity/CredentialStore.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CredentialStore"
+#define LOG_TAG "credstore"
 
 #include <algorithm>
 
@@ -41,11 +41,12 @@
         LOG(ERROR) << "Error getting hardware information: " << status.toString8();
         return false;
     }
+    halApiVersion_ = hal_->getInterfaceVersion();
 
-    LOG(INFO) << "Connected to Identity Credential HAL with name '" << hwInfo_.credentialStoreName
-              << "' authored by '" << hwInfo_.credentialStoreAuthorName << "' with chunk size "
-              << hwInfo_.dataChunkSize << " and directoAccess set to "
-              << (hwInfo_.isDirectAccess ? "true" : "false");
+    LOG(INFO) << "Connected to Identity Credential HAL with API version " << halApiVersion_
+              << " and name '" << hwInfo_.credentialStoreName << "' authored by '"
+              << hwInfo_.credentialStoreAuthorName << "' with chunk size " << hwInfo_.dataChunkSize
+              << " and directoAccess set to " << (hwInfo_.isDirectAccess ? "true" : "false");
     return true;
 }
 
@@ -89,7 +90,7 @@
     }
 
     sp<IWritableCredential> writableCredential = new WritableCredential(
-        dataPath_, credentialName, docType, hwInfo_.dataChunkSize, halWritableCredential);
+        dataPath_, credentialName, docType, false, hwInfo_, halWritableCredential);
     *_aidl_return = writableCredential;
     return Status::ok();
 }
@@ -112,9 +113,10 @@
 
     // Note: IdentityCredentialStore.java's CipherSuite enumeration and CipherSuite from the
     // HAL is manually kept in sync. So this cast is safe.
-    sp<Credential> credential = new Credential(CipherSuite(cipherSuite), dataPath_, credentialName);
+    sp<Credential> credential = new Credential(CipherSuite(cipherSuite), dataPath_, credentialName,
+                                               callingUid, hwInfo_, hal_, halApiVersion_);
 
-    Status loadStatus = credential->loadCredential(hal_);
+    Status loadStatus = credential->ensureOrReplaceHalBinder();
     if (!loadStatus.isOk()) {
         LOG(ERROR) << "Error loading credential";
     } else {
diff --git a/identity/CredentialStore.h b/identity/CredentialStore.h
index 24b2b4d..15da4eb 100644
--- a/identity/CredentialStore.h
+++ b/identity/CredentialStore.h
@@ -57,6 +57,7 @@
     string dataPath_;
 
     sp<IIdentityCredentialStore> hal_;
+    int halApiVersion_;
 
     HardwareInformation hwInfo_;
 };
diff --git a/identity/CredentialStoreFactory.cpp b/identity/CredentialStoreFactory.cpp
index 5c3bf36..0e901ba 100644
--- a/identity/CredentialStoreFactory.cpp
+++ b/identity/CredentialStoreFactory.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CredentialStoreFactory"
+#define LOG_TAG "credstore"
 
 #include <android-base/logging.h>
 
diff --git a/identity/TEST_MAPPING b/identity/TEST_MAPPING
new file mode 100644
index 0000000..87707a8
--- /dev/null
+++ b/identity/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsIdentityTestCases"
+    }
+  ]
+}
diff --git a/identity/Util.cpp b/identity/Util.cpp
index a962dc3..3a46bca 100644
--- a/identity/Util.cpp
+++ b/identity/Util.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "Util"
+#define LOG_TAG "credstore"
 
 #include <fcntl.h>
 #include <stdlib.h>
@@ -110,7 +110,7 @@
         remaining -= numWritten;
     }
 
-    if (TEMP_FAILURE_RETRY(fsync(fd) == -1)) {
+    if (TEMP_FAILURE_RETRY(fsync(fd))) {
         PLOG(ERROR) << "Failed fsyncing temp file for '" << path << "'";
         close(fd);
         return false;
diff --git a/identity/WritableCredential.cpp b/identity/WritableCredential.cpp
index a932dcf..9827d75 100644
--- a/identity/WritableCredential.cpp
+++ b/identity/WritableCredential.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "WritableCredential"
+#define LOG_TAG "credstore"
 
 #include <android-base/logging.h>
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
@@ -39,13 +39,18 @@
 using ::android::hardware::identity::support::chunkVector;
 
 WritableCredential::WritableCredential(const string& dataPath, const string& credentialName,
-                                       const string& docType, size_t dataChunkSize,
+                                       const string& docType, bool isUpdate,
+                                       HardwareInformation hwInfo,
                                        sp<IWritableIdentityCredential> halBinder)
-    : dataPath_(dataPath), credentialName_(credentialName), docType_(docType),
-      dataChunkSize_(dataChunkSize), halBinder_(halBinder) {}
+    : dataPath_(dataPath), credentialName_(credentialName), docType_(docType), isUpdate_(isUpdate),
+      hwInfo_(std::move(hwInfo)), halBinder_(halBinder) {}
 
 WritableCredential::~WritableCredential() {}
 
+void WritableCredential::setCredentialToReloadWhenUpdated(sp<Credential> credential) {
+    credentialToReloadWhenUpdated_ = credential;
+}
+
 Status WritableCredential::ensureAttestationCertificateExists(const vector<uint8_t>& challenge) {
     if (!attestationCertificate_.empty()) {
         return Status::ok();
@@ -79,7 +84,10 @@
 
 Status WritableCredential::getCredentialKeyCertificateChain(const vector<uint8_t>& challenge,
                                                             vector<uint8_t>* _aidl_return) {
-
+    if (isUpdate_) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Cannot be called for an update");
+    }
     Status ensureStatus = ensureAttestationCertificateExists(challenge);
     if (!ensureStatus.isOk()) {
         return ensureStatus;
@@ -89,6 +97,15 @@
     return Status::ok();
 }
 
+void WritableCredential::setAttestationCertificate(const vector<uint8_t>& attestationCertificate) {
+    attestationCertificate_ = attestationCertificate;
+}
+
+void WritableCredential::setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey) {
+    keyCount_ = keyCount;
+    maxUsesPerKey_ = maxUsesPerKey;
+}
+
 ssize_t WritableCredential::calcExpectedProofOfProvisioningSize(
     const vector<AccessControlProfileParcel>& accessControlProfiles,
     const vector<EntryNamespaceParcel>& entryNamespaces) {
@@ -149,9 +166,12 @@
 WritableCredential::personalize(const vector<AccessControlProfileParcel>& accessControlProfiles,
                                 const vector<EntryNamespaceParcel>& entryNamespaces,
                                 int64_t secureUserId, vector<uint8_t>* _aidl_return) {
-    Status ensureStatus = ensureAttestationCertificateExists({0x00});  // Challenge cannot be empty.
-    if (!ensureStatus.isOk()) {
-        return ensureStatus;
+    if (!isUpdate_) {
+        Status ensureStatus =
+            ensureAttestationCertificateExists({0x00});  // Challenge cannot be empty.
+        if (!ensureStatus.isOk()) {
+            return ensureStatus;
+        }
     }
 
     uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
@@ -203,7 +223,7 @@
 
     for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
         for (const EntryParcel& eParcel : ensParcel.entries) {
-            vector<vector<uint8_t>> chunks = chunkVector(eParcel.value, dataChunkSize_);
+            vector<vector<uint8_t>> chunks = chunkVector(eParcel.value, hwInfo_.dataChunkSize);
 
             vector<int32_t> ids;
             std::copy(eParcel.accessControlProfileIds.begin(),
@@ -240,11 +260,18 @@
     }
     data.setCredentialData(credentialData);
 
+    data.setAvailableAuthenticationKeys(keyCount_, maxUsesPerKey_);
+
     if (!data.saveToDisk()) {
         return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
                                                 "Error saving credential data to disk");
     }
 
+    if (credentialToReloadWhenUpdated_) {
+        credentialToReloadWhenUpdated_->writableCredentialPersonalized();
+        credentialToReloadWhenUpdated_.clear();
+    }
+
     *_aidl_return = proofOfProvisioningSignature;
     return Status::ok();
 }
diff --git a/identity/WritableCredential.h b/identity/WritableCredential.h
index eb63aca..838b956 100644
--- a/identity/WritableCredential.h
+++ b/identity/WritableCredential.h
@@ -24,11 +24,14 @@
 
 #include <android/hardware/identity/IIdentityCredentialStore.h>
 
+#include "Credential.h"
+
 namespace android {
 namespace security {
 namespace identity {
 
 using ::android::binder::Status;
+using ::android::hardware::identity::HardwareInformation;
 using ::android::hardware::identity::IWritableIdentityCredential;
 using ::std::string;
 using ::std::vector;
@@ -36,9 +39,17 @@
 class WritableCredential : public BnWritableCredential {
   public:
     WritableCredential(const string& dataPath, const string& credentialName, const string& docType,
-                       size_t dataChunkSize, sp<IWritableIdentityCredential> halBinder);
+                       bool isUpdate, HardwareInformation hwInfo,
+                       sp<IWritableIdentityCredential> halBinder);
     ~WritableCredential();
 
+    // Used when updating a credential
+    void setAttestationCertificate(const vector<uint8_t>& attestationCertificate);
+    void setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey);
+
+    // Used by Credential::update()
+    void setCredentialToReloadWhenUpdated(sp<Credential> credential);
+
     // IWritableCredential overrides
     Status getCredentialKeyCertificateChain(const vector<uint8_t>& challenge,
                                             vector<uint8_t>* _aidl_return) override;
@@ -51,9 +62,15 @@
     string dataPath_;
     string credentialName_;
     string docType_;
-    size_t dataChunkSize_;
+    bool isUpdate_;
+    HardwareInformation hwInfo_;
     sp<IWritableIdentityCredential> halBinder_;
+
     vector<uint8_t> attestationCertificate_;
+    int keyCount_ = 0;
+    int maxUsesPerKey_ = 1;
+
+    sp<Credential> credentialToReloadWhenUpdated_;
 
     ssize_t calcExpectedProofOfProvisioningSize(
         const vector<AccessControlProfileParcel>& accessControlProfiles,
diff --git a/identity/binder/android/security/identity/ICredential.aidl b/identity/binder/android/security/identity/ICredential.aidl
index 7bd0df7..2165810 100644
--- a/identity/binder/android/security/identity/ICredential.aidl
+++ b/identity/binder/android/security/identity/ICredential.aidl
@@ -16,6 +16,8 @@
 
 package android.security.identity;
 
+import android.security.identity.IWritableCredential;
+
 import android.security.identity.RequestNamespaceParcel;
 import android.security.identity.GetEntriesResultParcel;
 import android.security.identity.AuthKeyParcel;
@@ -40,23 +42,35 @@
     void setReaderEphemeralPublicKey(in byte[] publicKey);
 
     byte[] deleteCredential();
+    byte[] deleteWithChallenge(in byte[] challenge);
+
+    byte[] proveOwnership(in byte[] challenge);
 
     byte[] getCredentialKeyCertificateChain();
 
-    long selectAuthKey(in boolean allowUsingExhaustedKeys);
+    long selectAuthKey(in boolean allowUsingExhaustedKeys,
+                       in boolean allowUsingExpiredKeys);
 
     GetEntriesResultParcel getEntries(in byte[] requestMessage,
                                       in RequestNamespaceParcel[] requestNamespaces,
                                       in byte[] sessionTranscript,
                                       in byte[] readerSignature,
-                                      in boolean allowUsingExhaustedKeys);
+                                      in boolean allowUsingExhaustedKeys,
+                                      in boolean allowUsingExpiredKeys);
 
     void setAvailableAuthenticationKeys(in int keyCount, in int maxUsesPerKey);
 
     AuthKeyParcel[] getAuthKeysNeedingCertification();
 
-    void storeStaticAuthenticationData(in AuthKeyParcel authenticationKey, in byte[] staticAuthData);
+    void storeStaticAuthenticationData(in AuthKeyParcel authenticationKey,
+                                       in byte[] staticAuthData);
+
+    void storeStaticAuthenticationDataWithExpiration(in AuthKeyParcel authenticationKey,
+                                       in long expirationDateMillisSinceEpoch,
+                                       in byte[] staticAuthData);
 
     int[] getAuthenticationDataUsageCount();
+
+    IWritableCredential update();
 }
 
diff --git a/identity/binder/android/security/identity/ICredentialStore.aidl b/identity/binder/android/security/identity/ICredentialStore.aidl
index 1039831..8357f47 100644
--- a/identity/binder/android/security/identity/ICredentialStore.aidl
+++ b/identity/binder/android/security/identity/ICredentialStore.aidl
@@ -39,6 +39,7 @@
     const int ERROR_AUTHENTICATION_KEY_NOT_FOUND = 9;
     const int ERROR_INVALID_ITEMS_REQUEST_MESSAGE = 10;
     const int ERROR_SESSION_TRANSCRIPT_MISMATCH = 11;
+    const int ERROR_NOT_SUPPORTED = 12;
 
     SecurityHardwareInfoParcel getSecurityHardwareInfo();
 
diff --git a/identity/main.cpp b/identity/main.cpp
index 8f4968d..2559789 100644
--- a/identity/main.cpp
+++ b/identity/main.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.security.identity"
+#define LOG_TAG "credstore"
 
 #include <filesystem>
 
@@ -40,7 +40,7 @@
 using ::android::security::identity::CredentialStoreFactory;
 
 int main(int argc, char* argv[]) {
-    InitLogging(argv, StderrLogger);
+    InitLogging(argv);
 
     CHECK(argc == 2) << "A directory must be specified";
     string data_dir = string(argv[1]);
@@ -51,11 +51,10 @@
 
     auto ret = sm->addService(String16("android.security.identity"), factory);
     CHECK(ret == ::android::OK) << "Couldn't register binder service";
-    LOG(ERROR) << "Registered binder service";
+    LOG(INFO) << "Registered binder service";
 
-    // This is needed for binder callbacks from keystore on a ICredstoreTokenCallback binder.
-    android::ProcessState::self()->startThreadPool();
-
+    // Credstore is a single-threaded process. So devote the main thread
+    // to handling binder messages.
     IPCThreadState::self()->joinThreadPool();
 
     return 0;
diff --git a/keystore-engine/Android.bp b/keystore-engine/Android.bp
index 6512c66..0cecfd8 100644
--- a/keystore-engine/Android.bp
+++ b/keystore-engine/Android.bp
@@ -12,12 +12,21 @@
 // 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",
 
     srcs: [
         "android_engine.cpp",
-        "keystore_backend_binder.cpp",
+        "keystore2_engine.cpp",
     ],
 
     cflags: [
@@ -27,13 +36,10 @@
     ],
 
     shared_libs: [
-        "libbinder",
+        "android.system.keystore2-V1-ndk_platform",
+        "libbinder_ndk",
         "libcrypto",
         "libcutils",
-        "libhidlbase",
-        "libkeystore_aidl",
-        "libkeystore_binder",
-        "libkeystore_parcelables",
         "liblog",
         "libbase",
         "libutils",
@@ -41,28 +47,30 @@
 
 }
 
-// This builds a variant of libkeystore-engine that uses a HIDL HAL
-// owned by the WiFi user to perform signing operations.
+// This builds a variant of libkeystore-engine that is available vendor.
+// It used to use a HIDL interface to connect to keystore through wificond.
+// Now That Keystore 2.0 has a vintf stable interface this library is
+// actually identical to libkeystore-engine.
 cc_library_shared {
     name: "libkeystore-engine-wifi-hidl",
 
     srcs: [
         "android_engine.cpp",
-        "keystore_backend_hidl.cpp",
+        "keystore2_engine.cpp",
     ],
 
     cflags: [
         "-fvisibility=hidden",
         "-Wall",
         "-Werror",
-        "-DBACKEND_WIFI_HIDL",
     ],
 
     shared_libs: [
-        "android.system.wifi.keystore@1.0",
+        "android.system.keystore2-V1-ndk_platform",
+        "libbase",
+        "libbinder_ndk",
         "libcrypto",
         "liblog",
-        "libhidlbase",
         "libcutils",
         "libutils",
     ],
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index e3525b2..e46204e 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -22,307 +22,9 @@
 
 #define LOG_TAG "keystore-engine"
 
-#include <pthread.h>
-#include <sys/socket.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-
 #include <log/log.h>
 
-#include <openssl/bn.h>
-#include <openssl/ec.h>
-#include <openssl/ec_key.h>
-#include <openssl/ecdsa.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <openssl/x509.h>
-
-#include <memory>
-
-#ifndef BACKEND_WIFI_HIDL
-#include "keystore_backend_binder.h"
-#else
-#include "keystore_backend_hidl.h"
-#endif
-
-namespace {
-KeystoreBackend *g_keystore_backend;
-void ensure_keystore_engine();
-
-/* key_id_dup is called when one of the RSA or EC_KEY objects is duplicated. */
-int key_id_dup(CRYPTO_EX_DATA* /* to */,
-               const CRYPTO_EX_DATA* /* from */,
-               void** from_d,
-               int /* index */,
-               long /* argl */,
-               void* /* argp */) {
-    char *key_id = reinterpret_cast<char *>(*from_d);
-    if (key_id != nullptr) {
-        *from_d = strdup(key_id);
-    }
-    return 1;
-}
-
-/* key_id_free is called when one of the RSA, DSA or EC_KEY object is freed. */
-void key_id_free(void* /* parent */,
-                 void* ptr,
-                 CRYPTO_EX_DATA* /* ad */,
-                 int /* index */,
-                 long /* argl */,
-                 void* /* argp */) {
-    char *key_id = reinterpret_cast<char *>(ptr);
-    free(key_id);
-}
-
-/* Many OpenSSL APIs take ownership of an argument on success but don't free
- * the argument on failure. This means we need to tell our scoped pointers when
- * we've transferred ownership, without triggering a warning by not using the
- * result of release(). */
-#define OWNERSHIP_TRANSFERRED(obj) auto _dummy __attribute__((unused)) = (obj).release()
-
-const char* rsa_get_key_id(const RSA* rsa);
-
-/* rsa_private_transform takes a big-endian integer from |in|, calculates the
- * d'th power of it, modulo the RSA modulus, and writes the result as a
- * big-endian integer to |out|. Both |in| and |out| are |len| bytes long. It
- * returns one on success and zero otherwise. */
-int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) {
-    ALOGV("rsa_private_transform(%p, %p, %p, %u)", rsa, out, in, (unsigned) len);
-
-    ensure_keystore_engine();
-
-    const char *key_id = rsa_get_key_id(rsa);
-    if (key_id == nullptr) {
-        ALOGE("key had no key_id!");
-        return 0;
-    }
-
-    uint8_t* reply = nullptr;
-    size_t reply_len;
-    int32_t ret = g_keystore_backend->sign(key_id, in, len, &reply, &reply_len);
-    if (ret < 0) {
-        ALOGW("There was an error during rsa_decrypt: could not connect");
-        return 0;
-    } else if (ret != 0) {
-        ALOGW("Error during sign from keystore: %d", ret);
-        return 0;
-    } else if (reply_len == 0 || reply == nullptr) {
-        ALOGW("No valid signature returned");
-        return 0;
-    }
-
-    if (reply_len > len) {
-        /* The result of the RSA operation can never be larger than the size of
-         * the modulus so we assume that the result has extra zeros on the
-         * left. This provides attackers with an oracle, but there's nothing
-         * that we can do about it here. */
-        ALOGW("Reply len %zu greater than expected %zu", reply_len, len);
-        memcpy(out, &reply[reply_len - len], len);
-    } else if (reply_len < len) {
-        /* If the Keystore implementation returns a short value we assume that
-         * it's because it removed leading zeros from the left side. This is
-         * bad because it provides attackers with an oracle but we cannot do
-         * anything about a broken Keystore implementation here. */
-        ALOGW("Reply len %zu lesser than expected %zu", reply_len, len);
-        memset(out, 0, len);
-        memcpy(out + len - reply_len, &reply[0], reply_len);
-    } else {
-        memcpy(out, &reply[0], len);
-    }
-
-    ALOGV("rsa=%p keystore_rsa_priv_dec successful", rsa);
-    return 1;
-}
-
-const char* ecdsa_get_key_id(const EC_KEY* ec_key);
-
-/* ecdsa_sign signs |digest_len| bytes from |digest| with |ec_key| and writes
- * the resulting signature (an ASN.1 encoded blob) to |sig|. It returns one on
- * success and zero otherwise. */
-static int ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
-                      unsigned int* sig_len, EC_KEY* ec_key) {
-    ALOGV("ecdsa_sign(%p, %u, %p)", digest, (unsigned) digest_len, ec_key);
-
-    ensure_keystore_engine();
-
-    const char *key_id = ecdsa_get_key_id(ec_key);
-    if (key_id == nullptr) {
-        ALOGE("key had no key_id!");
-        return 0;
-    }
-
-    size_t ecdsa_size = ECDSA_size(ec_key);
-
-    uint8_t* reply = nullptr;
-    size_t reply_len;
-    int32_t ret = g_keystore_backend->sign(
-            key_id, digest, digest_len, &reply, &reply_len);
-    if (ret < 0) {
-        ALOGW("There was an error during ecdsa_sign: could not connect");
-        return 0;
-    } else if (reply_len == 0 || reply == nullptr) {
-        ALOGW("No valid signature returned");
-        return 0;
-    } else if (reply_len > ecdsa_size) {
-        ALOGW("Signature is too large");
-        return 0;
-    }
-
-    // Reviewer: should't sig_len be checked here? Or is it just assumed that it is at least ecdsa_size?
-    memcpy(sig, &reply[0], reply_len);
-    *sig_len = reply_len;
-
-    ALOGV("ecdsa_sign(%p, %u, %p) => success", digest, (unsigned)digest_len,
-          ec_key);
-    return 1;
-}
-
-/* KeystoreEngine is a BoringSSL ENGINE that implements RSA and ECDSA by
- * forwarding the requested operations to Keystore. */
-class KeystoreEngine {
- public:
-  KeystoreEngine()
-      : rsa_index_(RSA_get_ex_new_index(0 /* argl */,
-                                        nullptr /* argp */,
-                                        nullptr /* new_func */,
-                                        key_id_dup,
-                                        key_id_free)),
-        ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */,
-                                              nullptr /* argp */,
-                                              nullptr /* new_func */,
-                                              key_id_dup,
-                                              key_id_free)),
-        engine_(ENGINE_new()) {
-    memset(&rsa_method_, 0, sizeof(rsa_method_));
-    rsa_method_.common.is_static = 1;
-    rsa_method_.private_transform = rsa_private_transform;
-    rsa_method_.flags = RSA_FLAG_OPAQUE;
-    ENGINE_set_RSA_method(engine_, &rsa_method_, sizeof(rsa_method_));
-
-    memset(&ecdsa_method_, 0, sizeof(ecdsa_method_));
-    ecdsa_method_.common.is_static = 1;
-    ecdsa_method_.sign = ecdsa_sign;
-    ecdsa_method_.flags = ECDSA_FLAG_OPAQUE;
-    ENGINE_set_ECDSA_method(engine_, &ecdsa_method_, sizeof(ecdsa_method_));
-  }
-
-  int rsa_ex_index() const { return rsa_index_; }
-  int ec_key_ex_index() const { return ec_key_index_; }
-
-  const ENGINE* engine() const { return engine_; }
-
- private:
-  const int rsa_index_;
-  const int ec_key_index_;
-  RSA_METHOD rsa_method_;
-  ECDSA_METHOD ecdsa_method_;
-  ENGINE* const engine_;
-};
-
-pthread_once_t g_keystore_engine_once = PTHREAD_ONCE_INIT;
-KeystoreEngine *g_keystore_engine;
-
-/* init_keystore_engine is called to initialize |g_keystore_engine|. This
- * should only be called by |pthread_once|. */
-void init_keystore_engine() {
-  g_keystore_engine = new KeystoreEngine;
-#ifndef BACKEND_WIFI_HIDL
-  g_keystore_backend = new KeystoreBackendBinder;
-#else
-  g_keystore_backend = new KeystoreBackendHidl;
-#endif
-}
-
-/* ensure_keystore_engine ensures that |g_keystore_engine| is pointing to a
- * valid |KeystoreEngine| object and creates one if not. */
-void ensure_keystore_engine() {
-  pthread_once(&g_keystore_engine_once, init_keystore_engine);
-}
-
-const char* rsa_get_key_id(const RSA* rsa) {
-  return reinterpret_cast<char*>(
-      RSA_get_ex_data(rsa, g_keystore_engine->rsa_ex_index()));
-}
-
-const char* ecdsa_get_key_id(const EC_KEY* ec_key) {
-  return reinterpret_cast<char*>(
-      EC_KEY_get_ex_data(ec_key, g_keystore_engine->ec_key_ex_index()));
-}
-
-/* wrap_rsa returns an |EVP_PKEY| that contains an RSA key where the public
- * part is taken from |public_rsa| and the private operations are forwarded to
- * KeyStore and operate on the key named |key_id|. */
-static EVP_PKEY *wrap_rsa(const char *key_id, const RSA *public_rsa) {
-    bssl::UniquePtr<RSA> rsa(RSA_new_method(g_keystore_engine->engine()));
-    if (rsa.get() == nullptr) {
-        return nullptr;
-    }
-
-    char *key_id_copy = strdup(key_id);
-    if (key_id_copy == nullptr) {
-        return nullptr;
-    }
-
-    if (!RSA_set_ex_data(rsa.get(), g_keystore_engine->rsa_ex_index(),
-                         key_id_copy)) {
-        free(key_id_copy);
-        return nullptr;
-    }
-
-    rsa->n = BN_dup(public_rsa->n);
-    rsa->e = BN_dup(public_rsa->e);
-    if (rsa->n == nullptr || rsa->e == nullptr) {
-        return nullptr;
-    }
-
-    bssl::UniquePtr<EVP_PKEY> result(EVP_PKEY_new());
-    if (result.get() == nullptr ||
-        !EVP_PKEY_assign_RSA(result.get(), rsa.get())) {
-        return nullptr;
-    }
-    OWNERSHIP_TRANSFERRED(rsa);
-
-    return result.release();
-}
-
-/* wrap_ecdsa returns an |EVP_PKEY| that contains an ECDSA key where the public
- * part is taken from |public_rsa| and the private operations are forwarded to
- * KeyStore and operate on the key named |key_id|. */
-static EVP_PKEY *wrap_ecdsa(const char *key_id, const EC_KEY *public_ecdsa) {
-    bssl::UniquePtr<EC_KEY> ec(EC_KEY_new_method(g_keystore_engine->engine()));
-    if (ec.get() == nullptr) {
-        return nullptr;
-    }
-
-    if (!EC_KEY_set_group(ec.get(), EC_KEY_get0_group(public_ecdsa)) ||
-        !EC_KEY_set_public_key(ec.get(), EC_KEY_get0_public_key(public_ecdsa))) {
-        return nullptr;
-    }
-
-    char *key_id_copy = strdup(key_id);
-    if (key_id_copy == nullptr) {
-        return nullptr;
-    }
-
-    if (!EC_KEY_set_ex_data(ec.get(), g_keystore_engine->ec_key_ex_index(),
-                            key_id_copy)) {
-        free(key_id_copy);
-        return nullptr;
-    }
-
-    bssl::UniquePtr<EVP_PKEY> result(EVP_PKEY_new());
-    if (result.get() == nullptr ||
-        !EVP_PKEY_assign_EC_KEY(result.get(), ec.get())) {
-        return nullptr;
-    }
-    OWNERSHIP_TRANSFERRED(ec);
-
-    return result.release();
-}
-
-}  /* anonymous namespace */
+#include "keystore2_engine.h"
 
 extern "C" {
 
@@ -335,44 +37,7 @@
 EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id) {
     ALOGV("EVP_PKEY_from_keystore(\"%s\")", key_id);
 
-    ensure_keystore_engine();
-
-    uint8_t *pubkey = nullptr;
-    size_t pubkey_len;
-    int32_t ret = g_keystore_backend->get_pubkey(key_id, &pubkey, &pubkey_len);
-    if (ret < 0) {
-        ALOGW("could not contact keystore");
-        return nullptr;
-    } else if (ret != 0 || pubkey == nullptr) {
-        ALOGW("keystore reports error: %d", ret);
-        return nullptr;
-    }
-
-    const uint8_t *inp = pubkey;
-    bssl::UniquePtr<EVP_PKEY> pkey(d2i_PUBKEY(nullptr, &inp, pubkey_len));
-    if (pkey.get() == nullptr) {
-        ALOGW("Cannot convert pubkey");
-        return nullptr;
-    }
-
-    EVP_PKEY *result;
-    switch (EVP_PKEY_type(pkey->type)) {
-    case EVP_PKEY_RSA: {
-        bssl::UniquePtr<RSA> public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
-        result = wrap_rsa(key_id, public_rsa.get());
-        break;
-    }
-    case EVP_PKEY_EC: {
-        bssl::UniquePtr<EC_KEY> public_ecdsa(EVP_PKEY_get1_EC_KEY(pkey.get()));
-        result = wrap_ecdsa(key_id, public_ecdsa.get());
-        break;
-    }
-    default:
-        ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
-        result = nullptr;
-    }
-
-    return result;
+    return EVP_PKEY_from_keystore2(key_id);
 }
 
 }  // extern "C"
diff --git a/keystore-engine/keystore2_engine.cpp b/keystore-engine/keystore2_engine.cpp
new file mode 100644
index 0000000..69d2ca6
--- /dev/null
+++ b/keystore-engine/keystore2_engine.cpp
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2021 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 "keystore2_engine.h"
+
+#include <aidl/android/system/keystore2/IKeystoreService.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <android/binder_manager.h>
+
+#include <private/android_filesystem_config.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
+#include <openssl/engine.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+
+#define AT __func__ << ":" << __LINE__ << " "
+
+constexpr const char keystore2_service_name[] = "android.system.keystore2.IKeystoreService/default";
+const std::string keystore2_grant_id_prefix("ks2_keystore-engine_grant_id:");
+
+/**
+ * Keystore 2.0 namespace identifiers.
+ * Keep in sync with system/sepolicy/private/keystore2_key_contexts.
+ */
+constexpr const int64_t KS2_NAMESPACE_WIFI = 102;
+
+namespace ks2 = ::aidl::android::system::keystore2;
+namespace KMV1 = ::aidl::android::hardware::security::keymint;
+
+namespace {
+
+int64_t getNamespaceforCurrentUid() {
+    auto uid = getuid();
+    switch (uid) {
+    case AID_WIFI:
+        return KS2_NAMESPACE_WIFI;
+    // 0 is the super user namespace, and nothing has access to this namespace on user builds.
+    // So this will always fail.
+    default:
+        return 0;
+    }
+}
+
+struct Keystore2KeyBackend {
+    ks2::KeyDescriptor descriptor_;
+    std::shared_ptr<ks2::IKeystoreSecurityLevel> i_keystore_security_level_;
+};
+
+/* key_backend_dup is called when one of the RSA or EC_KEY objects is duplicated. */
+extern "C" int key_backend_dup(CRYPTO_EX_DATA* /* to */, const CRYPTO_EX_DATA* /* from */,
+                               void** from_d, int /* index */, long /* argl */, void* /* argp */) {
+    auto key_backend = reinterpret_cast<std::shared_ptr<Keystore2KeyBackend>*>(*from_d);
+    if (key_backend != nullptr) {
+        *from_d = new std::shared_ptr<Keystore2KeyBackend>(*key_backend);
+    }
+    return 1;
+}
+
+/* key_backend_free is called when one of the RSA, DSA or EC_KEY object is freed. */
+extern "C" void key_backend_free(void* /* parent */, void* ptr, CRYPTO_EX_DATA* /* ad */,
+                                 int /* index */, long /* argl */, void* /* argp */) {
+    delete reinterpret_cast<std::shared_ptr<Keystore2KeyBackend>*>(ptr);
+}
+
+extern "C" int rsa_private_transform(RSA* rsa, uint8_t* out, const uint8_t* in, size_t len);
+extern "C" int ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                          unsigned int* sig_len, EC_KEY* ec_key);
+/* KeystoreEngine is a BoringSSL ENGINE that implements RSA and ECDSA by
+ * forwarding the requested operations to Keystore. */
+class Keystore2Engine {
+  public:
+    Keystore2Engine()
+        : rsa_index_(RSA_get_ex_new_index(0 /* argl */, nullptr /* argp */, nullptr /* new_func */,
+                                          key_backend_dup, key_backend_free)),
+          ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */, nullptr /* argp */,
+                                                nullptr /* new_func */, key_backend_dup,
+                                                key_backend_free)),
+          engine_(ENGINE_new()) {
+        memset(&rsa_method_, 0, sizeof(rsa_method_));
+        rsa_method_.common.is_static = 1;
+        rsa_method_.private_transform = rsa_private_transform;
+        rsa_method_.flags = RSA_FLAG_OPAQUE;
+        ENGINE_set_RSA_method(engine_, &rsa_method_, sizeof(rsa_method_));
+
+        memset(&ecdsa_method_, 0, sizeof(ecdsa_method_));
+        ecdsa_method_.common.is_static = 1;
+        ecdsa_method_.sign = ecdsa_sign;
+        ecdsa_method_.flags = ECDSA_FLAG_OPAQUE;
+        ENGINE_set_ECDSA_method(engine_, &ecdsa_method_, sizeof(ecdsa_method_));
+    }
+
+    int rsa_ex_index() const { return rsa_index_; }
+    int ec_key_ex_index() const { return ec_key_index_; }
+
+    const ENGINE* engine() const { return engine_; }
+
+    static const Keystore2Engine& get() {
+        static Keystore2Engine engine;
+        return engine;
+    }
+
+  private:
+    const int rsa_index_;
+    const int ec_key_index_;
+    RSA_METHOD rsa_method_;
+    ECDSA_METHOD ecdsa_method_;
+    ENGINE* const engine_;
+};
+
+#define OWNERSHIP_TRANSFERRED(x) x.release()
+
+/* wrap_rsa returns an |EVP_PKEY| that contains an RSA key where the public
+ * part is taken from |public_rsa| and the private operations are forwarded to
+ * KeyStore and operate on the key named |key_id|. */
+bssl::UniquePtr<EVP_PKEY> wrap_rsa(std::shared_ptr<Keystore2KeyBackend> key_backend,
+                                   const RSA* public_rsa) {
+    bssl::UniquePtr<RSA> rsa(RSA_new_method(Keystore2Engine::get().engine()));
+    if (rsa.get() == nullptr) {
+        return nullptr;
+    }
+
+    auto key_backend_copy = new decltype(key_backend)(key_backend);
+
+    if (!RSA_set_ex_data(rsa.get(), Keystore2Engine::get().rsa_ex_index(), key_backend_copy)) {
+        delete key_backend_copy;
+        return nullptr;
+    }
+
+    rsa->n = BN_dup(public_rsa->n);
+    rsa->e = BN_dup(public_rsa->e);
+    if (rsa->n == nullptr || rsa->e == nullptr) {
+        return nullptr;
+    }
+
+    bssl::UniquePtr<EVP_PKEY> result(EVP_PKEY_new());
+    if (result.get() == nullptr || !EVP_PKEY_assign_RSA(result.get(), rsa.get())) {
+        return nullptr;
+    }
+    OWNERSHIP_TRANSFERRED(rsa);
+
+    return result;
+}
+
+/* wrap_ecdsa returns an |EVP_PKEY| that contains an ECDSA key where the public
+ * part is taken from |public_rsa| and the private operations are forwarded to
+ * KeyStore and operate on the key named |key_id|. */
+bssl::UniquePtr<EVP_PKEY> wrap_ecdsa(std::shared_ptr<Keystore2KeyBackend> key_backend,
+                                     const EC_KEY* public_ecdsa) {
+    bssl::UniquePtr<EC_KEY> ec(EC_KEY_new_method(Keystore2Engine::get().engine()));
+    if (ec.get() == nullptr) {
+        return nullptr;
+    }
+
+    if (!EC_KEY_set_group(ec.get(), EC_KEY_get0_group(public_ecdsa)) ||
+        !EC_KEY_set_public_key(ec.get(), EC_KEY_get0_public_key(public_ecdsa))) {
+        return nullptr;
+    }
+
+    auto key_backend_copy = new decltype(key_backend)(key_backend);
+
+    if (!EC_KEY_set_ex_data(ec.get(), Keystore2Engine::get().ec_key_ex_index(), key_backend_copy)) {
+        delete key_backend_copy;
+        return nullptr;
+    }
+
+    bssl::UniquePtr<EVP_PKEY> result(EVP_PKEY_new());
+    if (result.get() == nullptr || !EVP_PKEY_assign_EC_KEY(result.get(), ec.get())) {
+        return nullptr;
+    }
+    OWNERSHIP_TRANSFERRED(ec);
+
+    return result;
+}
+
+std::optional<std::vector<uint8_t>> keystore2_sign(const Keystore2KeyBackend& key_backend,
+                                                   std::vector<uint8_t> input,
+                                                   KMV1::Algorithm algorithm) {
+    auto sec_level = key_backend.i_keystore_security_level_;
+    ks2::CreateOperationResponse response;
+
+    std::vector<KMV1::KeyParameter> op_params(4);
+    op_params[0] = KMV1::KeyParameter{
+        .tag = KMV1::Tag::PURPOSE,
+        .value = KMV1::KeyParameterValue::make<KMV1::KeyParameterValue::keyPurpose>(
+            KMV1::KeyPurpose::SIGN)};
+    op_params[1] = KMV1::KeyParameter{
+        .tag = KMV1::Tag::ALGORITHM,
+        .value = KMV1::KeyParameterValue::make<KMV1::KeyParameterValue::algorithm>(algorithm)};
+    op_params[2] = KMV1::KeyParameter{
+        .tag = KMV1::Tag::PADDING,
+        .value = KMV1::KeyParameterValue::make<KMV1::KeyParameterValue::paddingMode>(
+            KMV1::PaddingMode::NONE)};
+    op_params[3] =
+        KMV1::KeyParameter{.tag = KMV1::Tag::DIGEST,
+                           .value = KMV1::KeyParameterValue::make<KMV1::KeyParameterValue::digest>(
+                               KMV1::Digest::NONE)};
+
+    auto rc = sec_level->createOperation(key_backend.descriptor_, op_params, false /* forced */,
+                                         &response);
+    if (!rc.isOk()) {
+        auto exception_code = rc.getExceptionCode();
+        if (exception_code == EX_SERVICE_SPECIFIC) {
+            LOG(ERROR) << AT << "Keystore createOperation returned service specific error: "
+                       << rc.getServiceSpecificError();
+        } else {
+            LOG(ERROR) << AT << "Communication with Keystore createOperation failed error: "
+                       << exception_code;
+        }
+        return std::nullopt;
+    }
+
+    auto op = response.iOperation;
+
+    std::optional<std::vector<uint8_t>> output = std::nullopt;
+    rc = op->finish(std::move(input), {}, &output);
+    if (!rc.isOk()) {
+        auto exception_code = rc.getExceptionCode();
+        if (exception_code == EX_SERVICE_SPECIFIC) {
+            LOG(ERROR) << AT << "Keystore finish returned service specific error: "
+                       << rc.getServiceSpecificError();
+        } else {
+            LOG(ERROR) << AT
+                       << "Communication with Keystore finish failed error: " << exception_code;
+        }
+        return std::nullopt;
+    }
+
+    if (!output) {
+        LOG(ERROR) << AT << "We did not get a signature from Keystore.";
+    }
+
+    return output;
+}
+
+/* rsa_private_transform takes a big-endian integer from |in|, calculates the
+ * d'th power of it, modulo the RSA modulus, and writes the result as a
+ * big-endian integer to |out|. Both |in| and |out| are |len| bytes long. It
+ * returns one on success and zero otherwise. */
+extern "C" int rsa_private_transform(RSA* rsa, uint8_t* out, const uint8_t* in, size_t len) {
+    auto key_backend = reinterpret_cast<std::shared_ptr<Keystore2KeyBackend>*>(
+        RSA_get_ex_data(rsa, Keystore2Engine::get().rsa_ex_index()));
+
+    if (key_backend == nullptr) {
+        LOG(ERROR) << AT << "Invalid key.";
+        return 0;
+    }
+
+    auto output =
+        keystore2_sign(**key_backend, std::vector<uint8_t>(in, in + len), KMV1::Algorithm::RSA);
+    if (!output) {
+        return 0;
+    }
+
+    if (output->size() > len) {
+        /* The result of the RSA operation can never be larger than the size of
+         * the modulus so we assume that the result has extra zeros on the
+         * left. This provides attackers with an oracle, but there's nothing
+         * that we can do about it here. */
+        LOG(WARNING) << "Reply len " << output->size() << " greater than expected " << len;
+        memcpy(out, &output->data()[output->size() - len], len);
+    } else if (output->size() < len) {
+        /* If the Keystore implementation returns a short value we assume that
+         * it's because it removed leading zeros from the left side. This is
+         * bad because it provides attackers with an oracle but we cannot do
+         * anything about a broken Keystore implementation here. */
+        LOG(WARNING) << "Reply len " << output->size() << " less than expected " << len;
+        memset(out, 0, len);
+        memcpy(out + len - output->size(), output->data(), output->size());
+    } else {
+        memcpy(out, output->data(), len);
+    }
+
+    return 1;
+}
+
+/* ecdsa_sign signs |digest_len| bytes from |digest| with |ec_key| and writes
+ * the resulting signature (an ASN.1 encoded blob) to |sig|. It returns one on
+ * success and zero otherwise. */
+extern "C" int ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                          unsigned int* sig_len, EC_KEY* ec_key) {
+    auto key_backend = reinterpret_cast<std::shared_ptr<Keystore2KeyBackend>*>(
+        EC_KEY_get_ex_data(ec_key, Keystore2Engine::get().ec_key_ex_index()));
+
+    if (key_backend == nullptr) {
+        LOG(ERROR) << AT << "Invalid key.";
+        return 0;
+    }
+
+    size_t ecdsa_size = ECDSA_size(ec_key);
+
+    auto output = keystore2_sign(**key_backend, std::vector<uint8_t>(digest, digest + digest_len),
+                                 KMV1::Algorithm::EC);
+    if (!output) {
+        LOG(ERROR) << "There was an error during ecdsa_sign.";
+        return 0;
+    }
+
+    if (output->size() == 0) {
+        LOG(ERROR) << "No valid signature returned";
+        return 0;
+    } else if (output->size() > ecdsa_size) {
+        LOG(ERROR) << "Signature is too large";
+        return 0;
+    }
+
+    memcpy(sig, output->data(), output->size());
+    *sig_len = output->size();
+
+    return 1;
+}
+
+}  // namespace
+
+/* EVP_PKEY_from_keystore returns an |EVP_PKEY| that contains either an RSA or
+ * ECDSA key where the public part of the key reflects the value of the key
+ * named |key_id| in Keystore and the private operations are forwarded onto
+ * KeyStore. */
+extern "C" EVP_PKEY* EVP_PKEY_from_keystore2(const char* key_id) {
+    ::ndk::SpAIBinder keystoreBinder(AServiceManager_checkService(keystore2_service_name));
+    auto keystore2 = ks2::IKeystoreService::fromBinder(keystoreBinder);
+
+    if (!keystore2) {
+        LOG(ERROR) << AT << "Unable to connect to Keystore 2.0.";
+        return nullptr;
+    }
+
+    std::string alias = key_id;
+    if (android::base::StartsWith(alias, "USRPKEY_")) {
+        LOG(WARNING) << AT << "Keystore backend used with legacy alias prefix - ignoring.";
+        alias = alias.substr(8);
+    }
+
+    ks2::KeyDescriptor descriptor = {
+        .domain = ks2::Domain::SELINUX,
+        .nspace = getNamespaceforCurrentUid(),
+        .alias = alias,
+        .blob = std::nullopt,
+    };
+
+    // If the key_id starts with the grant id prefix, we parse the following string as numeric
+    // grant id. We can then use the grant domain without alias to load the designated key.
+    if (alias.find(keystore2_grant_id_prefix) == 0) {
+        std::stringstream s(alias.substr(keystore2_grant_id_prefix.size()));
+        s >> std::hex >> reinterpret_cast<uint64_t&>(descriptor.nspace);
+        descriptor.domain = ks2::Domain::GRANT;
+        descriptor.alias = std::nullopt;
+    }
+
+    ks2::KeyEntryResponse response;
+    auto rc = keystore2->getKeyEntry(descriptor, &response);
+    if (!rc.isOk()) {
+        auto exception_code = rc.getExceptionCode();
+        if (exception_code == EX_SERVICE_SPECIFIC) {
+            LOG(ERROR) << AT << "Keystore getKeyEntry returned service specific error: "
+                       << rc.getServiceSpecificError();
+        } else {
+            LOG(ERROR) << AT << "Communication with Keystore getKeyEntry failed error: "
+                       << exception_code;
+        }
+        return nullptr;
+    }
+
+    if (!response.metadata.certificate) {
+        LOG(ERROR) << AT << "No public key found.";
+        return nullptr;
+    }
+
+    const uint8_t* p = response.metadata.certificate->data();
+    bssl::UniquePtr<X509> x509(d2i_X509(nullptr, &p, response.metadata.certificate->size()));
+    if (!x509) {
+        LOG(ERROR) << AT << "Failed to parse x509 certificate.";
+        return nullptr;
+    }
+    bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(x509.get()));
+    if (!pkey) {
+        LOG(ERROR) << AT << "Failed to extract public key.";
+        return nullptr;
+    }
+
+    auto key_backend = std::make_shared<Keystore2KeyBackend>(
+        Keystore2KeyBackend{response.metadata.key, response.iSecurityLevel});
+
+    bssl::UniquePtr<EVP_PKEY> result;
+    switch (EVP_PKEY_type(pkey->type)) {
+    case EVP_PKEY_RSA: {
+        bssl::UniquePtr<RSA> public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
+        result = wrap_rsa(key_backend, public_rsa.get());
+        break;
+    }
+    case EVP_PKEY_EC: {
+        bssl::UniquePtr<EC_KEY> public_ecdsa(EVP_PKEY_get1_EC_KEY(pkey.get()));
+        result = wrap_ecdsa(key_backend, public_ecdsa.get());
+        break;
+    }
+    default:
+        LOG(ERROR) << AT << "Unsupported key type " << EVP_PKEY_type(pkey->type);
+        return nullptr;
+    }
+
+    return result.release();
+}
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/keystore-engine/keystore2_engine.h
similarity index 76%
copy from keystore/binder/android/security/keymaster/OperationResult.aidl
copy to keystore-engine/keystore2_engine.h
index db689d4..a8381d9 100644
--- a/keystore/binder/android/security/keymaster/OperationResult.aidl
+++ b/keystore-engine/keystore2_engine.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-package android.security.keymaster;
+#pragma once
 
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
+#include <openssl/evp.h>
+
+extern "C" EVP_PKEY* EVP_PKEY_from_keystore2(const char* key_id);
diff --git a/keystore-engine/keystore_backend.h b/keystore-engine/keystore_backend.h
deleted file mode 100644
index 88c94b3..0000000
--- a/keystore-engine/keystore_backend.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#ifndef ANDROID_KEYSTORE_BACKEND_H
-#define ANDROID_KEYSTORE_BACKEND_H
-
-#include <stdint.h>
-
-class KeystoreBackend {
-  public:
-    virtual ~KeystoreBackend() {}
-    virtual int32_t sign(const char *key_id, const uint8_t* in, size_t len,
-                         uint8_t** reply, size_t* reply_len) = 0;
-    virtual int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
-                               size_t* reply_len) = 0;
-};
-
-#endif  // ANDROID_KEYSTORE_BACKEND_H
diff --git a/keystore-engine/keystore_backend_binder.cpp b/keystore-engine/keystore_backend_binder.cpp
deleted file mode 100644
index 8b5a584..0000000
--- a/keystore-engine/keystore_backend_binder.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#include "keystore_backend_binder.h"
-
-#include <android-base/logging.h>
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <keystore/KeyCharacteristics.h>
-#include <keystore/KeymasterArguments.h>
-#include <keystore/KeymasterBlob.h>
-#include <keystore/KeystoreResponse.h>
-#include <keystore/OperationResult.h>
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore.h>
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_promises.h>
-#include <keystore/keystore_return_types.h>
-
-#include <future>
-#include <thread>
-
-using android::security::keystore::IKeystoreService;
-using namespace android;
-using keystore::hidl_vec;
-
-using android::hardware::keymaster::V4_0::Algorithm;
-using android::hardware::keymaster::V4_0::authorizationValue;
-using android::hardware::keymaster::V4_0::Digest;
-using android::hardware::keymaster::V4_0::KeyFormat;
-using android::hardware::keymaster::V4_0::KeyParameter;
-using android::hardware::keymaster::V4_0::KeyPurpose;
-using android::hardware::keymaster::V4_0::NullOr;
-using android::hardware::keymaster::V4_0::PaddingMode;
-using android::hardware::keymaster::V4_0::TAG_ALGORITHM;
-using android::hardware::keymaster::V4_0::TAG_DIGEST;
-using android::hardware::keymaster::V4_0::TAG_PADDING;
-using android::security::keymaster::ExportResult;
-using android::security::keymaster::KeyCharacteristics;
-using android::security::keymaster::KeymasterArguments;
-using android::security::keymaster::KeymasterBlob;
-using android::security::keymaster::OperationResult;
-
-using KSReturn = keystore::KeyStoreNativeReturnCode;
-
-namespace {
-const char keystore_service_name[] = "android.security.keystore";
-constexpr int32_t UID_SELF = -1;
-
-using keystore::KeyCharacteristicsPromise;
-using keystore::KeystoreExportPromise;
-using keystore::KeystoreResponsePromise;
-using keystore::OperationResultPromise;
-
-}  // namespace
-
-#define AT __func__ << ":" << __LINE__ << " "
-
-static NullOr<const Algorithm&> getKeyAlgoritmFromKeyCharacteristics(
-    const ::android::security::keymaster::KeyCharacteristics& characteristics) {
-    for (const auto& param : characteristics.hardwareEnforced.getParameters()) {
-        auto algo = authorizationValue(TAG_ALGORITHM, param);
-        if (algo.isOk()) return algo;
-    }
-    for (const auto& param : characteristics.softwareEnforced.getParameters()) {
-        auto algo = authorizationValue(TAG_ALGORITHM, param);
-        if (algo.isOk()) return algo;
-    }
-    return {};
-}
-
-KeystoreBackendBinder::KeystoreBackendBinder() {
-    android::ProcessState::self()->startThreadPool();
-}
-
-int32_t KeystoreBackendBinder::sign(const char* key_id, const uint8_t* in, size_t len,
-                                    uint8_t** reply, size_t* reply_len) {
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16(keystore_service_name));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == nullptr) {
-        LOG(ERROR) << AT << "could not contact keystore";
-        return -1;
-    }
-
-    String16 key_name16(key_id);
-    int32_t error_code;
-    android::sp<KeyCharacteristicsPromise> kc_promise(new KeyCharacteristicsPromise);
-    auto kc_future = kc_promise->get_future();
-    auto binder_result = service->getKeyCharacteristics(kc_promise, key_name16, KeymasterBlob(),
-                                                        KeymasterBlob(), UID_SELF, &error_code);
-    if (!binder_result.isOk()) {
-        LOG(ERROR) << AT << "communication error while calling keystore";
-        return -1;
-    }
-    if (!KSReturn(error_code).isOk()) {
-        LOG(ERROR) << AT << "getKeyCharacteristics failed: " << error_code;
-        return -1;
-    }
-
-    auto [km_response, characteristics] = kc_future.get();
-
-    if (!KSReturn(km_response.response_code()).isOk()) {
-        LOG(ERROR) << AT << "getKeyCharacteristics failed: " << km_response.response_code();
-        return -1;
-    }
-
-    auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
-    if (!algorithm.isOk()) {
-        LOG(ERROR) << AT << "could not get algorithm from key characteristics";
-        return -1;
-    }
-
-    hidl_vec<KeyParameter> params(3);
-    params[0] = Authorization(TAG_DIGEST, Digest::NONE);
-    params[1] = Authorization(TAG_PADDING, PaddingMode::NONE);
-    params[2] = Authorization(TAG_ALGORITHM, algorithm.value());
-
-    android::sp<android::IBinder> token(new android::BBinder);
-    sp<OperationResultPromise> promise(new OperationResultPromise());
-    auto future = promise->get_future();
-    binder_result = service->begin(promise, token, key_name16, (int)KeyPurpose::SIGN,
-                                   true /*pruneable*/, KeymasterArguments(params),
-                                   std::vector<uint8_t>() /* entropy */, UID_SELF, &error_code);
-    if (!binder_result.isOk()) {
-        LOG(ERROR) << AT << "communication error while calling keystore";
-        return -1;
-    }
-
-    keystore::KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) {
-        LOG(ERROR) << AT << "Keystore begin returned: " << error_code;
-        return -1;
-    }
-    OperationResult result = future.get();
-
-    if (!result.resultCode.isOk()) {
-        LOG(ERROR) << AT << "begin failed: " << result.resultCode;
-        return -1;
-    }
-    auto handle = std::move(result.token);
-
-    do {
-        future = {};
-        promise = new OperationResultPromise();
-        future = promise->get_future();
-        binder_result = service->update(promise, handle, KeymasterArguments(params),
-                                        std::vector<uint8_t>(in, in + len), &error_code);
-        if (!binder_result.isOk()) {
-            LOG(ERROR) << AT << "communication error while calling keystore";
-            return -1;
-        }
-
-        rc = keystore::KeyStoreNativeReturnCode(error_code);
-        if (!rc.isOk()) {
-            LOG(ERROR) << AT << "Keystore update returned: " << error_code;
-            return -1;
-        }
-        result = future.get();
-
-        if (!result.resultCode.isOk()) {
-            LOG(ERROR) << AT << "update failed: " << result.resultCode;
-            return -1;
-        }
-
-        if (result.inputConsumed > len) {
-            LOG(ERROR) << AT << "update consumed more data than provided";
-            sp<KeystoreResponsePromise> abortPromise(new KeystoreResponsePromise);
-            auto abortFuture = abortPromise->get_future();
-            binder_result = service->abort(abortPromise, handle, &error_code);
-            if (!binder_result.isOk()) {
-                LOG(ERROR) << AT << "communication error while calling keystore";
-                return -1;
-            }
-            // This is mainly for logging since we already failed.
-            // But if abort returned OK we have to wait untill abort calls the callback
-            // hence the call to abortFuture.get().
-            if (!KSReturn(error_code).isOk()) {
-                LOG(ERROR) << AT << "abort failed: " << error_code;
-            } else if (!(rc = KSReturn(abortFuture.get().response_code())).isOk()) {
-                LOG(ERROR) << AT << "abort failed: " << rc;
-            }
-            return -1;
-        }
-        len -= result.inputConsumed;
-        in += result.inputConsumed;
-    } while (len > 0);
-
-    future = {};
-    promise = new OperationResultPromise();
-    future = promise->get_future();
-
-    binder_result = service->finish(
-        promise, handle, KeymasterArguments(params), std::vector<uint8_t>() /* input */,
-        std::vector<uint8_t>() /* signature */, std::vector<uint8_t>() /* entropy */, &error_code);
-
-    if (!binder_result.isOk()) {
-        LOG(ERROR) << AT << "communication error while calling keystore";
-        return -1;
-    }
-
-    rc = keystore::KeyStoreNativeReturnCode(error_code);
-    if (!rc.isOk()) {
-        LOG(ERROR) << AT << "Keystore finish returned: " << error_code;
-        return -1;
-    }
-    result = future.get();
-
-    if (!result.resultCode.isOk()) {
-        LOG(ERROR) << AT << "finish failed: " << result.resultCode;
-        return -1;
-    }
-
-    hidl_vec<uint8_t> reply_hidl(result.data);
-    if (reply_len) {
-        *reply_len = reply_hidl.size();
-    }
-    if (reply) {
-        *reply = reply_hidl.releaseData();
-    }
-    return 0;
-}
-
-int32_t KeystoreBackendBinder::get_pubkey(const char* key_id, uint8_t** pubkey,
-                                          size_t* pubkey_len) {
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16(keystore_service_name));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == nullptr) {
-        LOG(ERROR) << AT << "could not contact keystore";
-        return -1;
-    }
-
-    int32_t error_code;
-    android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
-    auto future = promise->get_future();
-    auto binder_result = service->exportKey(
-        promise, String16(key_id), static_cast<int32_t>(KeyFormat::X509),
-        KeymasterBlob() /* clientId */, KeymasterBlob() /* appData */, UID_SELF, &error_code);
-    if (!binder_result.isOk()) {
-        LOG(ERROR) << AT << "communication error while calling keystore";
-        return -1;
-    }
-
-    KSReturn rc(error_code);
-    if (!rc.isOk()) {
-        LOG(ERROR) << AT << "exportKey failed: " << error_code;
-        return -1;
-    }
-
-    auto export_result = future.get();
-    if (!export_result.resultCode.isOk()) {
-        LOG(ERROR) << AT << "exportKey failed: " << export_result.resultCode;
-        return -1;
-    }
-
-    if (pubkey_len) {
-        *pubkey_len = export_result.exportData.size();
-    }
-    if (pubkey) {
-        *pubkey = export_result.exportData.releaseData();
-    }
-    return 0;
-}
diff --git a/keystore-engine/keystore_backend_binder.h b/keystore-engine/keystore_backend_binder.h
deleted file mode 100644
index 4c828c5..0000000
--- a/keystore-engine/keystore_backend_binder.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#ifndef ANDROID_KEYSTORE_BACKEND_BINDER_H
-#define ANDROID_KEYSTORE_BACKEND_BINDER_H
-
-#include "keystore_backend.h"
-
-class KeystoreBackendBinder : public KeystoreBackend {
-  public:
-    KeystoreBackendBinder();
-    virtual ~KeystoreBackendBinder() {}
-    int32_t sign(const char *key_id, const uint8_t* in, size_t len,
-                 uint8_t** reply, size_t* reply_len) override;
-    int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
-                     size_t* reply_len) override;
-};
-
-#endif  // ANDROID_KEYSTORE_BACKEND_BINDER_H
diff --git a/keystore-engine/keystore_backend_hidl.cpp b/keystore-engine/keystore_backend_hidl.cpp
deleted file mode 100644
index 30cf890..0000000
--- a/keystore-engine/keystore_backend_hidl.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#include "keystore_backend_hidl.h"
-
-#include <android/system/wifi/keystore/1.0/IKeystore.h>
-#include <log/log.h>
-
-using android::hardware::hidl_vec;
-using android::hardware::Return;
-using android::sp;
-using android::system::wifi::keystore::V1_0::IKeystore;
-
-int32_t KeystoreBackendHidl::sign(
-        const char *key_id, const uint8_t* in, size_t len, uint8_t** reply,
-        size_t* reply_len) {
-    if (key_id == nullptr || in == nullptr || reply == nullptr || reply_len == nullptr) {
-        ALOGE("Null pointer argument passed");
-        return -1;
-    }
-
-    sp<IKeystore> service = IKeystore::tryGetService();
-    if (service == nullptr) {
-        ALOGE("could not contact keystore HAL");
-        return -1;
-    }
-
-    bool success = false;
-    auto cb = [&](IKeystore::KeystoreStatusCode status,
-                  hidl_vec<uint8_t> signedData) {
-      if (status == IKeystore::KeystoreStatusCode::SUCCESS) {
-          *reply_len = signedData.size();
-          *reply = signedData.releaseData();
-          success = true;
-      }
-    };
-    Return<void> ret = service->sign(
-        key_id, std::vector<uint8_t>(in, in + len), cb);
-    if (!ret.isOk() || !success) {
-        return 1;
-    }
-    return 0;
-}
-
-int32_t KeystoreBackendHidl::get_pubkey(
-        const char *key_id, uint8_t** pubkey, size_t* pubkey_len) {
-    if (key_id == nullptr || pubkey == nullptr || pubkey_len == nullptr) {
-        ALOGE("Null pointer argument passed");
-        return -1;
-    }
-
-    sp<IKeystore> service = IKeystore::tryGetService();
-    if (service == nullptr) {
-        ALOGE("could not contact keystore HAL");
-        return -1;
-    }
-
-    bool success = false;
-    auto cb = [&](IKeystore::KeystoreStatusCode status,
-                  hidl_vec<uint8_t> publicKey) {
-      if (status == IKeystore::KeystoreStatusCode::SUCCESS) {
-          *pubkey_len = publicKey.size();
-          *pubkey = publicKey.releaseData();
-          success = true;
-      }
-    };
-    Return<void> ret = service->getPublicKey(key_id, cb);
-    if (!ret.isOk() || !success) {
-        return 1;
-    }
-    return 0;
-}
diff --git a/keystore-engine/keystore_backend_hidl.h b/keystore-engine/keystore_backend_hidl.h
deleted file mode 100644
index fd38f69..0000000
--- a/keystore-engine/keystore_backend_hidl.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2017 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#ifndef ANDROID_KEYSTORE_BACKEND_HIDL_H
-#define ANDROID_KEYSTORE_BACKEND_HIDL_H
-
-#include "keystore_backend.h"
-
-class KeystoreBackendHidl : public KeystoreBackend {
-  public:
-    KeystoreBackendHidl() {}
-    virtual ~KeystoreBackendHidl() {}
-    int32_t sign(const char *key_id, const uint8_t* in, size_t len,
-                 uint8_t** reply, size_t* reply_len) override;
-    int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
-                     size_t* reply_len) override;
-};
-
-#endif  // ANDROID_KEYSTORE_BACKEND_HIDL_H
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 45b721b..0f2000c 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",
 
@@ -25,97 +35,6 @@
 }
 
 cc_binary {
-    name: "keystore",
-    defaults: ["keystore_defaults"],
-
-    srcs: [
-        "KeyStore.cpp",
-        "auth_token_table.cpp",
-        "blob.cpp",
-        "confirmation_manager.cpp",
-        "grant_store.cpp",
-        "key_creation_log_handler.cpp",
-        "key_operation_log_handler.cpp",
-        "key_attestation_log_handler.cpp",
-        "key_store_service.cpp",
-        "keyblob_utils.cpp",
-        "keymaster_enforcement.cpp",
-        "keymaster_worker.cpp",
-        "keystore_main.cpp",
-        "keystore_utils.cpp",
-        "legacy_keymaster_device_wrapper.cpp",
-        "operation.cpp",
-        "permissions.cpp",
-        "user_state.cpp",
-    ],
-    shared_libs: [
-        "android.hardware.confirmationui@1.0",
-        "android.hardware.keymaster@3.0",
-        "android.hardware.keymaster@4.0",
-        "android.hardware.keymaster@4.1",
-        "libbase",
-        "libbinder",
-        "libcrypto",
-        "libcutils",
-        "libhardware",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeymaster4_1support",
-        "libkeymaster_messages",
-        "libkeymaster_portable",
-        "libkeystore-attestation-application-id",
-        "libkeystore_aidl",
-        "libkeystore_binder",
-        "libkeystore_parcelables",
-        "liblog",
-        "libprotobuf-cpp-lite",
-        "libselinux",
-        "libservices",
-        "libsoftkeymasterdevice",
-        "libutils",
-        "libstatslog",
-    ],
-    init_rc: ["keystore.rc"],
-    aidl: {
-        include_dirs: ["frameworks/base/core/java/"],
-    },
-
-    product_variables: {
-        pdk: {
-            enabled: false,
-        },
-	debuggable: {
-            cflags: [
-                // Allow VTS tests running as root to have
-                // additional permissions.
-                "-DGRANT_ROOT_ALL_PERMISSIONS",
-            ],
-        },
-    },
-
-    required: ["keystore_cli_v2"],
-}
-
-cc_binary {
-    name: "keystore_cli",
-    defaults: ["keystore_defaults"],
-
-    srcs: ["keystore_cli.cpp"],
-    shared_libs: [
-        "android.hardware.keymaster@4.0",
-        "libbinder",
-        "libcrypto",
-        "libcutils",
-        "libhidlbase",
-        "libkeystore_aidl", // for IKeyStoreService.asInterface()
-        "libkeystore_binder",
-        "libkeystore_parcelables",
-        "liblog",
-        "libutils",
-    ],
-}
-
-cc_binary {
     name: "keystore_cli_v2",
     defaults: ["keystore_defaults"],
 
@@ -123,95 +42,25 @@
         "-DKEYMASTER_NAME_TAGS",
         "-Wno-unused-parameter",
     ],
-    srcs: ["keystore_cli_v2.cpp"],
+    srcs: [
+        "keystore_cli_v2.cpp",
+        "keystore_client.proto",
+    ],
     shared_libs: [
-        "android.hardware.confirmationui@1.0",
+        "android.security.apc-ndk_platform",
+        "android.system.keystore2-V1-ndk_platform",
         "libbinder",
-        "android.hardware.keymaster@4.0",
+        "libbinder_ndk",
         "libchrome",
+        "libcrypto",
+        "libkeymint_support",
+        "libprotobuf-cpp-lite",
         "libutils",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeystore_aidl",
-        "libkeystore_binder",
-        "libkeystore_parcelables",
     ],
 
     local_include_dirs: ["include"],
 }
 
-cc_library_shared {
-    name: "libkeystore_parcelables",
-    defaults: ["keystore_defaults"],
-    export_include_dirs: ["include"],
-    srcs: [
-        "KeymasterArguments.cpp",
-        "keystore_aidl_hidl_marshalling_utils.cpp",
-        "KeystoreResponse.cpp",
-        "OperationResult.cpp",
-    ],
-    shared_libs: [
-        "android.hardware.keymaster@4.0",
-        "android.hardware.keymaster@4.1",
-        "libbinder",
-        "libhardware",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeymaster4_1support",
-        "liblog",
-        "libprotobuf-cpp-lite",
-        "libutils",
-        "libkeystore-attestation-application-id",
-    ],
-    export_shared_lib_headers: [
-        "android.hardware.keymaster@4.0",
-        "android.hardware.keymaster@4.1",
-        "libbinder",
-        "libhidlbase",
-        "libkeymaster4_1support",
-    ],
-}
-// Library for keystore clients
-cc_library_shared {
-    name: "libkeystore_binder",
-    defaults: ["keystore_defaults"],
-
-    srcs: [
-        "keyblob_utils.cpp",
-        "keystore_client.proto",
-        "keystore_client_impl.cpp",
-        "keystore_get.cpp",
-    ],
-    shared_libs: [
-        "android.hardware.keymaster@4.0",
-        "libbinder",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeystore_aidl",
-        "libkeystore_parcelables",
-        "liblog",
-        "libprotobuf-cpp-lite",
-        "libutils",
-    ],
-
-    proto: {
-        type: "lite",
-        export_proto_headers: true,
-    },
-    aidl: {
-        export_aidl_headers: true,
-        include_dirs: ["frameworks/base/core/java/"],
-    },
-    export_include_dirs: ["include"],
-    export_shared_lib_headers: [
-        "android.hardware.keymaster@4.0",
-        "libbinder",
-        "libhidlbase",
-        "libkeystore_aidl",
-        "libkeystore_parcelables",
-    ],
-}
-
 // Library used by both keystore and credstore for generating the ASN.1 stored
 // in Tag::ATTESTATION_APPLICATION_ID
 cc_library_shared {
@@ -255,77 +104,3 @@
 
     vendor: true,
 }
-
-// Library for unit tests
-cc_library_static {
-    name: "libkeystore_test",
-    defaults: ["keystore_defaults"],
-
-    srcs: [
-        "auth_token_table.cpp",
-        "blob.cpp",
-    ],
-    cflags: [ "-O0", ],
-    static_libs: ["libgtest_main"],
-    shared_libs: [
-        "android.hardware.keymaster@4.0",
-        "libbinder",
-        "libcrypto",
-        "libhidlbase",
-        "libkeymaster4support",
-        "libkeystore-attestation-application-id",
-        "libutils",
-        "libkeystore_aidl",
-        "libkeystore_parcelables",
-    ],
-    export_shared_lib_headers: [
-        "android.hardware.keymaster@4.0",
-        "libhidlbase",
-        "libkeymaster4support",
-    ],
-
-    aidl: {
-        include_dirs: ["frameworks/base/core/java/"],
-    },
-    export_include_dirs: ["include"],
-}
-
-filegroup {
-    name: "keystore_aidl",
-    srcs: [
-        "binder/android/security/IConfirmationPromptCallback.aidl",
-        "binder/android/security/keystore/ICredstoreTokenCallback.aidl",
-        "binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl",
-        "binder/android/security/keystore/IKeystoreExportKeyCallback.aidl",
-        "binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl",
-        "binder/android/security/keystore/IKeystoreOperationResultCallback.aidl",
-        "binder/android/security/keystore/IKeystoreResponseCallback.aidl",
-        "binder/android/security/keystore/IKeystoreService.aidl",
-    ],
-    path: "binder",
-}
-
-cc_library_shared {
-    name: "libkeystore_aidl",
-    srcs: [":keystore_aidl"],
-    aidl: {
-        export_aidl_headers: true,
-        include_dirs: [
-            "system/security/keystore/binder",
-        ],
-    },
-    shared_libs: [
-        "libbinder",
-        "libcutils",
-        "libhardware",
-        "libhidlbase",
-        "libkeystore_parcelables",
-        "liblog",
-        "libselinux",
-        "libutils",
-    ],
-    export_shared_lib_headers: [
-        "libbinder",
-        "libkeystore_parcelables",
-    ],
-}
diff --git a/keystore/KeyAttestationApplicationId.cpp b/keystore/KeyAttestationApplicationId.cpp
index c62571f..1838b07 100644
--- a/keystore/KeyAttestationApplicationId.cpp
+++ b/keystore/KeyAttestationApplicationId.cpp
@@ -26,8 +26,8 @@
 KeyAttestationApplicationId::KeyAttestationApplicationId() = default;
 
 KeyAttestationApplicationId::KeyAttestationApplicationId(
-        std::unique_ptr<KeyAttestationPackageInfo> package) :
-    packageInfos_(new std::vector<std::unique_ptr<KeyAttestationPackageInfo>>()) {
+    std::optional<KeyAttestationPackageInfo> package)
+    : packageInfos_(new std::vector<std::optional<KeyAttestationPackageInfo>>()) {
     packageInfos_->push_back(std::move(package));
 }
 
@@ -39,10 +39,13 @@
 }
 
 status_t KeyAttestationApplicationId::readFromParcel(const Parcel* parcel) {
-    std::unique_ptr<std::vector<std::unique_ptr<KeyAttestationPackageInfo>>> temp_vector;
+    std::optional<std::vector<std::optional<KeyAttestationPackageInfo>>> temp_vector;
     auto rc = parcel->readParcelableVector(&temp_vector);
     if (rc != NO_ERROR) return rc;
-    packageInfos_.reset(temp_vector.release());
+    packageInfos_.reset();
+    if (temp_vector) {
+        packageInfos_ = std::make_shared<PackageInfoVector>(std::move(*temp_vector));
+    }
     return NO_ERROR;
 }
 
diff --git a/keystore/KeyAttestationPackageInfo.cpp b/keystore/KeyAttestationPackageInfo.cpp
index 75fbb7a..8e9a36a 100644
--- a/keystore/KeyAttestationPackageInfo.cpp
+++ b/keystore/KeyAttestationPackageInfo.cpp
@@ -28,7 +28,7 @@
 KeyAttestationPackageInfo::KeyAttestationPackageInfo(const String16& packageName,
                                                      int64_t versionCode,
                                                      SharedSignaturesVector signatures)
-    : packageName_(new String16(packageName)), versionCode_(versionCode), signatures_(signatures) {}
+    : packageName_(packageName), versionCode_(versionCode), signatures_(signatures) {}
 
 status_t KeyAttestationPackageInfo::writeToParcel(Parcel* parcel) const {
     auto rc = parcel->writeString16(packageName_);
@@ -44,10 +44,13 @@
     rc = parcel->readInt64(&versionCode_);
     if (rc != NO_ERROR) return rc;
 
-    std::unique_ptr<SignaturesVector> temp_vector;
+    std::optional<SignaturesVector> temp_vector;
     rc = parcel->readParcelableVector(&temp_vector);
     if (rc != NO_ERROR) return rc;
-    signatures_.reset(temp_vector.release());
+    signatures_.reset();
+    if (temp_vector) {
+        signatures_ = std::make_shared<SignaturesVector>(std::move(*temp_vector));
+    }
     return NO_ERROR;
 }
 
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
deleted file mode 100644
index 7545397..0000000
--- a/keystore/KeyStore.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define LOG_TAG "keystore"
-
-#include "KeyStore.h"
-
-#include <dirent.h>
-#include <fcntl.h>
-
-#include <openssl/bio.h>
-
-#include <utils/String16.h>
-#include <utils/String8.h>
-
-#include <android-base/scopeguard.h>
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <android/security/keystore/IKeystoreService.h>
-#include <log/log_event_list.h>
-
-#include <private/android_logger.h>
-
-#include "keystore_utils.h"
-#include "permissions.h"
-#include <keystore/keystore_hidl_support.h>
-
-#include "keymaster_worker.h"
-
-namespace keystore {
-
-const char* KeyStore::kOldMasterKey = ".masterkey";
-const char* KeyStore::kMetaDataFile = ".metadata";
-
-const android::String16 KeyStore::kRsaKeyType("RSA");
-const android::String16 KeyStore::kEcKeyType("EC");
-
-using android::String8;
-
-KeyStore::KeyStore(const KeymasterDevices& kmDevices,
-                   SecurityLevel minimalAllowedSecurityLevelForNewKeys)
-    : mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE),
-      mConfirmationManager(new ConfirmationManager(this)) {
-    memset(&mMetaData, '\0', sizeof(mMetaData));
-
-    static_assert(std::tuple_size<std::decay_t<decltype(kmDevices)>>::value ==
-                      std::tuple_size<decltype(mKmDevices)>::value,
-                  "KmasterDevices and KeymasterWorkers must have the same size");
-    for (size_t i = 0; i < kmDevices.size(); ++i) {
-        if (kmDevices[SecurityLevel(i)]) {
-            mKmDevices[SecurityLevel(i)] =
-                std::make_shared<KeymasterWorker>(kmDevices[SecurityLevel(i)], this);
-        }
-    }
-}
-
-KeyStore::~KeyStore() {
-}
-
-ResponseCode KeyStore::initialize() {
-    readMetaData();
-    if (upgradeKeystore()) {
-        writeMetaData();
-    }
-
-    return ResponseCode::NO_ERROR;
-}
-
-ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
-    auto userState = mUserStateDB.getUserState(userId);
-    return userState->initialize(pw);
-}
-
-ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
-    auto userState = mUserStateDB.getUserState(dstUser);
-    auto initState = mUserStateDB.getUserState(srcUser);
-    return userState->copyMasterKey(&initState);
-}
-
-ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
-    auto userState = mUserStateDB.getUserState(userId);
-    return userState->writeMasterKey(pw);
-}
-
-ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
-    auto userState = mUserStateDB.getUserState(userId);
-    return userState->readMasterKey(pw);
-}
-
-LockedKeyBlobEntry KeyStore::getLockedBlobEntryIfNotExists(const std::string& alias, uid_t uid) {
-    KeyBlobEntry kbe(alias, mUserStateDB.getUserStateByUid(uid)->getUserDirName(), uid);
-    auto result = LockedKeyBlobEntry::get(std::move(kbe));
-    if (result->hasKeyBlob()) return {};
-    return result;
-}
-
-std::optional<KeyBlobEntry> KeyStore::getBlobEntryIfExists(const std::string& alias, uid_t uid) {
-    KeyBlobEntry kbe(alias, mUserStateDB.getUserStateByUid(uid)->getUserDirName(), uid);
-    if (kbe.hasKeyBlob()) return kbe;
-
-    // If this is one of the legacy UID->UID mappings, use it.
-    uid_t euid = get_keystore_euid(uid);
-    if (euid != uid) {
-        kbe = KeyBlobEntry(alias, mUserStateDB.getUserStateByUid(euid)->getUserDirName(), euid);
-        if (kbe.hasKeyBlob()) return kbe;
-    }
-
-    // They might be using a granted key.
-    auto grant = mGrants.get(uid, alias);
-    if (grant) {
-        kbe = grant->entry_;
-        if (kbe.hasKeyBlob()) return kbe;
-    }
-    return {};
-}
-LockedKeyBlobEntry KeyStore::getLockedBlobEntryIfExists(const std::string& alias, uid_t uid) {
-    auto blobentry = getBlobEntryIfExists(alias, uid);
-    if (!blobentry) return {};
-    LockedKeyBlobEntry lockedentry = LockedKeyBlobEntry::get(std::move(*blobentry));
-    if (!lockedentry || !lockedentry->hasKeyBlob()) return {};
-    return lockedentry;
-}
-
-void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
-    android::String8 prefix("");
-    android::Vector<android::String16> aliases;
-
-    auto userState = mUserStateDB.getUserState(userId);
-    std::string userDirName = userState->getUserDirName();
-    auto encryptionKey = userState->getEncryptionKey();
-    auto state = userState->getState();
-    // userState is a proxy that holds a lock which may be required by a worker.
-    // LockedKeyBlobEntry::list has a fence that waits until all workers have finished which may
-    // not happen if a user state lock is held. The following line relinquishes the lock.
-    userState = {};
-
-    ResponseCode rc;
-    std::list<LockedKeyBlobEntry> matches;
-
-    // must not be called by a keymaster worker. List waits for workers to relinquish all access
-    // to blob entries
-    std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
-    if (rc != ResponseCode::NO_ERROR) {
-        return;
-    }
-
-    for (LockedKeyBlobEntry& lockedEntry : matches) {
-        bool shouldDelete = true;
-
-        if (keepUnenryptedEntries) {
-            Blob blob;
-            Blob charBlob;
-            ResponseCode rc;
-
-            std::tie(rc, blob, charBlob) = lockedEntry.readBlobs(encryptionKey, state);
-
-            switch (rc) {
-            case ResponseCode::SYSTEM_ERROR:
-            case ResponseCode::VALUE_CORRUPTED:
-                // If we can't read blobs, delete them.
-                shouldDelete = true;
-                break;
-
-            case ResponseCode::NO_ERROR:
-            case ResponseCode::LOCKED:
-                // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs.  We
-                // need to keep super-encrypted blobs so we can report that the user is
-                // unauthenticated if a caller tries to use them, rather than reporting that they
-                // don't exist.
-                shouldDelete = blob.isEncrypted();
-                break;
-
-            default:
-                ALOGE("Got unexpected return code %d from readBlobs", rc);
-                // This shouldn't happen.  To be on the safe side, delete it.
-                shouldDelete = true;
-                break;
-            }
-        }
-        if (shouldDelete) {
-            del(lockedEntry);
-        }
-    }
-
-    userState = mUserStateDB.getUserState(userId);
-    if (!userState->deleteMasterKey()) {
-        ALOGE("Failed to delete user %d's master key", userId);
-    }
-    if (!keepUnenryptedEntries) {
-        if (!userState->reset()) {
-            ALOGE("Failed to remove user %d's directory", userId);
-        }
-    }
-}
-
-bool KeyStore::isEmpty(uid_t userId) const {
-    std::string userDirName;
-    {
-        // userState holds a lock which must be relinquished before list is called. This scope
-        // prevents deadlocks.
-        auto userState = mUserStateDB.getUserState(userId);
-        if (!userState) {
-            return true;
-        }
-        userDirName = userState->getUserDirName();
-    }
-
-    ResponseCode rc;
-    std::list<LockedKeyBlobEntry> matches;
-
-    // must not be called by a keymaster worker. List waits for workers to relinquish all access
-    // to blob entries
-    std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
-
-    return rc == ResponseCode::SYSTEM_ERROR || matches.size() == 0;
-}
-
-void KeyStore::lock(uid_t userId) {
-    auto userState = mUserStateDB.getUserState(userId);
-    userState->zeroizeMasterKeysInMemory();
-    userState->setState(STATE_LOCKED);
-}
-
-static void maybeLogKeyIntegrityViolation(const LockedKeyBlobEntry& lockedEntry,
-                                          const BlobType type) {
-    if (!__android_log_security() || (type != TYPE_KEY_PAIR && type != TYPE_KEYMASTER_10)) return;
-    log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
-}
-
-std::tuple<ResponseCode, Blob, Blob> KeyStore::get(const LockedKeyBlobEntry& blobfile) {
-    std::tuple<ResponseCode, Blob, Blob> result;
-
-    uid_t userId = get_user_id(blobfile->uid());
-    Blob& keyBlob = std::get<1>(result);
-    ResponseCode& rc = std::get<0>(result);
-
-    auto userState = mUserStateDB.getUserState(userId);
-    BlobType type = BlobType::TYPE_ANY;
-    auto logOnScopeExit = android::base::make_scope_guard([&] {
-        if (rc == ResponseCode::VALUE_CORRUPTED) {
-            maybeLogKeyIntegrityViolation(blobfile, type);
-        }
-    });
-
-    result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState());
-    if (rc != ResponseCode::NO_ERROR) {
-        return result;
-    }
-
-    // update the type for logging (see scope_guard above)
-    type = keyBlob.getType();
-
-    const uint8_t version = keyBlob.getVersion();
-    if (version < CURRENT_BLOB_VERSION) {
-        /* If we upgrade the key, we need to write it to disk again. Then
-         * it must be read it again since the blob is encrypted each time
-         * it's written.
-         */
-        if (upgradeBlob(&keyBlob, version)) {
-            if ((rc = this->put(blobfile, keyBlob, {})) != ResponseCode::NO_ERROR ||
-                (result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState()),
-                 rc) != ResponseCode::NO_ERROR) {
-                return result;
-            }
-        }
-    }
-
-    return result;
-}
-
-ResponseCode KeyStore::put(const LockedKeyBlobEntry& blobfile, Blob keyBlob,
-                           Blob characteristicsBlob) {
-    auto userState = mUserStateDB.getUserStateByUid(blobfile->uid());
-    return blobfile.writeBlobs(std::move(keyBlob), std::move(characteristicsBlob),
-                               userState->getEncryptionKey(), userState->getState());
-}
-
-ResponseCode KeyStore::del(const LockedKeyBlobEntry& blobfile) {
-    Blob keyBlob;
-    Blob charactaristicsBlob;
-    ResponseCode rc;
-    uid_t uid = blobfile->uid();
-    std::string alias = blobfile->alias();
-
-    std::tie(rc, keyBlob, charactaristicsBlob) = get(blobfile);
-
-    // after getting the blob from the file system we scrub the filesystem.
-    mGrants.removeAllGrantsToKey(uid, alias);
-    auto result = blobfile.deleteBlobs();
-
-    if (rc != ResponseCode::NO_ERROR) {
-        LOG(ERROR) << "get keyblob failed " << int(rc);
-        return rc;
-    }
-
-    // if we got the blob successfully, we try and delete it from the keymaster device
-    auto dev = getDevice(keyBlob);
-
-    if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
-        dev->deleteKey(blob2hidlVec(keyBlob), [dev, alias, uid](Return<ErrorCode> rc) {
-            auto ret = KS_HANDLE_HIDL_ERROR(dev, rc);
-            // A device doesn't have to implement delete_key.
-            bool success = ret == ErrorCode::OK || ret == ErrorCode::UNIMPLEMENTED;
-            if (__android_log_security()) {
-                android_log_event_list(SEC_TAG_KEY_DESTROYED)
-                    << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
-            }
-            if (!success) {
-                LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid
-                           << " failed";
-            }
-        });
-    }
-
-    return result;
-}
-
-std::string KeyStore::addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid) {
-    return mGrants.put(granteeUid, blobfile);
-}
-
-bool KeyStore::removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid) {
-    return mGrants.removeByFileAlias(granteeUid, blobfile);
-}
-void KeyStore::removeAllGrantsToUid(const uid_t granteeUid) {
-    mGrants.removeAllGrantsToUid(granteeUid);
-}
-
-bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
-    // if strongbox device is present TEE must also be present and of sufficiently high version
-    // to support all keys in hardware
-    if (getDevice(SecurityLevel::STRONGBOX)) return true;
-    if (!getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)) {
-        ALOGW("can't get keymaster device");
-        return false;
-    }
-
-    auto version = getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)->halVersion();
-    if (keyType == kRsaKeyType) return true;  // All versions support RSA
-    return keyType == kEcKeyType && version.supportsEc;
-}
-
-std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
-KeyStore::getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type) {
-    std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry> result;
-    auto& [rc, keyBlob, charBlob, lockedEntry] = result;
-
-    lockedEntry = getLockedBlobEntryIfExists(keyName.string(), uid);
-
-    if (!lockedEntry) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
-
-    std::tie(rc, keyBlob, charBlob) = get(lockedEntry);
-
-    if (rc == ResponseCode::NO_ERROR) {
-        if (keyBlob.getType() != type) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
-    }
-    return result;
-}
-
-bool KeyStore::upgradeBlob(Blob* blob, const uint8_t oldVersion) {
-    bool updated = false;
-    uint8_t version = oldVersion;
-
-    if (!blob || !(*blob)) return false;
-
-    /* From V0 -> V1: All old types were unknown */
-    if (version == 0) {
-        ALOGE("Failed to upgrade key blob. Ancient blob version 0 is no longer supported");
-
-        return false;
-    }
-
-    /* From V1 -> V2: All old keys were encrypted */
-    if (version == 1) {
-        ALOGV("upgrading to version 2");
-
-        blob->setEncrypted(true);
-        version = 2;
-        updated = true;
-    }
-
-    /*
-     * If we've updated, set the key blob to the right version
-     * and write it.
-     */
-    if (updated) {
-        blob->setVersion(version);
-    }
-
-    return updated;
-}
-
-void KeyStore::readMetaData() {
-    int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
-    if (in < 0) {
-        return;
-    }
-    size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData));
-    if (fileLength != sizeof(mMetaData)) {
-        ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData));
-    }
-    close(in);
-}
-
-void KeyStore::writeMetaData() {
-    const char* tmpFileName = ".metadata.tmp";
-    int out =
-        TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
-    if (out < 0) {
-        ALOGE("couldn't write metadata file: %s", strerror(errno));
-        return;
-    }
-    size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData));
-    if (fileLength != sizeof(mMetaData)) {
-        ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
-              sizeof(mMetaData));
-    }
-    close(out);
-    rename(tmpFileName, kMetaDataFile);
-}
-
-bool KeyStore::upgradeKeystore() {
-    bool upgraded = false;
-
-    if (mMetaData.version == 0) {
-        auto userState = getUserStateDB().getUserStateByUid(0);
-
-        // Initialize first so the directory is made.
-        userState->initialize();
-
-        // Migrate the old .masterkey file to user 0.
-        if (access(kOldMasterKey, R_OK) == 0) {
-            if (rename(kOldMasterKey, userState->getMasterKeyFileName().c_str()) < 0) {
-                ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
-                return false;
-            }
-        }
-
-        // Initialize again in case we had a key.
-        userState->initialize();
-
-        // Try to migrate existing keys.
-        DIR* dir = opendir(".");
-        if (!dir) {
-            // Give up now; maybe we can upgrade later.
-            ALOGE("couldn't open keystore's directory; something is wrong");
-            return false;
-        }
-
-        struct dirent* file;
-        while ((file = readdir(dir)) != nullptr) {
-            // We only care about files.
-            if (file->d_type != DT_REG) {
-                continue;
-            }
-
-            // Skip anything that starts with a "."
-            if (file->d_name[0] == '.') {
-                continue;
-            }
-
-            // Find the current file's user.
-            char* end;
-            unsigned long thisUid = strtoul(file->d_name, &end, 10);
-            if (end[0] != '_' || end[1] == 0) {
-                continue;
-            }
-            auto otherUser = getUserStateDB().getUserStateByUid(thisUid);
-            if (otherUser->getUserId() != 0) {
-                unlinkat(dirfd(dir), file->d_name, 0);
-            }
-
-            // Rename the file into user directory.
-            DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
-            if (otherdir == nullptr) {
-                ALOGW("couldn't open user directory for rename");
-                continue;
-            }
-            if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
-                ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
-            }
-            closedir(otherdir);
-        }
-        closedir(dir);
-
-        mMetaData.version = 1;
-        upgraded = true;
-    }
-
-    return upgraded;
-}
-
-void KeyStore::binderDied(const ::android::wp<IBinder>& who) {
-    for (unsigned i = 0; i < mKmDevices.size(); ++i) {
-        if (mKmDevices[SecurityLevel(i)]) mKmDevices[SecurityLevel(i)]->binderDied(who);
-    }
-    getConfirmationManager().binderDied(who);
-}
-
-}  // namespace keystore
diff --git a/keystore/KeyStore.h b/keystore/KeyStore.h
deleted file mode 100644
index 0027ec8..0000000
--- a/keystore/KeyStore.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 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_KEYSTORE_H_
-#define KEYSTORE_KEYSTORE_H_
-
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <keymasterV4_1/Keymaster.h>
-#include <utils/Vector.h>
-
-#include <keystore/keymaster_types.h>
-
-#include "auth_token_table.h"
-#include "blob.h"
-#include "confirmation_manager.h"
-#include "grant_store.h"
-#include "keymaster_worker.h"
-#include "keystore_keymaster_enforcement.h"
-#include "operation.h"
-#include "user_state.h"
-
-#include <array>
-#include <optional>
-#include <tuple>
-
-namespace keystore {
-
-using ::android::sp;
-using keymaster::support::Keymaster;
-
-template <typename T, size_t count> class Devices : public std::array<T, count> {
-  public:
-    T& operator[](SecurityLevel secLevel) {
-        static_assert(uint32_t(SecurityLevel::SOFTWARE) == 0 &&
-                          uint32_t(SecurityLevel::TRUSTED_ENVIRONMENT) == 1 &&
-                          uint32_t(SecurityLevel::STRONGBOX) == 2,
-                      "Numeric values of security levels have changed");
-        return std::array<T, count>::at(static_cast<uint32_t>(secLevel));
-    }
-    T operator[](SecurityLevel secLevel) const {
-        if (static_cast<uint32_t>(secLevel) > static_cast<uint32_t>(SecurityLevel::STRONGBOX)) {
-            LOG(ERROR) << "Invalid security level requested";
-            return {};
-        }
-        return (*const_cast<Devices*>(this))[secLevel];
-    }
-};
-
-}  // namespace keystore
-
-namespace std {
-template <typename T, size_t count> struct tuple_size<keystore::Devices<T, count>> {
-  public:
-    static constexpr size_t value = std::tuple_size<std::array<T, count>>::value;
-};
-}  // namespace std
-
-namespace keystore {
-
-using KeymasterWorkers = Devices<std::shared_ptr<KeymasterWorker>, 3>;
-using KeymasterDevices = Devices<sp<Keymaster>, 3>;
-
-class KeyStore : public ::android::IBinder::DeathRecipient {
-  public:
-    KeyStore(const KeymasterDevices& kmDevices,
-             SecurityLevel minimalAllowedSecurityLevelForNewKeys);
-    ~KeyStore();
-
-    std::shared_ptr<KeymasterWorker> getDevice(SecurityLevel securityLevel) const {
-        return mKmDevices[securityLevel];
-    }
-
-    std::shared_ptr<KeymasterWorker> getFallbackDevice() const {
-        // we only return the fallback device if the creation of new fallback key blobs is
-        // allowed. (also see getDevice below)
-        if (mAllowNewFallback) {
-            return mKmDevices[SecurityLevel::SOFTWARE];
-        } else {
-            return nullptr;
-        }
-    }
-
-    std::shared_ptr<KeymasterWorker> getDevice(const Blob& blob) {
-        return mKmDevices[blob.getSecurityLevel()];
-    }
-
-    ResponseCode initialize();
-
-    State getState(uid_t userId) { return mUserStateDB.getUserState(userId)->getState(); }
-
-    ResponseCode initializeUser(const android::String8& pw, uid_t userId);
-
-    ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser);
-    ResponseCode writeMasterKey(const android::String8& pw, uid_t userId);
-    ResponseCode readMasterKey(const android::String8& pw, uid_t userId);
-
-    LockedKeyBlobEntry getLockedBlobEntryIfNotExists(const std::string& alias, uid_t uid);
-    std::optional<KeyBlobEntry> getBlobEntryIfExists(const std::string& alias, uid_t uid);
-    LockedKeyBlobEntry getLockedBlobEntryIfExists(const std::string& alias, uid_t uid);
-    /*
-     * Delete entries owned by userId. If keepUnencryptedEntries is true
-     * then only encrypted entries will be removed, otherwise all entries will
-     * be removed.
-     */
-    void resetUser(uid_t userId, bool keepUnenryptedEntries);
-    bool isEmpty(uid_t userId) const;
-
-    void lock(uid_t userId);
-
-    std::tuple<ResponseCode, Blob, Blob> get(const LockedKeyBlobEntry& blobfile);
-    ResponseCode put(const LockedKeyBlobEntry& blobfile, Blob keyBlob, Blob characteristicsBlob);
-    ResponseCode del(const LockedKeyBlobEntry& blobfile);
-
-    std::string addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid);
-    bool removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid);
-    void removeAllGrantsToUid(const uid_t granteeUid);
-
-    ResponseCode importKey(const uint8_t* key, size_t keyLen, const LockedKeyBlobEntry& blobfile,
-                           uid_t userId, int32_t flags);
-
-    bool isHardwareBacked(const android::String16& keyType) const;
-
-    std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
-    getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type);
-
-    void binderDied(const ::android::wp<IBinder>& who) override;
-
-    UserStateDB& getUserStateDB() { return mUserStateDB; }
-    AuthTokenTable& getAuthTokenTable() { return mAuthTokenTable; }
-    KeystoreKeymasterEnforcement& getEnforcementPolicy() { return mEnforcementPolicy; }
-    ConfirmationManager& getConfirmationManager() { return *mConfirmationManager; }
-
-    void addOperationDevice(sp<IBinder> token, std::shared_ptr<KeymasterWorker> dev) {
-        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
-        operationDeviceMap_.emplace(std::move(token), std::move(dev));
-    }
-    std::shared_ptr<KeymasterWorker> getOperationDevice(const sp<IBinder>& token) {
-        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
-        auto it = operationDeviceMap_.find(token);
-        if (it != operationDeviceMap_.end()) {
-            return it->second;
-        }
-        return {};
-    }
-    void removeOperationDevice(const sp<IBinder>& token) {
-        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
-        operationDeviceMap_.erase(token);
-    }
-
-  private:
-    static const char* kOldMasterKey;
-    static const char* kMetaDataFile;
-    static const android::String16 kRsaKeyType;
-    static const android::String16 kEcKeyType;
-
-    KeymasterWorkers mKmDevices;
-
-    bool mAllowNewFallback;
-
-    UserStateDB mUserStateDB;
-    AuthTokenTable mAuthTokenTable;
-    KeystoreKeymasterEnforcement mEnforcementPolicy;
-    sp<ConfirmationManager> mConfirmationManager;
-
-    ::keystore::GrantStore mGrants;
-
-    typedef struct { uint32_t version; } keystore_metadata_t;
-
-    keystore_metadata_t mMetaData;
-
-    /**
-     * Upgrade the key from the current version to whatever is newest.
-     */
-    bool upgradeBlob(Blob* blob, const uint8_t oldVersion);
-
-    void readMetaData();
-    void writeMetaData();
-
-    bool upgradeKeystore();
-
-    std::mutex operationDeviceMapMutex_;
-    std::map<sp<IBinder>, std::shared_ptr<KeymasterWorker>> operationDeviceMap_;
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_KEYSTORE_H_
diff --git a/keystore/KeymasterArguments.cpp b/keystore/KeymasterArguments.cpp
deleted file mode 100644
index 60b86cc..0000000
--- a/keystore/KeymasterArguments.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-**
-** Copyright 2017, 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/KeymasterArguments.h"
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-#include <binder/Parcel.h>
-
-namespace android {
-namespace security {
-namespace keymaster {
-
-using ::android::status_t;
-status_t KeymasterArguments::readFromParcel(const android::Parcel* in) {
-    data_ = keystore::readParamSetFromParcel(*in);
-    return OK;
-};
-
-status_t KeymasterArguments::writeToParcel(android::Parcel* out) const {
-    return keystore::writeParamSetToParcel(data_, out);
-};
-
-KeymasterArguments::KeymasterArguments(hardware::hidl_vec<keystore::KeyParameter>&& other)
-    : data_(std::move(other)) {}
-
-KeymasterArguments::KeymasterArguments(const hardware::hidl_vec<keystore::KeyParameter>& other)
-    : data_(other) {}
-
-}  // namespace keymaster
-}  // namespace security
-}  // namespace android
diff --git a/keystore/KeystoreResponse.cpp b/keystore/KeystoreResponse.cpp
deleted file mode 100644
index c46973a..0000000
--- a/keystore/KeystoreResponse.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-**
-** Copyright 2018, 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 <binder/Parcel.h>
-#include <keystore/keymaster_types.h>
-#include <utility>
-#include <utils/String16.h>
-
-#include "include/keystore/KeystoreResponse.h"
-
-namespace android {
-namespace security {
-namespace keystore {
-
-status_t KeystoreResponse::readFromParcel(const Parcel* in) {
-    auto rc = in->readInt32(&response_code_);
-    if (rc != NO_ERROR) return rc;
-    return in->readString16(&error_msg_);
-}
-
-status_t KeystoreResponse::writeToParcel(Parcel* out) const {
-    auto rc = out->writeInt32(response_code_);
-    if (rc != NO_ERROR) return rc;
-    return out->writeString16(error_msg_);
-}
-
-}  // namespace keystore
-}  // namespace security
-}  // namespace android
diff --git a/keystore/OperationResult.cpp b/keystore/OperationResult.cpp
deleted file mode 100644
index dec4d40..0000000
--- a/keystore/OperationResult.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-**
-** Copyright 2017, 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/OperationResult.h"
-
-#include <utility>
-
-#include <binder/Parcel.h>
-
-#include <keystore/keymaster_types.h>
-
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-namespace android {
-namespace security {
-namespace keymaster {
-
-using ::android::status_t;
-using ::keystore::ErrorCode;
-
-OperationResult::OperationResult() : resultCode(), token(), handle(0), inputConsumed(0), data() {}
-
-status_t OperationResult::readFromParcel(const Parcel* inn) {
-    const Parcel& in = *inn;
-    resultCode = ErrorCode(in.readInt32());
-    token = in.readStrongBinder();
-    handle = static_cast<uint64_t>(in.readInt64());
-    inputConsumed = in.readInt32();
-    data = keystore::readKeymasterBlob(in);
-    outParams = keystore::readParamSetFromParcel(in);
-    return OK;
-}
-
-status_t OperationResult::writeToParcel(Parcel* out) const {
-    out->writeInt32(resultCode.getErrorCode());
-    out->writeStrongBinder(token);
-    out->writeInt64(handle);
-    out->writeInt32(inputConsumed);
-    keystore::writeKeymasterBlob(data, out);
-    keystore::writeParamSetToParcel(outParams, out);
-    return OK;
-}
-
-OperationResult operationFailed(const ::keystore::KeyStoreServiceReturnCode& error) {
-    OperationResult opResult = {};
-    opResult.resultCode = error;
-    return opResult;
-}
-
-}  // namespace keymaster
-}  // namespace security
-}  // namespace android
diff --git a/keystore/TEST_MAPPING b/keystore/TEST_MAPPING
new file mode 100644
index 0000000..0511967
--- /dev/null
+++ b/keystore/TEST_MAPPING
@@ -0,0 +1,74 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsKeystoreTestCases",
+      "options": [
+        {
+          "include-annotation": "android.platform.test.annotations.RequiresDevice"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.SignatureTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.RsaSignaturePerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.RsaKeyGenPerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.RsaCipherPerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.MacTest#testLargeMsgKat"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.KeyPairGeneratorTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.KeyGeneratorTest#testHmacKeySupportedSizes"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.HmacMacPerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.EcdsaSignaturePerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.EcKeyGenPerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.DesCipherPerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.CipherTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.AttestationPerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.AndroidKeyStoreTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.AesCipherPerformanceTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.AESCipherNistCavpKatTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.DESedeECBPKCS7PaddingCipherTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.DESedeECBNoPaddingCipherTest"
+        },
+        {
+          "exclude-filter": "android.keystore.cts.DESedeECBPKCS7PaddingCipherTest"
+        }
+      ]
+    }
+  ],
+  "postsubmit": [
+    {
+      "name": "CtsKeystoreTestCases"
+    }
+  ]
+}
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
deleted file mode 100644
index 5e6d572..0000000
--- a/keystore/auth_token_table.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#define LOG_TAG "keystore"
-
-#include "auth_token_table.h"
-
-#include <assert.h>
-#include <time.h>
-
-#include <algorithm>
-
-#include <log/log.h>
-
-namespace keystore {
-
-template <typename IntType, uint32_t byteOrder> struct choose_hton;
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
-    inline static IntType hton(const IntType& value) {
-        IntType result = 0;
-        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
-        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
-        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
-            *(outbytes++) = inbytes[i];
-        }
-        return result;
-    }
-};
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
-    inline static IntType hton(const IntType& value) { return value; }
-};
-
-template <typename IntType> inline IntType hton(const IntType& value) {
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-template <typename IntType> inline IntType ntoh(const IntType& value) {
-    // same operation and hton
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-//
-// Some trivial template wrappers around std algorithms, so they take containers not ranges.
-//
-template <typename Container, typename Predicate>
-typename Container::iterator find_if(Container& container, Predicate pred) {
-    return std::find_if(container.begin(), container.end(), pred);
-}
-
-template <typename Container, typename Predicate>
-typename Container::iterator remove_if(Container& container, Predicate pred) {
-    return std::remove_if(container.begin(), container.end(), pred);
-}
-
-template <typename Container> typename Container::iterator min_element(Container& container) {
-    return std::min_element(container.begin(), container.end());
-}
-
-time_t clock_gettime_raw() {
-    struct timespec time;
-    clock_gettime(CLOCK_MONOTONIC_RAW, &time);
-    return time.tv_sec;
-}
-
-void AuthTokenTable::AddAuthenticationToken(HardwareAuthToken&& auth_token) {
-    Entry new_entry(std::move(auth_token), clock_function_());
-    // STOPSHIP: debug only, to be removed
-    ALOGD("AddAuthenticationToken: timestamp = %llu, time_received = %lld",
-          static_cast<unsigned long long>(new_entry.token().timestamp),
-          static_cast<long long>(new_entry.time_received()));
-
-    std::lock_guard<std::mutex> lock(entries_mutex_);
-    RemoveEntriesSupersededBy(new_entry);
-    if (entries_.size() >= max_entries_) {
-        ALOGW("Auth token table filled up; replacing oldest entry");
-        *min_element(entries_) = std::move(new_entry);
-    } else {
-        entries_.push_back(std::move(new_entry));
-    }
-}
-
-inline bool is_secret_key_operation(Algorithm algorithm, KeyPurpose purpose) {
-    if ((algorithm != Algorithm::RSA && algorithm != Algorithm::EC)) return true;
-    if (purpose == KeyPurpose::SIGN || purpose == KeyPurpose::DECRYPT) return true;
-    return false;
-}
-
-inline bool KeyRequiresAuthentication(const AuthorizationSet& key_info, KeyPurpose purpose) {
-    auto algorithm = defaultOr(key_info.GetTagValue(TAG_ALGORITHM), Algorithm::AES);
-    return is_secret_key_operation(algorithm, purpose) &&
-           key_info.find(Tag::NO_AUTH_REQUIRED) == -1;
-}
-
-inline bool KeyRequiresAuthPerOperation(const AuthorizationSet& key_info, KeyPurpose purpose) {
-    auto algorithm = defaultOr(key_info.GetTagValue(TAG_ALGORITHM), Algorithm::AES);
-    return is_secret_key_operation(algorithm, purpose) && key_info.find(Tag::AUTH_TIMEOUT) == -1;
-}
-
-std::tuple<AuthTokenTable::Error, HardwareAuthToken>
-AuthTokenTable::FindAuthorization(const AuthorizationSet& key_info, KeyPurpose purpose,
-                                  uint64_t op_handle) {
-
-    std::lock_guard<std::mutex> lock(entries_mutex_);
-
-    if (!KeyRequiresAuthentication(key_info, purpose)) return {AUTH_NOT_REQUIRED, {}};
-
-    auto auth_type =
-        defaultOr(key_info.GetTagValue(TAG_USER_AUTH_TYPE), HardwareAuthenticatorType::NONE);
-
-    std::vector<uint64_t> key_sids;
-    ExtractSids(key_info, &key_sids);
-
-    if (KeyRequiresAuthPerOperation(key_info, purpose))
-        return FindAuthPerOpAuthorization(key_sids, auth_type, op_handle);
-    else
-        return FindTimedAuthorization(key_sids, auth_type, key_info);
-}
-
-std::tuple<AuthTokenTable::Error, HardwareAuthToken> AuthTokenTable::FindAuthPerOpAuthorization(
-    const std::vector<uint64_t>& sids, HardwareAuthenticatorType auth_type, uint64_t op_handle) {
-    if (op_handle == 0) return {OP_HANDLE_REQUIRED, {}};
-
-    auto matching_op = find_if(
-        entries_, [&](Entry& e) { return e.token().challenge == op_handle && !e.completed(); });
-
-    if (matching_op == entries_.end()) return {AUTH_TOKEN_NOT_FOUND, {}};
-
-    if (!matching_op->SatisfiesAuth(sids, auth_type)) return {AUTH_TOKEN_WRONG_SID, {}};
-
-    return {OK, matching_op->token()};
-}
-
-std::tuple<AuthTokenTable::Error, HardwareAuthToken>
-AuthTokenTable::FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                       HardwareAuthenticatorType auth_type,
-                                       const AuthorizationSet& key_info) {
-    Entry* newest_match = nullptr;
-    for (auto& entry : entries_)
-        if (entry.SatisfiesAuth(sids, auth_type) && entry.is_newer_than(newest_match))
-            newest_match = &entry;
-
-    if (!newest_match) return {AUTH_TOKEN_NOT_FOUND, {}};
-
-    auto timeout = defaultOr(key_info.GetTagValue(TAG_AUTH_TIMEOUT), 0);
-
-    time_t now = clock_function_();
-    if (static_cast<int64_t>(newest_match->time_received()) + timeout < static_cast<int64_t>(now))
-        return {AUTH_TOKEN_EXPIRED, {}};
-
-    if (key_info.GetTagValue(TAG_ALLOW_WHILE_ON_BODY).isOk()) {
-        if (static_cast<int64_t>(newest_match->time_received()) <
-            static_cast<int64_t>(last_off_body_)) {
-            return {AUTH_TOKEN_EXPIRED, {}};
-        }
-    }
-
-    newest_match->UpdateLastUse(now);
-    return {OK, newest_match->token()};
-}
-
-std::tuple<AuthTokenTable::Error, HardwareAuthToken>
-AuthTokenTable::FindAuthorizationForCredstore(uint64_t challenge, uint64_t secureUserId,
-                                              int64_t authTokenMaxAgeMillis) {
-    std::vector<uint64_t> sids = {secureUserId};
-    HardwareAuthenticatorType auth_type = HardwareAuthenticatorType::ANY;
-
-    time_t now = clock_function_();
-
-    // challenge-based - the authToken has to contain the given challenge.
-    if (challenge != 0) {
-        auto matching_op = find_if(
-            entries_, [&](Entry& e) { return e.token().challenge == challenge && !e.completed(); });
-        if (matching_op == entries_.end()) {
-            return {AUTH_TOKEN_NOT_FOUND, {}};
-        }
-
-        if (!matching_op->SatisfiesAuth(sids, auth_type)) {
-            return {AUTH_TOKEN_WRONG_SID, {}};
-        }
-
-        if (authTokenMaxAgeMillis > 0) {
-            if (static_cast<int64_t>(matching_op->time_received()) + authTokenMaxAgeMillis <
-                static_cast<int64_t>(now)) {
-                return {AUTH_TOKEN_EXPIRED, {}};
-            }
-        }
-
-        return {OK, matching_op->token()};
-    }
-
-    // Otherwise, no challenge - any authToken younger than the specified maximum
-    // age will do.
-    Entry* newest_match = nullptr;
-    for (auto& entry : entries_) {
-        if (entry.SatisfiesAuth(sids, auth_type) && entry.is_newer_than(newest_match)) {
-            newest_match = &entry;
-        }
-    }
-
-    if (newest_match == nullptr) {
-        return {AUTH_TOKEN_NOT_FOUND, {}};
-    }
-
-    if (authTokenMaxAgeMillis > 0) {
-        if (static_cast<int64_t>(newest_match->time_received()) + authTokenMaxAgeMillis <
-            static_cast<int64_t>(now)) {
-            return {AUTH_TOKEN_EXPIRED, {}};
-        }
-    }
-
-    newest_match->UpdateLastUse(now);
-    return {OK, newest_match->token()};
-}
-
-void AuthTokenTable::ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids) {
-    assert(sids);
-    for (auto& param : key_info)
-        if (param.tag == Tag::USER_SECURE_ID)
-            sids->push_back(authorizationValue(TAG_USER_SECURE_ID, param).value());
-}
-
-void AuthTokenTable::RemoveEntriesSupersededBy(const Entry& entry) {
-    entries_.erase(remove_if(entries_, [&](Entry& e) { return entry.Supersedes(e); }),
-                   entries_.end());
-}
-
-void AuthTokenTable::onDeviceOffBody() {
-    last_off_body_ = clock_function_();
-}
-
-void AuthTokenTable::Clear() {
-    std::lock_guard<std::mutex> lock(entries_mutex_);
-
-    entries_.clear();
-}
-
-size_t AuthTokenTable::size() const {
-    std::lock_guard<std::mutex> lock(entries_mutex_);
-    return entries_.size();
-}
-
-bool AuthTokenTable::IsSupersededBySomeEntry(const Entry& entry) {
-    return std::any_of(entries_.begin(), entries_.end(),
-                       [&](Entry& e) { return e.Supersedes(entry); });
-}
-
-void AuthTokenTable::MarkCompleted(const uint64_t op_handle) {
-    std::lock_guard<std::mutex> lock(entries_mutex_);
-
-    auto found = find_if(entries_, [&](Entry& e) { return e.token().challenge == op_handle; });
-    if (found == entries_.end()) return;
-
-    assert(!IsSupersededBySomeEntry(*found));
-    found->mark_completed();
-
-    if (IsSupersededBySomeEntry(*found)) entries_.erase(found);
-}
-
-AuthTokenTable::Entry::Entry(HardwareAuthToken&& token, time_t current_time)
-    : token_(std::move(token)), time_received_(current_time), last_use_(current_time),
-      operation_completed_(token_.challenge == 0) {}
-
-bool AuthTokenTable::Entry::SatisfiesAuth(const std::vector<uint64_t>& sids,
-                                          HardwareAuthenticatorType auth_type) {
-    for (auto sid : sids) {
-        if (SatisfiesAuth(sid, auth_type)) return true;
-    }
-    return false;
-}
-
-void AuthTokenTable::Entry::UpdateLastUse(time_t time) {
-    this->last_use_ = time;
-}
-
-bool AuthTokenTable::Entry::Supersedes(const Entry& entry) const {
-    if (!entry.completed()) return false;
-
-    return (token_.userId == entry.token_.userId &&
-            token_.authenticatorType == entry.token_.authenticatorType &&
-            token_.authenticatorId == entry.token_.authenticatorId && is_newer_than(&entry));
-}
-
-}  // namespace keystore
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
deleted file mode 100644
index 787b9b1..0000000
--- a/keystore/auth_token_table.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2015 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 <memory>
-#include <mutex>
-#include <vector>
-
-#include <keystore/keymaster_types.h>
-
-#ifndef KEYSTORE_AUTH_TOKEN_TABLE_H_
-#define KEYSTORE_AUTH_TOKEN_TABLE_H_
-
-namespace keystore {
-
-namespace test {
-class AuthTokenTableTest;
-}  // namespace test
-
-time_t clock_gettime_raw();
-
-/**
- * AuthTokenTable manages a set of received authorization tokens and can provide the appropriate
- * token for authorizing a key operation.
- *
- * To keep the table from growing without bound, superseded entries are removed when possible, and
- * least recently used entries are automatically pruned when when the table exceeds a size limit,
- * which is expected to be relatively small, since the implementation uses a linear search.
- */
-class AuthTokenTable {
-  public:
-    explicit AuthTokenTable(size_t max_entries = 32, time_t (*clock_function)() = clock_gettime_raw)
-        : max_entries_(max_entries), last_off_body_(clock_function()),
-          clock_function_(clock_function) {}
-
-    enum Error {
-        OK,
-        AUTH_NOT_REQUIRED = -1,
-        AUTH_TOKEN_EXPIRED = -2,    // Found a matching token, but it's too old.
-        AUTH_TOKEN_WRONG_SID = -3,  // Found a token with the right challenge, but wrong SID.  This
-                                    // most likely indicates that the authenticator was updated
-                                    // (e.g. new fingerprint enrolled).
-        OP_HANDLE_REQUIRED = -4,    // The key requires auth per use but op_handle was zero.
-        AUTH_TOKEN_NOT_FOUND = -5,
-    };
-
-    /**
-     * Add an authorization token to the table.
-     */
-    void AddAuthenticationToken(HardwareAuthToken&& auth_token);
-
-    /**
-     * Find an authorization token that authorizes the operation specified by \p operation_handle on
-     * a key with the characteristics specified in \p key_info.
-     *
-     * This method is O(n * m), where n is the number of KM_TAG_USER_SECURE_ID entries in key_info
-     * and m is the number of entries in the table.  It could be made better, but n and m should
-     * always be small.
-     *
-     * The table retains ownership of the returned object.
-     */
-    std::tuple<Error, HardwareAuthToken> FindAuthorization(const AuthorizationSet& key_info,
-                                                           KeyPurpose purpose, uint64_t op_handle);
-
-    std::tuple<Error, HardwareAuthToken>
-    FindAuthorizationForCredstore(uint64_t challenge, uint64_t secureUserId,
-                                  int64_t authTokenMaxAgeMillis);
-
-    /**
-     * Mark operation completed.  This allows tokens associated with the specified operation to be
-     * superseded by new tokens.
-     */
-    void MarkCompleted(const uint64_t op_handle);
-
-    /**
-     * Update the last_off_body_ timestamp so that tokens which remain authorized only so long as
-     * the device stays on body can be revoked.
-     */
-    void onDeviceOffBody();
-
-    void Clear();
-
-    /**
-     * This function shall only be used for testing.
-     *
-     * BEWARE: Since the auth token table can be accessed
-     * concurrently, the size may be out dated as soon as it returns.
-     */
-    size_t size() const;
-
-  private:
-    friend class AuthTokenTableTest;
-
-    class Entry {
-      public:
-        Entry(HardwareAuthToken&& token, time_t current_time);
-        Entry(Entry&& entry) noexcept { *this = std::move(entry); }
-
-        void operator=(Entry&& rhs) noexcept {
-            token_ = std::move(rhs.token_);
-            time_received_ = rhs.time_received_;
-            last_use_ = rhs.last_use_;
-            operation_completed_ = rhs.operation_completed_;
-        }
-
-        bool operator<(const Entry& rhs) const { return last_use_ < rhs.last_use_; }
-
-        void UpdateLastUse(time_t time);
-
-        bool Supersedes(const Entry& entry) const;
-        bool SatisfiesAuth(const std::vector<uint64_t>& sids, HardwareAuthenticatorType auth_type);
-
-        bool is_newer_than(const Entry* entry) const {
-            if (!entry) return true;
-            uint64_t ts = token_.timestamp;
-            uint64_t other_ts = entry->token_.timestamp;
-            // Normally comparing timestamp_host_order alone is sufficient, but here is an
-            // additional hack to compare time_received value for some devices where their auth
-            // tokens contain fixed timestamp (due to the a stuck secure RTC on them)
-            return (ts > other_ts) ||
-                   ((ts == other_ts) && (time_received_ > entry->time_received_));
-        }
-
-        void mark_completed() { operation_completed_ = true; }
-
-        const HardwareAuthToken& token() const & { return token_; }
-        time_t time_received() const { return time_received_; }
-        bool completed() const { return operation_completed_; }
-
-      private:
-        bool SatisfiesAuth(uint64_t sid, HardwareAuthenticatorType auth_type) const {
-            return (sid == token_.userId || sid == token_.authenticatorId) &&
-                   (auth_type & token_.authenticatorType) != 0;
-        }
-
-        HardwareAuthToken token_;
-        time_t time_received_;
-        time_t last_use_;
-        bool operation_completed_;
-    };
-
-    std::tuple<Error, HardwareAuthToken>
-    FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
-                               HardwareAuthenticatorType auth_type, uint64_t op_handle);
-    std::tuple<Error, HardwareAuthToken> FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                                                HardwareAuthenticatorType auth_type,
-                                                                const AuthorizationSet& key_info);
-    void ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids);
-    void RemoveEntriesSupersededBy(const Entry& entry);
-    bool IsSupersededBySomeEntry(const Entry& entry);
-
-    /**
-     * Guards the entries_ vector against concurrent modification. All public facing methods
-     * reading of modifying the vector must grab this mutex.
-     */
-    mutable std::mutex entries_mutex_;
-    std::vector<Entry> entries_;
-    size_t max_entries_;
-    time_t last_off_body_;
-    time_t (*clock_function_)();
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_AUTH_TOKEN_TABLE_H_
diff --git a/keystore/binder/android/security/IConfirmationPromptCallback.aidl b/keystore/binder/android/security/IConfirmationPromptCallback.aidl
deleted file mode 100644
index 96a1a04..0000000
--- a/keystore/binder/android/security/IConfirmationPromptCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2017, 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;
-
-/**
- * This must be kept manually in sync with system/security/keystore until AIDL
- * can generate both Java and C++ bindings.
- *
- * @hide
- */
-interface IConfirmationPromptCallback {
-    oneway void onConfirmationPromptCompleted(in int result, in byte[] dataThatWasConfirmed);
-}
diff --git a/keystore/binder/android/security/keymaster/ExportResult.aidl b/keystore/binder/android/security/keymaster/ExportResult.aidl
deleted file mode 100644
index 1748653..0000000
--- a/keystore/binder/android/security/keymaster/ExportResult.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2015 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.keymaster;
-
-/* @hide */
-parcelable ExportResult cpp_header "keystore/ExportResult.h";
diff --git a/keystore/binder/android/security/keymaster/KeyCharacteristics.aidl b/keystore/binder/android/security/keymaster/KeyCharacteristics.aidl
deleted file mode 100644
index 32e75ad..0000000
--- a/keystore/binder/android/security/keymaster/KeyCharacteristics.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2015 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.keymaster;
-
-/* @hide */
-parcelable KeyCharacteristics cpp_header "keystore/KeyCharacteristics.h";
diff --git a/keystore/binder/android/security/keymaster/KeymasterArguments.aidl b/keystore/binder/android/security/keymaster/KeymasterArguments.aidl
deleted file mode 100644
index 44d9f09..0000000
--- a/keystore/binder/android/security/keymaster/KeymasterArguments.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2015 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.keymaster;
-
-/* @hide */
-parcelable KeymasterArguments cpp_header "keystore/KeymasterArguments.h";
diff --git a/keystore/binder/android/security/keymaster/KeymasterBlob.aidl b/keystore/binder/android/security/keymaster/KeymasterBlob.aidl
deleted file mode 100644
index 5c5db9e..0000000
--- a/keystore/binder/android/security/keymaster/KeymasterBlob.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2015 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.keymaster;
-
-/* @hide */
-parcelable KeymasterBlob cpp_header "keystore/KeymasterBlob.h";
diff --git a/keystore/binder/android/security/keymaster/KeymasterCertificateChain.aidl b/keystore/binder/android/security/keymaster/KeymasterCertificateChain.aidl
deleted file mode 100644
index ddb5cae..0000000
--- a/keystore/binder/android/security/keymaster/KeymasterCertificateChain.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.security.keymaster;
-
-/* @hide */
-parcelable KeymasterCertificateChain cpp_header "keystore/KeymasterCertificateChain.h";
diff --git a/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
deleted file mode 100644
index dca928d..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreCertificateChainCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2018, 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.keystore;
-
-import android.security.keystore.KeystoreResponse;
-import android.security.keymaster.KeymasterCertificateChain;
-
-/**
- * @hide
- */
-oneway interface IKeystoreCertificateChainCallback {
-    void onFinished(in KeystoreResponse response, in KeymasterCertificateChain chain);
-}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
deleted file mode 100644
index e42e927..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2018, 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.keystore;
-
-import android.security.keystore.KeystoreResponse;
-import android.security.keymaster.ExportResult;
-
-/**
- * @hide
- */
-oneway interface IKeystoreExportKeyCallback {
-	void onFinished(in ExportResult result);
-}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
deleted file mode 100644
index e1f0ffe..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2018, 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.keystore;
-
-import android.security.keystore.KeystoreResponse;
-import android.security.keymaster.KeyCharacteristics;
-
-/**
- * @hide
- */
-oneway interface IKeystoreKeyCharacteristicsCallback {
-	void onFinished(in KeystoreResponse response, in KeyCharacteristics charactersistics);
-}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
deleted file mode 100644
index 0a51511..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2018, 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.keystore;
-
-import android.security.keystore.KeystoreResponse;
-import android.security.keymaster.OperationResult;
-
-/**
- * @hide
- */
-oneway interface IKeystoreOperationResultCallback {
-    void onFinished(in OperationResult result);
-}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
deleted file mode 100644
index 912e605..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreResponseCallback.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (c) 2018, 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.keystore;
-
-import android.security.keystore.KeystoreResponse;
-
-/**
- * @hide
- */
-oneway interface IKeystoreResponseCallback {
-    void onFinished(in KeystoreResponse response);
-}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreService.aidl b/keystore/binder/android/security/keystore/IKeystoreService.aidl
deleted file mode 100644
index 6edca56..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreService.aidl
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (c) 2018, 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.keystore;
-
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterBlob;
-import android.security.keymaster.OperationResult;
-import android.security.keystore.ICredstoreTokenCallback;
-import android.security.keystore.IKeystoreResponseCallback;
-import android.security.keystore.IKeystoreKeyCharacteristicsCallback;
-import android.security.keystore.IKeystoreExportKeyCallback;
-import android.security.keystore.IKeystoreOperationResultCallback;
-import android.security.keystore.IKeystoreCertificateChainCallback;
-
-/**
- * @hide
- */
-interface IKeystoreService {
-    @UnsupportedAppUsage
-    int getState(int userId);
-    @UnsupportedAppUsage
-    byte[] get(String name, int uid);
-    @UnsupportedAppUsage
-    int insert(String name, in byte[] item, int uid, int flags);
-    @UnsupportedAppUsage
-    int del(String name, int uid);
-    @UnsupportedAppUsage
-    int exist(String name, int uid);
-    @UnsupportedAppUsage
-    String[] list(String namePrefix, int uid);
-    int onUserPasswordChanged(int userId, String newPassword);
-    int lock(int userId);
-    int unlock(int userId, String userPassword);
-    int isEmpty(int userId);
-    String grant(String name, int granteeUid);
-    @UnsupportedAppUsage
-    int ungrant(String name, int granteeUid);
-    long getmtime(String name, int uid);
-    @UnsupportedAppUsage
-    int is_hardware_backed(String string);
-    @UnsupportedAppUsage
-    int clear_uid(long uid);
-
-    int addRngEntropy(IKeystoreResponseCallback cb, in byte[] data, int flags);
-    int generateKey(IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterArguments arguments, in byte[] entropy, int uid,
-        int flags);
-    int getKeyCharacteristics (IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterBlob clientId, in KeymasterBlob appData,
-        int uid);
-    int importKey(IKeystoreKeyCharacteristicsCallback cb, String alias, in KeymasterArguments arguments, int format,
-        in byte[] keyData, int uid, int flags);
-    int exportKey(IKeystoreExportKeyCallback cb, String alias, int format, in KeymasterBlob clientId,
-        in KeymasterBlob appData, int uid);
-    int begin(in IKeystoreOperationResultCallback cb, IBinder appToken, String alias, int purpose, boolean pruneable,
-        in KeymasterArguments params, in byte[] entropy, int uid);
-    int update(in IKeystoreOperationResultCallback cb, IBinder token, in KeymasterArguments params, in byte[] input);
-    int finish(in IKeystoreOperationResultCallback cb, IBinder token, in KeymasterArguments params, in byte[] input, in byte[] signature,
-        in byte[] entropy);
-    int abort(in IKeystoreResponseCallback cb, IBinder token);
-    int addAuthToken(in byte[] authToken);
-    int onUserAdded(int userId, int parentId);
-    int onUserRemoved(int userId);
-    int attestKey(in IKeystoreCertificateChainCallback cb, String alias, in KeymasterArguments params);
-    int attestDeviceIds(in IKeystoreCertificateChainCallback cb, in KeymasterArguments params);
-    int onDeviceOffBody();
-    int importWrappedKey(in IKeystoreKeyCharacteristicsCallback cb, String wrappedKeyAlias, in byte[] wrappedKey,
-        in String wrappingKeyAlias, in byte[] maskingKey, in KeymasterArguments arguments,
-        in long rootSid, in long fingerprintSid);
-    int presentConfirmationPrompt(IBinder listener, String promptText, in byte[] extraData,
-        in String locale, in int uiOptionsAsFlags);
-    int cancelConfirmationPrompt(IBinder listener);
-    boolean isConfirmationPromptSupported();
-    int onKeyguardVisibilityChanged(in boolean isShowing, in int userId);
-    int listUidsOfAuthBoundKeys(out @utf8InCpp List<String> uids);
-
-    // Called by credstore (and only credstore).
-    void getTokensForCredstore(in long challenge, in long secureUserId, in int authTokenMaxAgeMillis,
-                               in ICredstoreTokenCallback cb);
-}
diff --git a/keystore/binder/android/security/keystore/KeystoreResponse.aidl b/keystore/binder/android/security/keystore/KeystoreResponse.aidl
deleted file mode 100644
index 128b456..0000000
--- a/keystore/binder/android/security/keystore/KeystoreResponse.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2018 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.keystore;
-
-/* @hide */
-parcelable KeystoreResponse cpp_header "keystore/KeystoreResponse.h";
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
deleted file mode 100644
index ffdb454..0000000
--- a/keystore/blob.cpp
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#define LOG_TAG "keystore"
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include <log/log.h>
-
-#include "blob.h"
-
-#include "keystore_utils.h"
-
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-
-#include <istream>
-#include <ostream>
-#include <streambuf>
-#include <string>
-
-#include <android-base/logging.h>
-#include <android-base/unique_fd.h>
-
-namespace {
-
-constexpr size_t kGcmIvSizeBytes = 96 / 8;
-
-#if defined(__clang__)
-#define OPTNONE __attribute__((optnone))
-#elif defined(__GNUC__)
-#define OPTNONE __attribute__((optimize("O0")))
-#else
-#error Need a definition for OPTNONE
-#endif
-
-class ArrayEraser {
-  public:
-    ArrayEraser(uint8_t* arr, size_t size) : mArr(arr), mSize(size) {}
-    OPTNONE ~ArrayEraser() { std::fill(mArr, mArr + mSize, 0); }
-
-  private:
-    volatile uint8_t* mArr;
-    size_t mSize;
-};
-
-/**
- * Returns a EVP_CIPHER appropriate for the given key, based on the key's size.
- */
-const EVP_CIPHER* getAesCipherForKey(const std::vector<uint8_t>& key) {
-    const EVP_CIPHER* cipher = EVP_aes_256_gcm();
-    if (key.size() == kAes128KeySizeBytes) {
-        cipher = EVP_aes_128_gcm();
-    }
-    return cipher;
-}
-
-/*
- * Encrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
- * 'iv' and write output to 'out' (which may be the same location as 'in') and 128-bit tag to
- * 'tag'.
- */
-ResponseCode AES_gcm_encrypt(const uint8_t* in, uint8_t* out, size_t len,
-                             const std::vector<uint8_t>& key, const uint8_t* iv, uint8_t* tag) {
-
-    // There can be 128-bit and 256-bit keys
-    const EVP_CIPHER* cipher = getAesCipherForKey(key);
-
-    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
-
-    EVP_EncryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key.data(), iv);
-    EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
-
-    std::unique_ptr<uint8_t[]> out_tmp(new uint8_t[len]);
-    uint8_t* out_pos = out_tmp.get();
-    int out_len;
-
-    EVP_EncryptUpdate(ctx.get(), out_pos, &out_len, in, len);
-    out_pos += out_len;
-    EVP_EncryptFinal_ex(ctx.get(), out_pos, &out_len);
-    out_pos += out_len;
-    if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
-        ALOGD("Encrypted ciphertext is the wrong size, expected %zu, got %zd", len,
-              out_pos - out_tmp.get());
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    std::copy(out_tmp.get(), out_pos, out);
-    EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kGcmTagLength, tag);
-
-    return ResponseCode::NO_ERROR;
-}
-
-/*
- * Decrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
- * 'iv', checking 128-bit tag at 'tag' and writing plaintext to 'out'(which may be the same
- * location as 'in').
- */
-ResponseCode AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len,
-                             const std::vector<uint8_t> key, const uint8_t* iv,
-                             const uint8_t* tag) {
-
-    // There can be 128-bit and 256-bit keys
-    const EVP_CIPHER* cipher = getAesCipherForKey(key);
-
-    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
-
-    EVP_DecryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key.data(), iv);
-    EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
-    EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kGcmTagLength, const_cast<uint8_t*>(tag));
-
-    std::unique_ptr<uint8_t[]> out_tmp(new uint8_t[len]);
-    ArrayEraser out_eraser(out_tmp.get(), len);
-    uint8_t* out_pos = out_tmp.get();
-    int out_len;
-
-    EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
-    out_pos += out_len;
-    if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
-        ALOGE("Failed to decrypt blob; ciphertext or tag is likely corrupted");
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-    out_pos += out_len;
-    if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
-        ALOGE("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
-              out_pos - out_tmp.get());
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-
-    std::copy(out_tmp.get(), out_pos, out);
-
-    return ResponseCode::NO_ERROR;
-}
-
-class ArrayStreamBuffer : public std::streambuf {
-  public:
-    template <typename T, size_t size> explicit ArrayStreamBuffer(const T (&data)[size]) {
-        static_assert(sizeof(T) == 1, "Array element size too large");
-        std::streambuf::char_type* d = const_cast<std::streambuf::char_type*>(
-            reinterpret_cast<const std::streambuf::char_type*>(&data[0]));
-        setg(d, d, d + size);
-        setp(d, d + size);
-    }
-
-  protected:
-    pos_type seekoff(off_type off, std::ios_base::seekdir dir,
-                     std::ios_base::openmode which = std::ios_base::in |
-                                                     std::ios_base::out) override {
-        bool in = which & std::ios_base::in;
-        bool out = which & std::ios_base::out;
-        if ((!in && !out) || (in && out && dir == std::ios_base::cur)) return -1;
-        std::streambuf::char_type* newPosPtr;
-        switch (dir) {
-        case std::ios_base::beg:
-            newPosPtr = pbase();
-            break;
-        case std::ios_base::cur:
-            // if dir == cur then in xor out due to
-            // if ((!in && !out) || (in && out && dir == std::ios_base::cur)) return -1; above
-            if (in)
-                newPosPtr = gptr();
-            else
-                newPosPtr = pptr();
-            break;
-        case std::ios_base::end:
-            // in and out bounds are the same and cannot change, so we can take either range
-            // regardless of the value of "which"
-            newPosPtr = epptr();
-            break;
-        }
-        newPosPtr += off;
-        if (newPosPtr < pbase() || newPosPtr > epptr()) return -1;
-        if (in) {
-            gbump(newPosPtr - gptr());
-        }
-        if (out) {
-            pbump(newPosPtr - pptr());
-        }
-        return newPosPtr - pbase();
-    }
-};
-
-}  // namespace
-
-Blob::Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
-           BlobType type) {
-    mBlob = std::make_unique<blobv3>();
-    memset(mBlob.get(), 0, sizeof(blobv3));
-    if (valueLength > kValueSize) {
-        valueLength = kValueSize;
-        ALOGW("Provided blob length too large");
-    }
-    if (infoLength + valueLength > kValueSize) {
-        infoLength = kValueSize - valueLength;
-        ALOGW("Provided info length too large");
-    }
-    mBlob->length = valueLength;
-    memcpy(mBlob->value, value, valueLength);
-
-    mBlob->info = infoLength;
-    memcpy(mBlob->value + valueLength, info, infoLength);
-
-    mBlob->version = CURRENT_BLOB_VERSION;
-    mBlob->type = uint8_t(type);
-
-    if (type == TYPE_MASTER_KEY || type == TYPE_MASTER_KEY_AES256) {
-        mBlob->flags = KEYSTORE_FLAG_ENCRYPTED;
-    } else {
-        mBlob->flags = KEYSTORE_FLAG_NONE;
-    }
-}
-
-Blob::Blob(blobv3 b) {
-    mBlob = std::make_unique<blobv3>(b);
-}
-
-Blob::Blob() {
-    if (mBlob) *mBlob = {};
-}
-
-Blob::Blob(const Blob& rhs) {
-    if (rhs.mBlob) {
-        mBlob = std::make_unique<blobv3>(*rhs.mBlob);
-    }
-}
-
-Blob::Blob(Blob&& rhs) : mBlob(std::move(rhs.mBlob)) {}
-
-Blob& Blob::operator=(const Blob& rhs) {
-    if (&rhs != this) {
-        if (mBlob) *mBlob = {};
-        if (rhs) {
-            mBlob = std::make_unique<blobv3>(*rhs.mBlob);
-        } else {
-            mBlob = {};
-        }
-    }
-    return *this;
-}
-
-Blob& Blob::operator=(Blob&& rhs) {
-    if (mBlob) *mBlob = {};
-    mBlob = std::move(rhs.mBlob);
-    return *this;
-}
-
-template <typename BlobType> static bool rawBlobIsEncrypted(const BlobType& blob) {
-    if (blob.version < 2) return true;
-
-    return blob.flags & (KEYSTORE_FLAG_ENCRYPTED | KEYSTORE_FLAG_SUPER_ENCRYPTED);
-}
-
-bool Blob::isEncrypted() const {
-    if (mBlob->version < 2) {
-        return true;
-    }
-
-    return mBlob->flags & KEYSTORE_FLAG_ENCRYPTED;
-}
-
-bool Blob::isSuperEncrypted() const {
-    return mBlob->flags & KEYSTORE_FLAG_SUPER_ENCRYPTED;
-}
-
-bool Blob::isCriticalToDeviceEncryption() const {
-    return mBlob->flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
-}
-
-inline uint8_t setFlag(uint8_t flags, bool set, KeyStoreFlag flag) {
-    return set ? (flags | flag) : (flags & ~flag);
-}
-
-void Blob::setEncrypted(bool encrypted) {
-    mBlob->flags = setFlag(mBlob->flags, encrypted, KEYSTORE_FLAG_ENCRYPTED);
-}
-
-void Blob::setSuperEncrypted(bool superEncrypted) {
-    mBlob->flags = setFlag(mBlob->flags, superEncrypted, KEYSTORE_FLAG_SUPER_ENCRYPTED);
-}
-
-void Blob::setCriticalToDeviceEncryption(bool critical) {
-    mBlob->flags = setFlag(mBlob->flags, critical, KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
-}
-
-void Blob::setFallback(bool fallback) {
-    if (fallback) {
-        mBlob->flags |= KEYSTORE_FLAG_FALLBACK;
-    } else {
-        mBlob->flags &= ~KEYSTORE_FLAG_FALLBACK;
-    }
-}
-
-static ResponseCode writeBlob(const std::string& filename, Blob blob, blobv3* rawBlob,
-                              const std::vector<uint8_t>& aes_key, State state) {
-    ALOGV("writing blob %s", filename.c_str());
-
-    const size_t dataLength = rawBlob->length;
-    rawBlob->length = htonl(rawBlob->length);
-
-    if (blob.isEncrypted() || blob.isSuperEncrypted()) {
-        if (state != STATE_NO_ERROR) {
-            ALOGD("couldn't insert encrypted blob while not unlocked");
-            return ResponseCode::LOCKED;
-        }
-
-        memset(rawBlob->initialization_vector, 0, AES_BLOCK_SIZE);
-        if (!RAND_bytes(rawBlob->initialization_vector, kGcmIvSizeBytes)) {
-            ALOGW("Could not read random data for: %s", filename.c_str());
-            return ResponseCode::SYSTEM_ERROR;
-        }
-
-        auto rc = AES_gcm_encrypt(rawBlob->value /* in */, rawBlob->value /* out */, dataLength,
-                                  aes_key, rawBlob->initialization_vector, rawBlob->aead_tag);
-        if (rc != ResponseCode::NO_ERROR) return rc;
-    }
-
-    size_t fileLength = offsetof(blobv3, value) + dataLength + rawBlob->info;
-
-    char tmpFileName[] = ".tmpXXXXXX";
-    {
-        android::base::unique_fd out(TEMP_FAILURE_RETRY(mkstemp(tmpFileName)));
-        if (out < 0) {
-            LOG(ERROR) << "could not open temp file: " << tmpFileName
-                       << " for writing blob file: " << filename.c_str()
-                       << " because: " << strerror(errno);
-            return ResponseCode::SYSTEM_ERROR;
-        }
-
-        const size_t writtenBytes =
-            writeFully(out, reinterpret_cast<uint8_t*>(rawBlob), fileLength);
-
-        if (writtenBytes != fileLength) {
-            LOG(ERROR) << "blob not fully written " << writtenBytes << " != " << fileLength;
-            unlink(tmpFileName);
-            return ResponseCode::SYSTEM_ERROR;
-        }
-    }
-
-    if (rename(tmpFileName, filename.c_str()) == -1) {
-        LOG(ERROR) << "could not rename blob file to " << filename
-                   << " because: " << strerror(errno);
-        unlink(tmpFileName);
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    fsyncDirectory(getContainingDirectory(filename));
-
-    return ResponseCode::NO_ERROR;
-}
-
-ResponseCode LockedKeyBlobEntry::writeBlobs(Blob keyBlob, Blob characteristicsBlob,
-                                            const std::vector<uint8_t>& aes_key,
-                                            State state) const {
-    if (entry_ == nullptr) {
-        return ResponseCode::SYSTEM_ERROR;
-    }
-    ResponseCode rc;
-    if (keyBlob) {
-        blobv3* rawBlob = keyBlob.mBlob.get();
-        rc = writeBlob(entry_->getKeyBlobPath(), std::move(keyBlob), rawBlob, aes_key, state);
-        if (rc != ResponseCode::NO_ERROR) {
-            return rc;
-        }
-    }
-
-    if (characteristicsBlob) {
-        blobv3* rawBlob = characteristicsBlob.mBlob.get();
-        rc = writeBlob(entry_->getCharacteristicsBlobPath(), std::move(characteristicsBlob),
-                       rawBlob, aes_key, state);
-    }
-    return rc;
-}
-
-ResponseCode Blob::readBlob(const std::string& filename, const std::vector<uint8_t>& aes_key,
-                            State state) {
-    ResponseCode rc;
-    ALOGV("reading blob %s", filename.c_str());
-    std::unique_ptr<blobv3> rawBlob = std::make_unique<blobv3>();
-
-    const int in = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY));
-    if (in < 0) {
-        return (errno == ENOENT) ? ResponseCode::KEY_NOT_FOUND : ResponseCode::SYSTEM_ERROR;
-    }
-
-    // fileLength may be less than sizeof(mBlob)
-    const size_t fileLength = readFully(in, (uint8_t*)rawBlob.get(), sizeof(blobv3));
-    if (close(in) != 0) {
-        return ResponseCode::SYSTEM_ERROR;
-    }
-
-    if (fileLength == 0) {
-        LOG(ERROR) << __func__ << " VALUE_CORRUPTED file length == 0";
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-
-    if (rawBlobIsEncrypted(*rawBlob)) {
-        if (state == STATE_LOCKED) {
-            mBlob = std::move(rawBlob);
-            return ResponseCode::LOCKED;
-        }
-        if (state == STATE_UNINITIALIZED) return ResponseCode::UNINITIALIZED;
-    }
-
-    if (fileLength < offsetof(blobv3, value)) {
-        LOG(ERROR) << __func__ << " VALUE_CORRUPTED blob file too short: " << fileLength;
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-
-    if (rawBlob->version == 3) {
-        const ssize_t encryptedLength = ntohl(rawBlob->length);
-
-        if (rawBlobIsEncrypted(*rawBlob)) {
-            rc = AES_gcm_decrypt(rawBlob->value /* in */, rawBlob->value /* out */, encryptedLength,
-                                 aes_key, rawBlob->initialization_vector, rawBlob->aead_tag);
-            if (rc != ResponseCode::NO_ERROR) {
-                // If the blob was superencrypted and decryption failed, it is
-                // almost certain that decryption is failing due to a user's
-                // changed master key.
-                if ((rawBlob->flags & KEYSTORE_FLAG_SUPER_ENCRYPTED) &&
-                    (rc == ResponseCode::VALUE_CORRUPTED)) {
-                    return ResponseCode::KEY_PERMANENTLY_INVALIDATED;
-                }
-                LOG(ERROR) << __func__ << " AES_gcm_decrypt returned: " << uint32_t(rc);
-
-                return rc;
-            }
-        }
-    } else if (rawBlob->version < 3) {
-        blobv2& v2blob = reinterpret_cast<blobv2&>(*rawBlob);
-        const size_t headerLength = offsetof(blobv2, encrypted);
-        const ssize_t encryptedLength = fileLength - headerLength - v2blob.info;
-        if (encryptedLength < 0) {
-            LOG(ERROR) << __func__ << " VALUE_CORRUPTED v2blob file too short";
-            return ResponseCode::VALUE_CORRUPTED;
-        }
-
-        if (rawBlobIsEncrypted(*rawBlob)) {
-            if (encryptedLength % AES_BLOCK_SIZE != 0) {
-                LOG(ERROR) << __func__
-                           << " VALUE_CORRUPTED encrypted length is not a multiple"
-                              " of the AES block size";
-                return ResponseCode::VALUE_CORRUPTED;
-            }
-
-            AES_KEY key;
-            AES_set_decrypt_key(aes_key.data(), kAesKeySize * 8, &key);
-            AES_cbc_encrypt(v2blob.encrypted, v2blob.encrypted, encryptedLength, &key,
-                            v2blob.vector, AES_DECRYPT);
-            key = {};  // clear key
-
-            uint8_t computedDigest[MD5_DIGEST_LENGTH];
-            ssize_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
-            MD5(v2blob.digested, digestedLength, computedDigest);
-            if (memcmp(v2blob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
-                LOG(ERROR) << __func__ << " v2blob MD5 digest mismatch";
-                return ResponseCode::VALUE_CORRUPTED;
-            }
-        }
-    }
-
-    const ssize_t maxValueLength = fileLength - offsetof(blobv3, value) - rawBlob->info;
-    rawBlob->length = ntohl(rawBlob->length);
-    if (rawBlob->length < 0 || rawBlob->length > maxValueLength ||
-        rawBlob->length + rawBlob->info + AES_BLOCK_SIZE >
-            static_cast<ssize_t>(sizeof(rawBlob->value))) {
-        LOG(ERROR) << __func__ << " raw blob length is out of bounds";
-        return ResponseCode::VALUE_CORRUPTED;
-    }
-
-    if (rawBlob->info != 0 && rawBlob->version < 3) {
-        // move info from after padding to after data
-        memmove(rawBlob->value + rawBlob->length, rawBlob->value + maxValueLength, rawBlob->info);
-    }
-
-    mBlob = std::move(rawBlob);
-    return ResponseCode::NO_ERROR;
-}
-
-std::tuple<ResponseCode, Blob, Blob>
-LockedKeyBlobEntry::readBlobs(const std::vector<uint8_t>& aes_key, State state) const {
-    std::tuple<ResponseCode, Blob, Blob> result;
-    auto& [rc, keyBlob, characteristicsBlob] = result;
-    if (entry_ == nullptr) return rc = ResponseCode::SYSTEM_ERROR, result;
-
-    rc = keyBlob.readBlob(entry_->getKeyBlobPath(), aes_key, state);
-    if (rc != ResponseCode::NO_ERROR && rc != ResponseCode::UNINITIALIZED) {
-        return result;
-    }
-
-    if (entry_->hasCharacteristicsBlob()) {
-        characteristicsBlob.readBlob(entry_->getCharacteristicsBlobPath(), aes_key, state);
-    }
-    return result;
-}
-
-ResponseCode LockedKeyBlobEntry::deleteBlobs() const {
-    if (entry_ == nullptr) return ResponseCode::NO_ERROR;
-
-    // always try to delete both
-    ResponseCode rc1 = (unlink(entry_->getKeyBlobPath().c_str()) && errno != ENOENT)
-                           ? ResponseCode::SYSTEM_ERROR
-                           : ResponseCode::NO_ERROR;
-    if (rc1 != ResponseCode::NO_ERROR) {
-        ALOGW("Failed to delete key blob file \"%s\"", entry_->getKeyBlobPath().c_str());
-    }
-    ResponseCode rc2 = (unlink(entry_->getCharacteristicsBlobPath().c_str()) && errno != ENOENT)
-                           ? ResponseCode::SYSTEM_ERROR
-                           : ResponseCode::NO_ERROR;
-    if (rc2 != ResponseCode::NO_ERROR) {
-        ALOGW("Failed to delete key characteristics file \"%s\"",
-              entry_->getCharacteristicsBlobPath().c_str());
-    }
-    // then report the first error that occured
-    if (rc1 != ResponseCode::NO_ERROR) return rc1;
-    return rc2;
-}
-
-keystore::SecurityLevel Blob::getSecurityLevel() const {
-    return keystore::flagsToSecurityLevel(mBlob->flags);
-}
-
-void Blob::setSecurityLevel(keystore::SecurityLevel secLevel) {
-    mBlob->flags &= ~(KEYSTORE_FLAG_FALLBACK | KEYSTORE_FLAG_STRONGBOX);
-    mBlob->flags |= keystore::securityLevelToFlags(secLevel);
-}
-
-std::tuple<bool, keystore::AuthorizationSet, keystore::AuthorizationSet>
-Blob::getKeyCharacteristics() const {
-    std::tuple<bool, keystore::AuthorizationSet, keystore::AuthorizationSet> result;
-    auto& [success, hwEnforced, swEnforced] = result;
-    success = false;
-    ArrayStreamBuffer buf(mBlob->value);
-    std::istream in(&buf);
-
-    // only the characteristics cache has both sets
-    if (getType() == TYPE_KEY_CHARACTERISTICS_CACHE) {
-        hwEnforced.Deserialize(&in);
-    } else if (getType() != TYPE_KEY_CHARACTERISTICS) {
-        // if its not the cache and not the legacy characteristics file we have no business
-        // here
-        return result;
-    }
-    swEnforced.Deserialize(&in);
-    success = !in.bad();
-
-    return result;
-}
-bool Blob::putKeyCharacteristics(const keystore::AuthorizationSet& hwEnforced,
-                                 const keystore::AuthorizationSet& swEnforced) {
-    if (!mBlob) mBlob = std::make_unique<blobv3>();
-    mBlob->version = CURRENT_BLOB_VERSION;
-    ArrayStreamBuffer buf(mBlob->value);
-    std::ostream out(&buf);
-    hwEnforced.Serialize(&out);
-    swEnforced.Serialize(&out);
-    if (out.bad()) return false;
-    setType(TYPE_KEY_CHARACTERISTICS_CACHE);
-    mBlob->length = out.tellp();
-    return true;
-}
-
-void LockedKeyBlobEntry::put(const KeyBlobEntry& entry) {
-    std::unique_lock<std::mutex> lock(locked_blobs_mutex_);
-    locked_blobs_.erase(entry);
-    lock.unlock();
-    locked_blobs_mutex_cond_var_.notify_all();
-}
-
-LockedKeyBlobEntry::~LockedKeyBlobEntry() {
-    if (entry_ != nullptr) put(*entry_);
-}
-
-LockedKeyBlobEntry LockedKeyBlobEntry::get(KeyBlobEntry entry) {
-    std::unique_lock<std::mutex> lock(locked_blobs_mutex_);
-    locked_blobs_mutex_cond_var_.wait(
-        lock, [&] { return locked_blobs_.find(entry) == locked_blobs_.end(); });
-    auto [iterator, success] = locked_blobs_.insert(std::move(entry));
-    if (!success) return {};
-    return LockedKeyBlobEntry(*iterator);
-}
-
-std::set<KeyBlobEntry> LockedKeyBlobEntry::locked_blobs_;
-std::mutex LockedKeyBlobEntry::locked_blobs_mutex_;
-std::condition_variable LockedKeyBlobEntry::locked_blobs_mutex_cond_var_;
-
-/* Here is the encoding of key names. This is necessary in order to allow arbitrary
- * characters in key names. Characters in [0-~] are not encoded. Others are encoded
- * into two bytes. The first byte is one of [+-.] which represents the first
- * two bits of the character. The second byte encodes the rest of the bits into
- * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
- * that Base64 cannot be used here due to the need of prefix match on keys. */
-
-std::string encodeKeyName(const std::string& keyName) {
-    std::string encodedName;
-    encodedName.reserve(keyName.size() * 2);
-    auto in = keyName.begin();
-    while (in != keyName.end()) {
-        // Input character needs to be encoded.
-        if (*in < '0' || *in > '~') {
-            // Encode the two most-significant bits of the input char in the first
-            // output character, by counting up from 43 ('+').
-            encodedName.append(1, '+' + (uint8_t(*in) >> 6));
-            // Encode the six least-significant bits of the input char in the second
-            // output character, by counting up from 48 ('0').
-            // This is safe because the maximum value is 112, which is the
-            // character 'p'.
-            encodedName.append(1, '0' + (*in & 0x3F));
-        } else {
-            // No need to encode input char - append as-is.
-            encodedName.append(1, *in);
-        }
-        ++in;
-    }
-    return encodedName;
-}
-
-std::string decodeKeyName(const std::string& encodedName) {
-    std::string decodedName;
-    decodedName.reserve(encodedName.size());
-    auto in = encodedName.begin();
-    bool multichar = false;
-    char c;
-    while (in != encodedName.end()) {
-        if (multichar) {
-            // Second part of a multi-character encoding. Turn off the multichar
-            // flag and set the six least-significant bits of c to the value originally
-            // encoded by counting up from '0'.
-            multichar = false;
-            decodedName.append(1, c | (uint8_t(*in) - '0'));
-        } else if (*in >= '+' && *in <= '.') {
-            // First part of a multi-character encoding. Set the multichar flag
-            // and set the two most-significant bits of c to be the two bits originally
-            // encoded by counting up from '+'.
-            multichar = true;
-            c = (*in - '+') << 6;
-        } else {
-            // Regular character, append as-is.
-            decodedName.append(1, *in);
-        }
-        ++in;
-    }
-    // mulitchars at the end get truncated
-    return decodedName;
-}
-
-std::string KeyBlobEntry::getKeyBlobBaseName() const {
-    std::stringstream s;
-    if (masterkey_) {
-        s << alias_;
-    } else {
-        s << uid_ << "_" << encodeKeyName(alias_);
-    }
-    return s.str();
-}
-
-std::string KeyBlobEntry::getKeyBlobPath() const {
-    std::stringstream s;
-    if (masterkey_) {
-        s << user_dir_ << "/" << alias_;
-    } else {
-        s << user_dir_ << "/" << uid_ << "_" << encodeKeyName(alias_);
-    }
-    return s.str();
-}
-
-std::string KeyBlobEntry::getCharacteristicsBlobBaseName() const {
-    std::stringstream s;
-    if (!masterkey_) s << "." << uid_ << "_chr_" << encodeKeyName(alias_);
-    return s.str();
-}
-
-std::string KeyBlobEntry::getCharacteristicsBlobPath() const {
-    std::stringstream s;
-    if (!masterkey_)
-        s << user_dir_ << "/"
-          << "." << uid_ << "_chr_" << encodeKeyName(alias_);
-    return s.str();
-}
-
-bool KeyBlobEntry::hasKeyBlob() const {
-    int trys = 3;
-    while (trys--) {
-        if (!access(getKeyBlobPath().c_str(), R_OK | W_OK)) return true;
-        if (errno == ENOENT) return false;
-        LOG(WARNING) << "access encountered " << strerror(errno) << " (" << errno << ")"
-                     << " while checking for key blob";
-        if (errno != EAGAIN) break;
-    }
-    return false;
-}
-
-bool KeyBlobEntry::hasCharacteristicsBlob() const {
-    int trys = 3;
-    while (trys--) {
-        if (!access(getCharacteristicsBlobPath().c_str(), R_OK | W_OK)) return true;
-        if (errno == ENOENT) return false;
-        LOG(WARNING) << "access encountered " << strerror(errno) << " (" << errno << ")"
-                     << " while checking for key characteristics blob";
-        if (errno != EAGAIN) break;
-    }
-    return false;
-}
-
-static std::tuple<bool, uid_t, std::string> filename2UidAlias(const std::string& filepath) {
-    std::tuple<bool, uid_t, std::string> result;
-
-    auto& [success, uid, alias] = result;
-
-    success = false;
-
-    auto filenamebase = filepath.find_last_of('/');
-    std::string filename =
-        filenamebase == std::string::npos ? filepath : filepath.substr(filenamebase + 1);
-
-    if (filename[0] == '.') return result;
-
-    auto sep = filename.find('_');
-    if (sep == std::string::npos) return result;
-
-    std::stringstream s(filename.substr(0, sep));
-    s >> uid;
-    if (!s) return result;
-
-    alias = decodeKeyName(filename.substr(sep + 1));
-    success = true;
-    return result;
-}
-
-std::tuple<ResponseCode, std::list<LockedKeyBlobEntry>>
-LockedKeyBlobEntry::list(const std::string& user_dir,
-                         std::function<bool(uid_t, const std::string&)> filter) {
-    std::list<LockedKeyBlobEntry> matches;
-
-    // This is a fence against any concurrent database accesses during database iteration.
-    // Only the keystore thread can lock entries. So it cannot be starved
-    // by workers grabbing new individual locks. We just wait here until all
-    // workers have relinquished their locked files.
-    std::unique_lock<std::mutex> lock(locked_blobs_mutex_);
-    locked_blobs_mutex_cond_var_.wait(lock, [&] { return locked_blobs_.empty(); });
-
-    DIR* dir = opendir(user_dir.c_str());
-    if (!dir) {
-        ALOGW("can't open directory for user: %s", strerror(errno));
-        return std::tuple<ResponseCode, std::list<LockedKeyBlobEntry>&&>{ResponseCode::SYSTEM_ERROR,
-                                                                         std::move(matches)};
-    }
-
-    struct dirent* file;
-    while ((file = readdir(dir)) != nullptr) {
-        // We only care about files.
-        if (file->d_type != DT_REG) {
-            continue;
-        }
-
-        // Skip anything that starts with a "."
-        if (file->d_name[0] == '.') {
-            continue;
-        }
-
-        auto [success, uid, alias] = filename2UidAlias(file->d_name);
-
-        if (!success) {
-            ALOGW("could not parse key filename \"%s\"", file->d_name);
-            continue;
-        }
-
-        if (!filter(uid, alias)) continue;
-
-        auto [iterator, dummy] = locked_blobs_.emplace(alias, user_dir, uid);
-        matches.push_back(*iterator);
-    }
-    closedir(dir);
-    return std::tuple<ResponseCode, std::list<LockedKeyBlobEntry>&&>{ResponseCode::NO_ERROR,
-                                                                     std::move(matches)};
-}
diff --git a/keystore/blob.h b/keystore/blob.h
deleted file mode 100644
index e0bd146..0000000
--- a/keystore/blob.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2015 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_BLOB_H_
-#define KEYSTORE_BLOB_H_
-
-#include <stdint.h>
-
-#include <openssl/aes.h>
-#include <openssl/md5.h>
-
-#include <condition_variable>
-#include <functional>
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore.h>
-#include <list>
-#include <mutex>
-#include <set>
-#include <sstream>
-#include <vector>
-
-constexpr size_t kValueSize = 32768;
-constexpr size_t kAesKeySize = 128 / 8;
-constexpr size_t kGcmTagLength = 128 / 8;
-constexpr size_t kGcmIvLength = 96 / 8;
-constexpr size_t kAes128KeySizeBytes = 128 / 8;
-constexpr size_t kAes256KeySizeBytes = 256 / 8;
-
-/* Here is the file format. There are two parts in blob.value, the secret and
- * the description. The secret is stored in ciphertext, and its original size
- * can be found in blob.length. The description is stored after the secret in
- * plaintext, and its size is specified in blob.info. The total size of the two
- * parts must be no more than kValueSize bytes. The first field is the version,
- * the second is the blob's type, and the third byte is flags. Fields other
- * than blob.info, blob.length, and blob.value are modified by encryptBlob()
- * and decryptBlob(). Thus they should not be accessed from outside. */
-
-struct __attribute__((packed)) blobv3 {
-    uint8_t version;
-    uint8_t type;
-    uint8_t flags;
-    uint8_t info;
-    uint8_t initialization_vector[AES_BLOCK_SIZE];  // Only 96 bits is used, rest is zeroed.
-    uint8_t aead_tag[kGcmTagLength];
-    int32_t length;  // in network byte order, only for backward compatibility
-    uint8_t value[kValueSize + AES_BLOCK_SIZE];
-};
-
-struct __attribute__((packed)) blobv2 {
-    uint8_t version;
-    uint8_t type;
-    uint8_t flags;
-    uint8_t info;
-    uint8_t vector[AES_BLOCK_SIZE];
-    uint8_t encrypted[0];  // Marks offset to encrypted data.
-    uint8_t digest[MD5_DIGEST_LENGTH];
-    uint8_t digested[0];  // Marks offset to digested data.
-    int32_t length;       // in network byte order
-    uint8_t value[kValueSize + AES_BLOCK_SIZE];
-};
-
-static_assert(sizeof(blobv3) == sizeof(blobv2) &&
-                  offsetof(blobv3, initialization_vector) == offsetof(blobv2, vector) &&
-                  offsetof(blobv3, aead_tag) == offsetof(blobv2, digest) &&
-                  offsetof(blobv3, aead_tag) == offsetof(blobv2, encrypted) &&
-                  offsetof(blobv3, length) == offsetof(blobv2, length) &&
-                  offsetof(blobv3, value) == offsetof(blobv2, value),
-              "Oops.  Blob layout changed.");
-
-static const uint8_t CURRENT_BLOB_VERSION = 3;
-
-typedef enum {
-    TYPE_ANY = 0,  // meta type that matches anything
-    TYPE_GENERIC = 1,
-    TYPE_MASTER_KEY = 2,
-    TYPE_KEY_PAIR = 3,
-    TYPE_KEYMASTER_10 = 4,
-    TYPE_KEY_CHARACTERISTICS = 5,
-    TYPE_KEY_CHARACTERISTICS_CACHE = 6,
-    TYPE_MASTER_KEY_AES256 = 7,
-} BlobType;
-
-class LockedKeyBlobEntry;
-
-/**
- * The Blob represents the content of a KeyBlobEntry.
- *
- * BEWARE: It is only save to call any member function of a Blob b if bool(b) yields true.
- *         Exceptions are putKeyCharacteristics(), the assignment operators and operator bool.
- */
-class Blob {
-    friend LockedKeyBlobEntry;
-
-  public:
-    Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
-         BlobType type);
-    explicit Blob(blobv3 b);
-    Blob();
-    Blob(const Blob& rhs);
-    Blob(Blob&& rhs);
-
-    ~Blob() {
-        if (mBlob) *mBlob = {};
-    }
-
-    Blob& operator=(const Blob& rhs);
-    Blob& operator=(Blob&& rhs);
-    explicit operator bool() const { return bool(mBlob); }
-
-    const uint8_t* getValue() const { return mBlob->value; }
-
-    int32_t getLength() const { return mBlob->length; }
-
-    const uint8_t* getInfo() const { return mBlob->value + mBlob->length; }
-    uint8_t getInfoLength() const { return mBlob->info; }
-
-    uint8_t getVersion() const { return mBlob->version; }
-
-    bool isEncrypted() const;
-    void setEncrypted(bool encrypted);
-
-    bool isSuperEncrypted() const;
-    void setSuperEncrypted(bool superEncrypted);
-
-    bool isCriticalToDeviceEncryption() const;
-    void setCriticalToDeviceEncryption(bool critical);
-
-    bool isFallback() const { return mBlob->flags & KEYSTORE_FLAG_FALLBACK; }
-    void setFallback(bool fallback);
-
-    void setVersion(uint8_t version) { mBlob->version = version; }
-    BlobType getType() const { return BlobType(mBlob->type); }
-    void setType(BlobType type) { mBlob->type = uint8_t(type); }
-
-    keystore::SecurityLevel getSecurityLevel() const;
-    void setSecurityLevel(keystore::SecurityLevel);
-
-    std::tuple<bool, keystore::AuthorizationSet, keystore::AuthorizationSet>
-    getKeyCharacteristics() const;
-
-    bool putKeyCharacteristics(const keystore::AuthorizationSet& hwEnforced,
-                               const keystore::AuthorizationSet& swEnforced);
-
-  private:
-    std::unique_ptr<blobv3> mBlob;
-
-    ResponseCode readBlob(const std::string& filename, const std::vector<uint8_t>& aes_key,
-                          State state);
-};
-
-/**
- * A KeyBlobEntry represents a full qualified key blob as known by Keystore. The key blob
- * is given by the uid of the owning app and the alias used by the app to refer to this key.
- * The user_dir_ is technically implied by the uid, but computation of the user directory is
- * done in the user state database. Which is why we also cache it here.
- *
- * The KeyBlobEntry knows the location of the key blob files (which may include a characteristics
- * cache file) but does not allow read or write access to the content. It also does not imply
- * the existence of the files.
- *
- * KeyBlobEntry abstracts, to some extent, from the the file system based storage of key blobs.
- * An evolution of KeyBlobEntry may be used for key blob storage based on a back end other than
- * file system, e.g., SQL database or other.
- *
- * For access to the key blob content the programmer has to acquire a LockedKeyBlobEntry (see
- * below).
- */
-class KeyBlobEntry {
-  private:
-    std::string alias_;
-    std::string user_dir_;
-    uid_t uid_;
-    bool masterkey_;
-
-  public:
-    KeyBlobEntry(std::string alias, std::string user_dir, uid_t uid, bool masterkey = false)
-        : alias_(std::move(alias)), user_dir_(std::move(user_dir)), uid_(uid),
-          masterkey_(masterkey) {}
-
-    std::string getKeyBlobBaseName() const;
-    std::string getKeyBlobPath() const;
-
-    std::string getCharacteristicsBlobBaseName() const;
-    std::string getCharacteristicsBlobPath() const;
-
-    bool hasKeyBlob() const;
-    bool hasCharacteristicsBlob() const;
-
-    bool operator<(const KeyBlobEntry& rhs) const {
-        return std::tie(uid_, alias_, user_dir_) < std::tie(rhs.uid_, rhs.alias_, rhs.user_dir_);
-    }
-    bool operator==(const KeyBlobEntry& rhs) const {
-        return std::tie(uid_, alias_, user_dir_) == std::tie(rhs.uid_, rhs.alias_, rhs.user_dir_);
-    }
-    bool operator!=(const KeyBlobEntry& rhs) const { return !(*this == rhs); }
-
-    inline const std::string& alias() const { return alias_; }
-    inline const std::string& user_dir() const { return user_dir_; }
-    inline uid_t uid() const { return uid_; }
-};
-
-/**
- * The LockedKeyBlobEntry is a proxy object to KeyBlobEntry that expresses exclusive ownership
- * of a KeyBlobEntry. LockedKeyBlobEntries can be acquired by calling
- * LockedKeyBlobEntry::get() or LockedKeyBlobEntry::list().
- *
- * LockedKeyBlobEntries are movable but not copyable. By convention they can only
- * be taken by the dispatcher thread of keystore, but not by any keymaster worker thread.
- * The dispatcher thread may transfer ownership of a locked entry to a keymaster worker thread.
- *
- * Locked entries are tracked on the stack or as members of movable functor objects passed to the
- * keymaster worker request queues. Locks are relinquished as the locked entry gets destroyed, e.g.,
- * when it goes out of scope or when the owning request functor gets destroyed.
- *
- * LockedKeyBlobEntry::list(), which must only be called by the dispatcher, blocks until all
- * LockedKeyBlobEntries have been destroyed. Thereby list acts as a fence to make sure it gets a
- * consistent view of the key blob database. Under the assumption that keymaster worker requests
- * cannot run or block indefinitely and cannot grab new locked entries, progress is guaranteed.
- * It then grabs locked entries in accordance with the given filter rule.
- *
- * LockedKeyBlobEntry allow access to the proxied KeyBlobEntry interface through the operator->.
- * They add additional functionality to access and modify the key blob's content on disk.
- * LockedKeyBlobEntry ensures atomic operations on the persistently stored key blobs on a per
- * entry granularity.
- */
-class LockedKeyBlobEntry {
-  private:
-    static std::set<KeyBlobEntry> locked_blobs_;
-    static std::mutex locked_blobs_mutex_;
-    static std::condition_variable locked_blobs_mutex_cond_var_;
-
-    const KeyBlobEntry* entry_;
-    // NOLINTNEXTLINE(google-explicit-constructor)
-    LockedKeyBlobEntry(const KeyBlobEntry& entry) : entry_(&entry) {}
-
-    static void put(const KeyBlobEntry& entry);
-    LockedKeyBlobEntry(const LockedKeyBlobEntry&) = delete;
-    LockedKeyBlobEntry& operator=(const LockedKeyBlobEntry&) = delete;
-
-  public:
-    LockedKeyBlobEntry() : entry_(nullptr){};
-    ~LockedKeyBlobEntry();
-    LockedKeyBlobEntry(LockedKeyBlobEntry&& rhs) : entry_(rhs.entry_) { rhs.entry_ = nullptr; }
-    LockedKeyBlobEntry& operator=(LockedKeyBlobEntry&& rhs) {
-        // as dummy goes out of scope it relinquishes the lock on this
-        LockedKeyBlobEntry dummy(std::move(*this));
-        entry_ = rhs.entry_;
-        rhs.entry_ = nullptr;
-        return *this;
-    }
-    static LockedKeyBlobEntry get(KeyBlobEntry entry);
-    static std::tuple<ResponseCode, std::list<LockedKeyBlobEntry>>
-    list(const std::string& user_dir,
-         std::function<bool(uid_t, const std::string&)> filter =
-             [](uid_t, const std::string&) -> bool { return true; });
-
-    ResponseCode writeBlobs(Blob keyBlob, Blob characteristicsBlob,
-                            const std::vector<uint8_t>& aes_key, State state) const;
-    std::tuple<ResponseCode, Blob, Blob> readBlobs(const std::vector<uint8_t>& aes_key,
-                                                   State state) const;
-    ResponseCode deleteBlobs() const;
-
-    inline explicit operator bool() const { return entry_ != nullptr; }
-    inline const KeyBlobEntry& operator*() const { return *entry_; }
-    inline const KeyBlobEntry* operator->() const { return entry_; }
-};
-
-// Visible for testing
-std::string encodeKeyName(const std::string& keyName);
-std::string decodeKeyName(const std::string& encodedName);
-
-#endif  // KEYSTORE_BLOB_H_
diff --git a/keystore/confirmation_manager.cpp b/keystore/confirmation_manager.cpp
deleted file mode 100644
index 76df1cc..0000000
--- a/keystore/confirmation_manager.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#define LOG_TAG "ConfirmationManager"
-
-#include "confirmation_manager.h"
-
-#include <android/hardware/confirmationui/1.0/IConfirmationResultCallback.h>
-#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <android/security/BpConfirmationPromptCallback.h>
-#include <binder/BpBinder.h>
-#include <binder/IPCThreadState.h>
-#include <binder/Parcel.h>
-
-#include "keystore_aidl_hidl_marshalling_utils.h"
-
-namespace keystore {
-
-using android::IBinder;
-using android::sp;
-using android::String16;
-using android::String8;
-using android::wp;
-using android::binder::Status;
-using android::hardware::hidl_vec;
-using android::hardware::Return;
-using android::hardware::confirmationui::V1_0::IConfirmationResultCallback;
-using android::hardware::confirmationui::V1_0::IConfirmationUI;
-using android::hardware::confirmationui::V1_0::UIOption;
-
-using android::security::BpConfirmationPromptCallback;
-using std::lock_guard;
-using std::mutex;
-using std::vector;
-
-ConfirmationManager::ConfirmationManager(IBinder::DeathRecipient* deathRecipient)
-    : IConfirmationResultCallback(), mDeathRecipient(deathRecipient) {}
-
-// Called by keystore main thread.
-Status ConfirmationManager::presentConfirmationPrompt(const sp<IBinder>& listener,
-                                                      const String16& promptText,
-                                                      const hidl_vec<uint8_t>& extraData,
-                                                      const String16& locale, int uiOptionsAsFlags,
-                                                      int32_t* aidl_return) {
-    lock_guard<mutex> lock(mMutex);
-
-    if (mCurrentListener != nullptr) {
-        *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::OperationPending);
-        return Status::ok();
-    }
-
-    sp<IConfirmationUI> confirmationUI = IConfirmationUI::tryGetService();
-    if (confirmationUI == nullptr) {
-        ALOGW("Error getting confirmationUI service\n");
-        *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::Unimplemented);
-        return Status::ok();
-    }
-
-    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
-    if (!mRateLimiting.tryPrompt(callingUid)) {
-        *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::SystemError);
-        return Status::ok();
-    }
-
-    String8 promptText8(promptText);
-    String8 locale8(locale);
-    vector<UIOption> uiOptionsVector;
-    for (int n = 0; n < 32; n++) {
-        if (uiOptionsAsFlags & (1 << n)) {
-            uiOptionsVector.push_back(UIOption(n));
-        }
-    }
-    ConfirmationResponseCode responseCode;
-    responseCode = confirmationUI->promptUserConfirmation(sp<IConfirmationResultCallback>(this),
-                                                          promptText8.string(), extraData,
-                                                          locale8.string(), uiOptionsVector);
-    if (responseCode != ConfirmationResponseCode::OK) {
-        ALOGW("Unexpecxted responseCode %d from promptUserConfirmation\n", responseCode);
-        *aidl_return = static_cast<int32_t>(responseCode);
-        return Status::ok();
-    }
-
-    listener->linkToDeath(mDeathRecipient);
-    confirmationUI->linkToDeath(this, 0);
-    mCurrentListener = listener;
-    mCurrentConfirmationUI = confirmationUI;
-
-    *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::OK);
-    return Status::ok();
-}
-
-// Called by keystore main thread.
-Status ConfirmationManager::cancelConfirmationPrompt(const sp<IBinder>& listener,
-                                                     int32_t* aidl_return) {
-    mMutex.lock();
-    if (mCurrentListener != listener) {
-        // If the prompt was displayed by another application, return
-        // OperationPending.
-        mMutex.unlock();
-        *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::OperationPending);
-        return Status::ok();
-    }
-    mMutex.unlock();
-
-    cancelPrompt();
-
-    *aidl_return = static_cast<int32_t>(ConfirmationResponseCode::OK);
-    return Status::ok();
-}
-
-void ConfirmationManager::cancelPrompt() {
-    mMutex.lock();
-    mRateLimiting.cancelPrompt();
-    sp<IConfirmationUI> confirmationUI = mCurrentConfirmationUI;
-    mMutex.unlock();
-    if (confirmationUI != nullptr) {
-        confirmationUI->abort();
-    }
-}
-
-// Called by keystore main thread.
-Status ConfirmationManager::isConfirmationPromptSupported(bool* aidl_return) {
-    sp<IConfirmationUI> confirmationUI = IConfirmationUI::tryGetService();
-    if (confirmationUI == nullptr) {
-        ALOGW("Error getting confirmationUI service\n");
-        *aidl_return = false;
-        return Status::ok();
-    }
-
-    *aidl_return = true;
-    return Status::ok();
-}
-
-void ConfirmationManager::finalizeTransaction(ConfirmationResponseCode responseCode,
-                                              hidl_vec<uint8_t> dataThatWasConfirmed) {
-    mMutex.lock();
-    mRateLimiting.processResult(responseCode);
-    sp<IBinder> listener = mCurrentListener;
-    if (mCurrentListener != nullptr) {
-        mCurrentListener->unlinkToDeath(mDeathRecipient);
-        mCurrentListener = nullptr;
-    }
-    if (mCurrentConfirmationUI != nullptr) {
-        mCurrentConfirmationUI->unlinkToDeath(this);
-        mCurrentConfirmationUI = nullptr;
-    }
-    mMutex.unlock();
-
-    // Deliver result to the application that started the operation.
-    if (listener != nullptr) {
-        sp<BpConfirmationPromptCallback> obj = new BpConfirmationPromptCallback(listener);
-        Status status = obj->onConfirmationPromptCompleted(static_cast<int32_t>(responseCode),
-                                                           dataThatWasConfirmed);
-        if (!status.isOk()) {
-            ALOGW("Error sending onConfirmationPromptCompleted - status: %s\n",
-                  status.toString8().c_str());
-        }
-    }
-}
-
-// Called by hwbinder thread (not keystore main thread).
-Return<void> ConfirmationManager::result(ConfirmationResponseCode responseCode,
-                                         const hidl_vec<uint8_t>& dataThatWasConfirmed,
-                                         const hidl_vec<uint8_t>& confirmationToken) {
-    finalizeTransaction(responseCode, dataThatWasConfirmed);
-    lock_guard<mutex> lock(mMutex);
-    mLatestConfirmationToken = confirmationToken;
-    return Return<void>();
-}
-
-// Called by keystore main thread or keymaster worker
-hidl_vec<uint8_t> ConfirmationManager::getLatestConfirmationToken() {
-    lock_guard<mutex> lock(mMutex);
-    return mLatestConfirmationToken;
-}
-
-void ConfirmationManager::binderDied(const wp<IBinder>& who) {
-    // This is also called for other binders so need to check it's for
-    // us before acting on it.
-    mMutex.lock();
-    if (who == mCurrentListener) {
-        // Clear this so we don't call back into the already dead
-        // binder in finalizeTransaction().
-        mCurrentListener->unlinkToDeath(mDeathRecipient);
-        mCurrentListener = nullptr;
-        mMutex.unlock();
-        ALOGW("The process which requested the confirmation dialog died.\n");
-        cancelPrompt();
-    } else {
-        mMutex.unlock();
-    }
-}
-
-void ConfirmationManager::serviceDied(uint64_t /* cookie */,
-                                      const wp<android::hidl::base::V1_0::IBase>& /* who */) {
-    ALOGW("The ConfirmationUI HAL died.\n");
-    finalizeTransaction(ConfirmationResponseCode::SystemError, {});
-}
-
-}  // namespace keystore
diff --git a/keystore/confirmation_manager.h b/keystore/confirmation_manager.h
deleted file mode 100644
index 7f0a11d..0000000
--- a/keystore/confirmation_manager.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2017 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_CONFIRMATION_MANAGER_H_
-#define KEYSTORE_CONFIRMATION_MANAGER_H_
-
-#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <binder/Status.h>
-#include <keystore/keymaster_types.h>
-#include <map>
-#include <mutex>
-#include <utils/LruCache.h>
-#include <utils/StrongPointer.h>
-#include <vector>
-
-#include "confirmationui_rate_limiting.h"
-
-namespace keystore {
-
-using android::binder::Status;
-using android::hardware::confirmationui::V1_0::IConfirmationResultCallback;
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
-
-class ConfirmationManager;
-
-class ConfirmationManager : public android::hardware::hidl_death_recipient,
-                            public IConfirmationResultCallback {
-  public:
-    explicit ConfirmationManager(android::IBinder::DeathRecipient* deathRecipient);
-
-    // Calls into the confirmationui HAL to start a new prompt.
-    //
-    // Returns OperationPending if another application is already
-    // showing a confirmation. Otherwise returns the return code from
-    // the HAL.
-    Status presentConfirmationPrompt(const android::sp<android::IBinder>& listener,
-                                     const android::String16& promptText,
-                                     const hidl_vec<uint8_t>& extraData,
-                                     const android::String16& locale, int uiOptionsAsFlags,
-                                     int32_t* aidl_return);
-
-    // Calls into the confirmationui HAL to cancel displaying a
-    // prompt.
-    //
-    // Returns OperatingPending if another application is showing a
-    // confirmation. Otherwise returns the return code from the HAL.
-    Status cancelConfirmationPrompt(const android::sp<android::IBinder>& listener,
-                                    int32_t* aidl_return);
-
-    // Checks if the confirmationUI HAL is available.
-    Status isConfirmationPromptSupported(bool* aidl_return);
-
-    // Gets the latest confirmation token received from the ConfirmationUI HAL.
-    hidl_vec<uint8_t> getLatestConfirmationToken();
-
-    // Called by KeyStoreService when a client binder has died.
-    void binderDied(const android::wp<android::IBinder>& who);
-
-    // hidl_death_recipient overrides:
-    virtual void serviceDied(uint64_t cookie,
-                             const android::wp<android::hidl::base::V1_0::IBase>& who) override;
-
-    // IConfirmationResultCallback overrides:
-    android::hardware::Return<void> result(ConfirmationResponseCode responseCode,
-                                           const hidl_vec<uint8_t>& dataThatWasConfirmed,
-                                           const hidl_vec<uint8_t>& confirmationToken) override;
-
-  private:
-    friend class ConfirmationResultCallback;
-
-    // Set rate limiting to not decrement on next abort and aborts
-    // confirmationui.
-    void cancelPrompt();
-
-    void finalizeTransaction(ConfirmationResponseCode responseCode,
-                             hidl_vec<uint8_t> dataThatWasConfirmed);
-
-    // This mutex protects all data below it.
-    std::mutex mMutex;
-
-    // The mCurrentListener and mCurrentConfirmationUI fields are set
-    // if and only if a prompt is currently showing.
-    android::sp<android::IBinder> mCurrentListener;
-    android::sp<android::hardware::confirmationui::V1_0::IConfirmationUI> mCurrentConfirmationUI;
-    android::IBinder::DeathRecipient* mDeathRecipient;
-    hidl_vec<uint8_t> mLatestConfirmationToken;
-    RateLimiting<> mRateLimiting;
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_CONFIRMATION_MANAGER_H_
diff --git a/keystore/confirmationui_rate_limiting.h b/keystore/confirmationui_rate_limiting.h
deleted file mode 100644
index 658bf41..0000000
--- a/keystore/confirmationui_rate_limiting.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-**
-** Copyright 2018, 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_CONFIRMATIONUI_RATE_LIMITING_H_
-#define KEYSTORE_CONFIRMATIONUI_RATE_LIMITING_H_
-
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <chrono>
-#include <stdint.h>
-#include <sys/types.h>
-#include <tuple>
-#include <unordered_map>
-
-namespace keystore {
-
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
-
-using std::chrono::duration;
-using std::chrono::time_point;
-
-template <typename Clock = std::chrono::steady_clock> class RateLimiting {
-  private:
-    struct Slot {
-        Slot() : previous_start{}, prompt_start{}, counter(0) {}
-        typename Clock::time_point previous_start;
-        typename Clock::time_point prompt_start;
-        uint32_t counter;
-    };
-
-    std::unordered_map<uid_t, Slot> slots_;
-
-    uint_t latest_requester_;
-
-    static std::chrono::seconds getBackoff(uint32_t counter) {
-        using namespace std::chrono_literals;
-        switch (counter) {
-        case 0:
-        case 1:
-        case 2:
-            return 0s;
-        case 3:
-        case 4:
-        case 5:
-            return 30s;
-        default:
-            return 60s * (1ULL << (counter - 6));
-        }
-    }
-
-  public:
-    // Exposes the number of used slots. This is only used by the test to verify the assumption
-    // about used counter slots.
-    size_t usedSlots() const { return slots_.size(); }
-    void doGC() {
-        using namespace std::chrono_literals;
-        using std::chrono::system_clock;
-        using std::chrono::time_point_cast;
-        auto then = Clock::now() - 24h;
-        auto iter = slots_.begin();
-        while (iter != slots_.end()) {
-            if (iter->second.prompt_start <= then) {
-                iter = slots_.erase(iter);
-            } else {
-                ++iter;
-            }
-        }
-    }
-
-    bool tryPrompt(uid_t id) {
-        using namespace std::chrono_literals;
-        // remove slots that have not been touched in 24 hours
-        doGC();
-        auto& slot = slots_[id];
-        auto now = Clock::now();
-        if (!slot.counter || slot.prompt_start <= now - getBackoff(slot.counter)) {
-            latest_requester_ = id;
-            slot.counter += 1;
-            slot.previous_start = slot.prompt_start;
-            slot.prompt_start = now;
-            return true;
-        }
-        return false;
-    }
-
-    // The app is penalized for cancelling a request. Request are rolled back only if
-    // the prompt was cancelled by the system: e.g. a system error or asynchronous event.
-    // When the user cancels the prompt, it is subject to rate limiting.
-    static constexpr const uint_t kInvalidRequester = -1;
-
-    void cancelPrompt() { latest_requester_ = kInvalidRequester; }
-
-    void processResult(ConfirmationResponseCode rc) {
-        if (latest_requester_ == kInvalidRequester) {
-            return;
-        }
-        switch (rc) {
-        case ConfirmationResponseCode::OK:
-            // reset the counter slot
-            slots_.erase(latest_requester_);
-            return;
-        case ConfirmationResponseCode::Canceled:
-            // nothing to do here
-            return;
-        default:;
-        }
-
-        // roll back latest request
-        auto& slot = slots_[latest_requester_];
-        if (slot.counter <= 1) {
-            slots_.erase(latest_requester_);
-            return;
-        }
-        slot.counter -= 1;
-        slot.prompt_start = slot.previous_start;
-    }
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_CONFIRMATIONUI_RATE_LIMITING_H_
diff --git a/keystore/defaults.h b/keystore/defaults.h
deleted file mode 100644
index 6f7ff2d..0000000
--- a/keystore/defaults.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013 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_DEFAULTS_H_
-#define KEYSTORE_DEFAULTS_H_
-
-/*
- * These must be kept in sync with
- * frameworks/base/keystore/java/android/security/KeyPairGeneratorSpec.java
- */
-
-/* DSA */
-constexpr int32_t DSA_DEFAULT_KEY_SIZE = 1024;
-constexpr int32_t DSA_MIN_KEY_SIZE = 512;
-constexpr int32_t DSA_MAX_KEY_SIZE = 8192;
-
-/* EC */
-constexpr int32_t EC_DEFAULT_KEY_SIZE = 256;
-constexpr int32_t EC_MIN_KEY_SIZE = 192;
-constexpr int32_t EC_MAX_KEY_SIZE = 521;
-
-/* RSA */
-constexpr int32_t RSA_DEFAULT_KEY_SIZE = 2048;
-constexpr int32_t RSA_DEFAULT_EXPONENT = 0x10001;
-constexpr int32_t RSA_MIN_KEY_SIZE = 512;
-constexpr int32_t RSA_MAX_KEY_SIZE = 8192;
-
-#endif /* KEYSTORE_DEFAULTS_H_ */
diff --git a/keystore/grant_store.cpp b/keystore/grant_store.cpp
deleted file mode 100644
index 9e627ce..0000000
--- a/keystore/grant_store.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2017 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 "grant_store.h"
-
-#include "blob.h"
-#include <algorithm>
-#include <sstream>
-
-namespace keystore {
-
-static constexpr uint64_t kInvalidGrantNo = std::numeric_limits<uint64_t>::max();
-static const char* kKeystoreGrantInfix = "_KEYSTOREGRANT_";
-static constexpr size_t kKeystoreGrantInfixLength = 15;
-
-Grant::Grant(const KeyBlobEntry& entry, const uint64_t grant_no)
-    : entry_(entry), grant_no_(grant_no) {}
-
-static std::pair<uint64_t, std::string> parseGrantAlias(const std::string& grantAlias) {
-    auto pos = grantAlias.rfind(kKeystoreGrantInfix);
-    if (pos == std::string::npos) return {kInvalidGrantNo, ""};
-    std::stringstream s(grantAlias.substr(pos + kKeystoreGrantInfixLength));
-    std::string wrapped_alias = grantAlias.substr(0, pos);
-    uint64_t grant_no = kInvalidGrantNo;
-    s >> grant_no;
-    if (s.fail() || grant_no == kInvalidGrantNo) return {kInvalidGrantNo, ""};
-    return {grant_no, wrapped_alias};
-}
-
-std::string GrantStore::put(const uid_t uid, const LockedKeyBlobEntry& lockedEntry) {
-    std::unique_lock<std::shared_mutex> lock(mutex_);
-    std::stringstream s;
-    KeyBlobEntry blobEntry = *lockedEntry;
-    s << blobEntry.alias() << kKeystoreGrantInfix;
-
-    std::set<Grant, std::less<>>& uid_grant_list = grants_[uid];
-
-    bool success = false;
-    auto iterator =
-        std::find_if(uid_grant_list.begin(), uid_grant_list.end(),
-                     [&](const Grant& entry) { return success = entry.entry_ == blobEntry; });
-    while (!success) {
-        std::tie(iterator, success) = uid_grant_list.emplace(blobEntry, std::rand());
-    }
-    s << iterator->grant_no_;
-    return s.str();
-}
-
-ReadLockedGrant GrantStore::get(const uid_t uid, const std::string& alias) const {
-    std::shared_lock<std::shared_mutex> lock(mutex_);
-    uint64_t grant_no;
-    std::string wrappedAlias;
-    std::tie(grant_no, wrappedAlias) = parseGrantAlias(alias);
-    if (grant_no == kInvalidGrantNo) return {};
-    auto uid_set_iter = grants_.find(uid);
-    if (uid_set_iter == grants_.end()) return {};
-    auto& uid_grant_list = uid_set_iter->second;
-    auto grant = uid_grant_list.find(grant_no);
-    if (grant == uid_grant_list.end()) return {};
-    if (grant->entry_.alias() != wrappedAlias) return {};
-    return {&(*grant), std::move(lock)};
-}
-
-bool GrantStore::removeByFileAlias(const uid_t granteeUid, const LockedKeyBlobEntry& lockedEntry) {
-    std::unique_lock<std::shared_mutex> lock(mutex_);
-    auto& uid_grant_list = grants_[granteeUid];
-    for (auto i = uid_grant_list.begin(); i != uid_grant_list.end(); ++i) {
-        if (i->entry_ == *lockedEntry) {
-            uid_grant_list.erase(i);
-            return true;
-        }
-    }
-    return false;
-}
-
-void GrantStore::removeAllGrantsToKey(const uid_t granterUid, const std::string& alias) {
-    std::unique_lock<std::shared_mutex> lock(mutex_);
-    for (auto& uid_grant_list : grants_) {
-        for (auto i = uid_grant_list.second.begin(); i != uid_grant_list.second.end(); ++i) {
-            if (i->entry_.alias() == alias && i->entry_.uid() == granterUid) {
-                uid_grant_list.second.erase(i);
-                break;
-            }
-        }
-    }
-}
-
-void GrantStore::removeAllGrantsToUid(const uid_t granteeUid) {
-    std::unique_lock<std::shared_mutex> lock(mutex_);
-    grants_.erase(granteeUid);
-}
-
-}  // namespace keystore
diff --git a/keystore/grant_store.h b/keystore/grant_store.h
deleted file mode 100644
index 1baf32c..0000000
--- a/keystore/grant_store.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2017 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_GRANT_STORE_H_
-#define KEYSTORE_GRANT_STORE_H_
-
-#include <mutex>
-#include <set>
-#include <shared_mutex>
-#include <string>
-#include <unordered_map>
-
-#include <keystore/keystore_concurrency.h>
-
-#include "blob.h"
-
-namespace keystore {
-
-class Grant;
-
-using ReadLockedGrant =
-    ProxyLock<MutexProxyLockHelper<const Grant, std::shared_mutex, std::shared_lock>>;
-
-/**
- * Grant represents a mapping from an alias to a key file.
- * Normally, key file names are derived from the alias chosen by the client
- * and the clients UID, to generate a per client name space.
- * Grants allow assotiating a key file with a new name, thereby making
- * it visible in another client's - the grantee's - namespace.
- */
-class Grant {
-public:
-  Grant(const KeyBlobEntry& entry, const uint64_t grant_no);
-  KeyBlobEntry entry_;
-
-  uint64_t grant_no_;  ///< numeric grant identifier - randomly assigned
-
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  operator const uint64_t&() const { return grant_no_; }
-};
-
-/**
- * The GrantStore holds a set of sets of Grants. One set of Grants for each grantee.
- * The uid parameter to each of the GrantStore function determines the grantee's
- * name space. The methods put, get, and removeByAlias/ByFileName create, lookup, and
- * remove a Grant, respectively.
- * put also returns a new alias for the newly granted key which has to be returned
- * to the granter. The grantee, and only the grantee, can use the granted key
- * by this new alias.
- */
-class GrantStore {
-public:
-    GrantStore() : grants_() {}
-    std::string put(const uid_t uid, const LockedKeyBlobEntry& blobfile);
-    ReadLockedGrant get(const uid_t uid, const std::string& alias) const;
-    bool removeByFileAlias(const uid_t granteeUid, const LockedKeyBlobEntry& lockedEntry);
-    void removeAllGrantsToKey(const uid_t granterUid, const std::string& alias);
-    void removeAllGrantsToUid(const uid_t granteeUid);
-
-    // GrantStore is neither copyable nor movable.
-    GrantStore(const GrantStore&) = delete;
-    GrantStore& operator=(const GrantStore&) = delete;
-private:
-    std::unordered_map<uid_t, std::set<Grant, std::less<>>> grants_;
-    mutable std::shared_mutex mutex_;
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_GRANT_STORE_H_
diff --git a/keystore/include/keystore/KeyAttestationApplicationId.h b/keystore/include/keystore/KeyAttestationApplicationId.h
index 861c2e1..0bf1aad 100644
--- a/keystore/include/keystore/KeyAttestationApplicationId.h
+++ b/keystore/include/keystore/KeyAttestationApplicationId.h
@@ -16,6 +16,7 @@
 #define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include <binder/Parcelable.h>
@@ -30,10 +31,10 @@
   public:
     typedef SharedNullableIterator<const KeyAttestationPackageInfo, std::vector>
         ConstKeyAttestationPackageInfoIterator;
-    typedef std::vector<std::unique_ptr<KeyAttestationPackageInfo>> PackageInfoVector;
+    typedef std::vector<std::optional<KeyAttestationPackageInfo>> PackageInfoVector;
     KeyAttestationApplicationId();
     // Following c'tors are for initializing instances containing test data.
-    explicit KeyAttestationApplicationId(std::unique_ptr<KeyAttestationPackageInfo> package);
+    explicit KeyAttestationApplicationId(std::optional<KeyAttestationPackageInfo> package);
     explicit KeyAttestationApplicationId(PackageInfoVector packages);
 
     status_t writeToParcel(Parcel*) const override;
@@ -47,7 +48,7 @@
     }
 
   private:
-    std::shared_ptr<std::vector<std::unique_ptr<KeyAttestationPackageInfo>>> packageInfos_;
+    std::shared_ptr<PackageInfoVector> packageInfos_;
 };
 
 }  // namespace keymaster
diff --git a/keystore/include/keystore/KeyAttestationPackageInfo.h b/keystore/include/keystore/KeyAttestationPackageInfo.h
index 92d4863..fa638f9 100644
--- a/keystore/include/keystore/KeyAttestationPackageInfo.h
+++ b/keystore/include/keystore/KeyAttestationPackageInfo.h
@@ -18,6 +18,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include <binder/Parcelable.h>
@@ -33,8 +34,7 @@
   public:
     typedef SharedNullableIterator<const content::pm::Signature, std::vector>
         ConstSignatureIterator;
-    typedef std::vector<std::unique_ptr<content::pm::Signature>>
-        SignaturesVector;
+    typedef std::vector<std::optional<content::pm::Signature>> SignaturesVector;
     typedef std::shared_ptr<SignaturesVector> SharedSignaturesVector;
 
     KeyAttestationPackageInfo(const String16& packageName, int64_t versionCode,
@@ -44,14 +44,14 @@
     status_t writeToParcel(Parcel*) const override;
     status_t readFromParcel(const Parcel* parcel) override;
 
-    const std::unique_ptr<String16>& package_name() const { return packageName_; }
+    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::unique_ptr<String16> packageName_;
+    std::optional<String16> packageName_;
     int64_t versionCode_;
     SharedSignaturesVector signatures_;
 };
diff --git a/keystore/include/keystore/KeystoreResponse.h b/keystore/include/keystore/KeystoreResponse.h
index 20f7274..4a7ef0d 100644
--- a/keystore/include/keystore/KeystoreResponse.h
+++ b/keystore/include/keystore/KeystoreResponse.h
@@ -31,29 +31,24 @@
   public:
     KeystoreResponse() = default;
     explicit KeystoreResponse(const int response_code, const String16& error_msg)
-        : response_code_(response_code), error_msg_(std::make_unique<String16>(error_msg)) {}
+        : response_code_(response_code), error_msg_(error_msg) {}
     explicit KeystoreResponse(const int response_code)
         : response_code_(response_code), error_msg_() {}
     // NOLINTNEXTLINE(google-explicit-constructor)
     KeystoreResponse(const ::keystore::KeyStoreServiceReturnCode& rc)
         : response_code_(rc.getErrorCode()), error_msg_() {}
-    KeystoreResponse(const KeystoreResponse& other)
-        : response_code_(other.response_code_), error_msg_() {
-        if (other.error_msg_) {
-            error_msg_ = std::make_unique<String16>(*other.error_msg_);
-        }
-    }
+    KeystoreResponse(const KeystoreResponse& other) = default;
     KeystoreResponse(KeystoreResponse&& other) = default;
 
     status_t readFromParcel(const Parcel* in) override;
     status_t writeToParcel(Parcel* out) const override;
 
     int response_code() const { return response_code_; }
-    const String16* error_msg() const { return error_msg_.get(); }
+    const std::optional<String16>& error_msg() const { return error_msg_; }
 
   private:
     int response_code_;
-    std::unique_ptr<String16> error_msg_;
+    std::optional<String16> error_msg_;
 };
 
 }  // namespace keystore
diff --git a/keystore/include/keystore/utils.h b/keystore/include/keystore/utils.h
index 544dd21..2143d3a 100644
--- a/keystore/include/keystore/utils.h
+++ b/keystore/include/keystore/utils.h
@@ -5,6 +5,7 @@
 
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <vector>
 
 namespace android {
@@ -12,7 +13,7 @@
 
 /*
  * This iterator abstracts from a collection of the form
- * std::shared_ptr<COLLECTION_TYPE<std::unique_ptr<T>>>
+ * std::shared_ptr<COLLECTION_TYPE<std::optional<T>>>
  * such that it is defined both for nulled outer pointer and
  * nulled entries. If shared_ptr(nullptr) is passed in, the iterator behaves
  * like the end iterator yielding an empty collection. Nulled
@@ -25,7 +26,7 @@
 template <typename T, template <typename...> class Coll = std::vector>
 class SharedNullableIterator {
   public:
-    typedef Coll<std::unique_ptr<typename std::remove_const<T>::type>> CollectionType;
+    typedef Coll<std::optional<typename std::remove_const<T>::type>> CollectionType;
     typedef std::shared_ptr<CollectionType> CollectionPtr;
 
     SharedNullableIterator() {}
diff --git a/keystore/key_attestation_log_handler.cpp b/keystore/key_attestation_log_handler.cpp
deleted file mode 100644
index c3278cb..0000000
--- a/keystore/key_attestation_log_handler.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 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 <statslog.h>
-namespace keystore {
-
-void logKeystoreKeyAttestationEvent(bool wasSuccessful, int32_t errorCode) {
-    // Due to a requirement in stats-write() method, the optional fields
-    // which are not required for attestation logging, are marked with -1 for
-    // non-repeated fields and 0 for repeated fields.
-    android::util::stats_write(android::util::KEYSTORE_KEY_EVENT_REPORTED, -1, -1, -1, -1, -1, 0, 0,
-                               0, 0, -1, -1,
-                               android::util::KEYSTORE_KEY_EVENT_REPORTED__TYPE__KEY_ATTESTATION,
-                               wasSuccessful, errorCode);
-}
-
-}  // namespace keystore
\ No newline at end of file
diff --git a/keystore/key_creation_log_handler.cpp b/keystore/key_creation_log_handler.cpp
deleted file mode 100644
index d846257..0000000
--- a/keystore/key_creation_log_handler.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#define LOG_TAG "KeystoreOperation"
-
-#include "key_creation_log_handler.h"
-#include <statslog.h>
-
-namespace keystore {
-
-template <typename Tag>
-int32_t getEnumTagValue(const AuthorizationSet& authorization_set, Tag tag) {
-    auto tagValue = authorization_set.GetTagValue(tag);
-    if (tagValue.isOk()) {
-        static_assert(sizeof(decltype(tagValue.value())) <= sizeof(int32_t),
-                      "Tag type value will be truncated, if cast to int32_t");
-        return static_cast<int32_t>(tagValue.value());
-    }
-    // Usually, if the value is not present, 0 is set. However, since 0 is a valid
-    // enum value, -1 is set for single enum fields.
-    return -1;
-}
-
-int32_t generateBitMapForPaddingModeValues(const AuthorizationSet& authorization_set) {
-    int32_t bitMap = 0;
-    int32_t tagValueCount = authorization_set.GetTagCount(TAG_PADDING);
-    if (tagValueCount == 0) {
-        // unlike in the single enum fields, if no value is provided,
-        // 0 is set for the bitmap
-        return bitMap;
-    }
-    int current_offset = -1;
-    while (tagValueCount > 0) {
-        current_offset = authorization_set.find(TAG_PADDING, current_offset);
-        KeyParameter keyParam = authorization_set[current_offset];
-        auto tagValue = accessTagValue(TAG_PADDING, keyParam);
-        switch (tagValue) {
-        case PaddingMode::NONE:
-            bitMap |= (1 << NONE_BIT_POS);
-            break;
-        case PaddingMode::RSA_OAEP:
-            bitMap |= (1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS);
-            break;
-        case PaddingMode::RSA_PSS:
-            bitMap |= (1 << PaddingModeBitPosition::RSA_PSS_BIT_POS);
-            break;
-        case PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
-            bitMap |= (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS);
-            break;
-        case PaddingMode::RSA_PKCS1_1_5_SIGN:
-            bitMap |= (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS);
-            break;
-        case PaddingMode::PKCS7:
-            bitMap |= (1 << PaddingModeBitPosition::PKCS7_BIT_POS);
-            break;
-        default:
-            break;
-        }
-        tagValueCount -= 1;
-    }
-    return bitMap;
-}
-
-int32_t generateBitMapForDigestValues(const AuthorizationSet& authorization_set) {
-    int32_t bitMap = 0;
-    int32_t tagValueCount = authorization_set.GetTagCount(TAG_DIGEST);
-    if (tagValueCount == 0) {
-        // unlike in the single enum fields, if no value is provided,
-        // 0 is set for the bitmap
-        return bitMap;
-    }
-    int current_offset = -1;
-    while (tagValueCount > 0) {
-        current_offset = authorization_set.find(TAG_DIGEST, current_offset);
-        KeyParameter keyParam = authorization_set[current_offset];
-        auto tagValue = accessTagValue(TAG_DIGEST, keyParam);
-        switch (tagValue) {
-        case Digest::NONE:
-            bitMap |= (1 << NONE_BIT_POS);
-            break;
-        case Digest::MD5:
-            bitMap |= (1 << DigestBitPosition::MD5_BIT_POS);
-            break;
-        case Digest::SHA1:
-            bitMap |= (1 << DigestBitPosition::SHA1_BIT_POS);
-            break;
-        case Digest::SHA_2_224:
-            bitMap |= (1 << DigestBitPosition::SHA_2_224_BIT_POS);
-            break;
-        case Digest::SHA_2_256:
-            bitMap |= (1 << DigestBitPosition::SHA_2_256_BIT_POS);
-            break;
-        case Digest::SHA_2_384:
-            bitMap |= (1 << DigestBitPosition::SHA_2_384_BIT_POS);
-            break;
-        case Digest::SHA_2_512:
-            bitMap |= (1 << DigestBitPosition::SHA_2_512_BIT_POS);
-            break;
-        default:
-            break;
-        }
-        tagValueCount -= 1;
-    }
-    return bitMap;
-}
-
-int32_t generateBitMapForBlockModeValues(const AuthorizationSet& authorization_set) {
-    int32_t bitMap = 0;
-    int32_t tagValueCount = authorization_set.GetTagCount(TAG_BLOCK_MODE);
-    if (tagValueCount == 0) {
-        // unlike in the single enum fields, if no value is provided,
-        // 0 is set for the bitmap
-        return bitMap;
-    }
-    int current_offset = -1;
-    while (tagValueCount > 0) {
-        current_offset = authorization_set.find(TAG_BLOCK_MODE, current_offset);
-        KeyParameter keyParam = authorization_set[current_offset];
-        auto tagValue = accessTagValue(TAG_BLOCK_MODE, keyParam);
-        switch (tagValue) {
-        case BlockMode::ECB:
-            bitMap |= (1 << BlockModeBitPosition::ECB_BIT_POS);
-            break;
-        case BlockMode::CBC:
-            bitMap |= (1 << BlockModeBitPosition::CBC_BIT_POS);
-            break;
-        case BlockMode::CTR:
-            bitMap |= (1 << BlockModeBitPosition::CTR_BIT_POS);
-            break;
-        case BlockMode::GCM:
-            bitMap |= (1 << BlockModeBitPosition::GCM_BIT_POS);
-            break;
-        default:
-            break;
-        }
-        tagValueCount -= 1;
-    }
-    return bitMap;
-}
-
-int32_t generateBitMapForKeyPurposeValues(const AuthorizationSet& authorization_set) {
-    int32_t bitMap = 0;
-    int32_t tagValueCount = authorization_set.GetTagCount(TAG_PURPOSE);
-    if (tagValueCount == 0) {
-        // unlike in the single enum fields, if no value is provided,
-        // 0 is set for the bitmap
-        return bitMap;
-    }
-    int current_offset = -1;
-    while (tagValueCount > 0) {
-        current_offset = authorization_set.find(TAG_PURPOSE, current_offset);
-        KeyParameter keyParam = authorization_set[current_offset];
-        auto tagValue = accessTagValue(TAG_PURPOSE, keyParam);
-        switch (tagValue) {
-        case KeyPurpose::ENCRYPT:
-            bitMap |= (1 << KeyPurposeBitPosition::ENCRYPT_BIT_POS);
-            break;
-        case KeyPurpose::DECRYPT:
-            bitMap |= (1 << KeyPurposeBitPosition::DECRYPT_BIT_POS);
-            break;
-        case KeyPurpose::SIGN:
-            bitMap |= (1 << KeyPurposeBitPosition::SIGN_BIT_POS);
-            break;
-        case KeyPurpose::VERIFY:
-            bitMap |= (1 << KeyPurposeBitPosition::VERIFY_BIT_POS);
-            break;
-        case KeyPurpose::WRAP_KEY:
-            bitMap |= (1 << KeyPurposeBitPosition::WRAP_KEY_BIT_POS);
-            break;
-        default:
-            break;
-        }
-        tagValueCount -= 1;
-    }
-    return bitMap;
-}
-
-void logKeystoreKeyCreationEvent(const hidl_vec<KeyParameter>& keyParams,
-                                 bool wasCreationSuccessful, int32_t errorCode) {
-    AuthorizationSet authorization_set(keyParams);
-    authorization_set.Deduplicate();
-
-    android::util::stats_write(android::util::KEYSTORE_KEY_EVENT_REPORTED,
-                               getEnumTagValue(authorization_set, TAG_ALGORITHM),
-                               getEnumTagValue(authorization_set, TAG_KEY_SIZE),
-                               getEnumTagValue(authorization_set, TAG_ORIGIN),
-                               getEnumTagValue(authorization_set, TAG_USER_AUTH_TYPE),
-                               getEnumTagValue(authorization_set, TAG_AUTH_TIMEOUT),
-                               generateBitMapForPaddingModeValues(authorization_set),
-                               generateBitMapForDigestValues(authorization_set),
-                               generateBitMapForBlockModeValues(authorization_set),
-                               generateBitMapForKeyPurposeValues(authorization_set),
-                               getEnumTagValue(authorization_set, TAG_EC_CURVE),
-                               getEnumTagValue(authorization_set, TAG_BLOB_USAGE_REQUIREMENTS),
-                               android::util::KEYSTORE_KEY_EVENT_REPORTED__TYPE__KEY_CREATION,
-                               wasCreationSuccessful, errorCode);
-}
-
-}  // namespace keystore
diff --git a/keystore/key_creation_log_handler.h b/keystore/key_creation_log_handler.h
deleted file mode 100644
index a314eb1..0000000
--- a/keystore/key_creation_log_handler.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 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 KEY_CREATION_LOG_HANDLER_H_
-#define KEY_CREATION_LOG_HANDLER_H_
-
-#include <keystore/keystore_hidl_support.h>
-
-namespace keystore {
-
-/**
- * Following enums are defined as a part of the workaround to log the repeated
- * values of ENUM_REP type. The workaround is to represent the repeated values
- * of ENUM_REP type as a bitmap and the following enums define their positions
- * in the bitmap.
- */
-
-enum PaddingModeBitPosition : int32_t {
-    RSA_OAEP_BIT_POS = 1,
-    RSA_PSS_BIT_POS = 2,
-    RSA_PKCS1_1_5_ENCRYPT_BIT_POS = 3,
-    RSA_PKCS1_1_5_SIGN_BIT_POS = 4,
-    PKCS7_BIT_POS = 5,
-};
-
-enum DigestBitPosition : int32_t {
-    MD5_BIT_POS = 1,
-    SHA1_BIT_POS = 2,
-    SHA_2_224_BIT_POS = 3,
-    SHA_2_256_BIT_POS = 4,
-    SHA_2_384_BIT_POS = 5,
-    SHA_2_512_BIT_POS = 6,
-};
-
-enum BlockModeBitPosition : int32_t {
-    ECB_BIT_POS = 1,
-    CBC_BIT_POS = 2,
-    CTR_BIT_POS = 3,
-    GCM_BIT_POS = 4,
-};
-
-enum KeyPurposeBitPosition : int32_t {
-    ENCRYPT_BIT_POS = 1,
-    DECRYPT_BIT_POS = 2,
-    SIGN_BIT_POS = 3,
-    VERIFY_BIT_POS = 4,
-    WRAP_KEY_BIT_POS = 5,
-};
-
-// None is an enum value for digest and a deprecated value for padding mode
-const int32_t NONE_BIT_POS = 0;
-
-void logKeystoreKeyCreationEvent(const hidl_vec<KeyParameter>& keyParams,
-                                 bool wasCreationSuccessful, int32_t errorCode);
-
-}  // namespace keystore
-
-#endif  // KEY_CREATION_LOG_HANDLER_H_
diff --git a/keystore/key_operation_log_handler.cpp b/keystore/key_operation_log_handler.cpp
deleted file mode 100644
index e7f4345..0000000
--- a/keystore/key_operation_log_handler.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#define LOG_TAG "KeystoreOperation"
-
-#include "key_operation_log_handler.h"
-#include "key_creation_log_handler.h"
-
-#include <keystore/keystore_hidl_support.h>
-#include <statslog.h>
-
-namespace keystore {
-
-template <typename Tag>
-int32_t getOptionalEnumTagValue(const AuthorizationSet& authorization_set, Tag tag) {
-    auto tagValue = authorization_set.GetTagValue(tag);
-    if (tagValue.isOk()) {
-        static_assert(sizeof(decltype(tagValue.value())) <= sizeof(int32_t),
-                      "Tag type value will be truncated, if cast to int32_t");
-        return static_cast<int32_t>(tagValue.value());
-    }
-    //-1 is an invalid value for all enum types.
-    return -1;
-}
-
-int32_t generateBitMapForPaddingModeValue(const AuthorizationSet& authorization_set) {
-    auto tagValue = authorization_set.GetTagValue(TAG_PADDING);
-    if (tagValue.isOk()) {
-        auto value = tagValue.value();
-        switch (value) {
-        case PaddingMode::NONE:
-            return (1 << NONE_BIT_POS);
-        case PaddingMode::RSA_OAEP:
-            return (1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS);
-        case PaddingMode::RSA_PSS:
-            return (1 << PaddingModeBitPosition::RSA_PSS_BIT_POS);
-        case PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
-            return (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS);
-        case PaddingMode::RSA_PKCS1_1_5_SIGN:
-            return (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS);
-        case PaddingMode::PKCS7:
-            return (1 << PaddingModeBitPosition::PKCS7_BIT_POS);
-        default:
-            break;
-        }
-    }
-    // unlike in the single enum fields, if no value is provided,
-    // 0 is set for the bitmap
-    return 0;
-}
-
-int32_t generateBitMapForDigestValue(const AuthorizationSet& authorization_set) {
-    auto tagValue = authorization_set.GetTagValue(TAG_DIGEST);
-    if (tagValue.isOk()) {
-        auto value = tagValue.value();
-        switch (value) {
-        case Digest::NONE:
-            return (1 << NONE_BIT_POS);
-        case Digest::MD5:
-            return (1 << DigestBitPosition::MD5_BIT_POS);
-        case Digest::SHA1:
-            return (1 << DigestBitPosition::SHA1_BIT_POS);
-        case Digest::SHA_2_224:
-            return (1 << DigestBitPosition::SHA_2_224_BIT_POS);
-        case Digest::SHA_2_256:
-            return (1 << DigestBitPosition::SHA_2_256_BIT_POS);
-        case Digest::SHA_2_384:
-            return (1 << DigestBitPosition::SHA_2_384_BIT_POS);
-        case Digest::SHA_2_512:
-            return (1 << DigestBitPosition::SHA_2_512_BIT_POS);
-        default:
-            break;
-        }
-    }
-    // unlike in the single enum fields, if no value is provided,
-    // 0 is set for the bitmap
-    return 0;
-}
-
-int32_t generateBitMapForBlockModeValue(const AuthorizationSet& authorization_set) {
-    auto tagValue = authorization_set.GetTagValue(TAG_BLOCK_MODE);
-    if (tagValue.isOk()) {
-        auto value = tagValue.value();
-        switch (value) {
-        case BlockMode::ECB:
-            return (1 << BlockModeBitPosition::ECB_BIT_POS);
-        case BlockMode::CBC:
-            return (1 << BlockModeBitPosition::CBC_BIT_POS);
-        case BlockMode::CTR:
-            return (1 << BlockModeBitPosition::CTR_BIT_POS);
-        case BlockMode::GCM:
-            return (1 << BlockModeBitPosition::GCM_BIT_POS);
-        default:
-            break;
-        }
-    }
-    // unlike in the single enum fields, if no value is provided,
-    // 0 is set for the bitmap
-    return 0;
-}
-
-void logKeystoreKeyOperationEvent(const Operation& op, bool wasOperationSuccessful,
-                                  int32_t responseCode) {
-    AuthorizationSet authorization_set(op.characteristics.softwareEnforced);
-    authorization_set.Union(op.characteristics.hardwareEnforced);
-    AuthorizationSet operation_params(op.params);
-
-    android::util::stats_write(
-        android::util::KEYSTORE_KEY_EVENT_REPORTED,
-        getOptionalEnumTagValue(authorization_set, TAG_ALGORITHM),
-        getOptionalEnumTagValue(authorization_set, TAG_KEY_SIZE),
-        getOptionalEnumTagValue(authorization_set, TAG_ORIGIN),
-        getOptionalEnumTagValue(authorization_set, TAG_USER_AUTH_TYPE),
-        getOptionalEnumTagValue(authorization_set, TAG_AUTH_TIMEOUT),
-        generateBitMapForPaddingModeValue(operation_params),
-        generateBitMapForDigestValue(operation_params),
-        generateBitMapForBlockModeValue(operation_params), static_cast<int32_t>(op.purpose),
-        getOptionalEnumTagValue(authorization_set, TAG_EC_CURVE),
-        getOptionalEnumTagValue(authorization_set, TAG_BLOB_USAGE_REQUIREMENTS),
-        android::util::KEYSTORE_KEY_EVENT_REPORTED__TYPE__KEY_OPERATION, wasOperationSuccessful,
-        responseCode);
-}
-
-}  // namespace keystore
\ No newline at end of file
diff --git a/keystore/key_operation_log_handler.h b/keystore/key_operation_log_handler.h
deleted file mode 100644
index ba27747..0000000
--- a/keystore/key_operation_log_handler.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 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 KEY_OPERATION_LOG_HANDLER_H_
-#define KEY_OPERATION_LOG_HANDLER_H_
-
-#include "operation_struct.h"
-
-namespace keystore {
-
-void logKeystoreKeyOperationEvent(const Operation& op, bool wasSuccessful, int32_t errorCode);
-
-}  // namespace keystore
-
-#endif  // KEY_OPERATION_LOG_HANDLER_H_
\ No newline at end of file
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
deleted file mode 100644
index 1b38643..0000000
--- a/keystore/key_store_service.cpp
+++ /dev/null
@@ -1,1394 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define LOG_TAG "keystore"
-
-#include "key_store_service.h"
-
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include <algorithm>
-#include <atomic>
-#include <sstream>
-
-#include <android-base/scopeguard.h>
-#include <binder/IInterface.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IPermissionController.h>
-#include <binder/IServiceManager.h>
-#include <cutils/multiuser.h>
-#include <log/log_event_list.h>
-
-#include <private/android_filesystem_config.h>
-#include <private/android_logger.h>
-
-#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
-#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
-#include <keymasterV4_0/keymaster_utils.h>
-
-#include "defaults.h"
-#include "key_attestation_log_handler.h"
-#include "keystore_keymaster_enforcement.h"
-#include "keystore_utils.h"
-#include <keystore/keystore_attestation_id.h>
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_return_types.h>
-
-#include <hardware/hw_auth_token.h>
-
-namespace keystore {
-
-using namespace android;
-
-namespace {
-
-using ::android::binder::Status;
-using android::hardware::keymaster::V4_0::support::authToken2HidlVec;
-using android::hardware::keymaster::V4_0::support::serializeVerificationToken;
-using android::security::keymaster::ExportResult;
-using android::security::keymaster::KeymasterArguments;
-using android::security::keymaster::KeymasterBlob;
-using android::security::keymaster::KeymasterCertificateChain;
-using android::security::keymaster::operationFailed;
-using android::security::keymaster::OperationResult;
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
-using ::android::security::keystore::ICredstoreTokenCallback;
-using ::android::security::keystore::IKeystoreOperationResultCallback;
-using ::android::security::keystore::IKeystoreResponseCallback;
-using ::android::security::keystore::KeystoreResponse;
-
-constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
-const char* kTimestampFilePath = "timestamp";
-
-bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
-    return params.end() !=
-           std::find_if(params.begin(), params.end(),
-                        [&](const KeyParameter& param) { return param.tag == tag; });
-}
-
-#define AIDL_RETURN(rc) (*_aidl_return = KeyStoreServiceReturnCode(rc).getErrorCode(), Status::ok())
-
-std::pair<KeyStoreServiceReturnCode, bool> hadFactoryResetSinceIdRotation() {
-    struct stat sbuf;
-    if (stat(kTimestampFilePath, &sbuf) == 0) {
-        double diff_secs = difftime(time(nullptr), sbuf.st_ctime);
-        return {ResponseCode::NO_ERROR, diff_secs < kIdRotationPeriod};
-    }
-
-    if (errno != ENOENT) {
-        ALOGE("Failed to stat \"timestamp\" file, with error %d", errno);
-        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
-    }
-
-    int fd = creat(kTimestampFilePath, 0600);
-    if (fd < 0) {
-        ALOGE("Couldn't create \"timestamp\" file, with error %d", errno);
-        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
-    }
-
-    if (close(fd)) {
-        ALOGE("Couldn't close \"timestamp\" file, with error %d", errno);
-        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
-    }
-
-    return {ResponseCode::NO_ERROR, true};
-}
-
-using ::android::security::KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE;
-
-KeyStoreServiceReturnCode updateParamsForAttestation(uid_t callingUid, AuthorizationSet* params) {
-    KeyStoreServiceReturnCode responseCode;
-    bool factoryResetSinceIdRotation;
-    std::tie(responseCode, factoryResetSinceIdRotation) = hadFactoryResetSinceIdRotation();
-
-    if (!responseCode.isOk()) return responseCode;
-    if (factoryResetSinceIdRotation) params->push_back(TAG_RESET_SINCE_ID_ROTATION);
-
-    auto asn1_attestation_id_result = security::gather_attestation_application_id(callingUid);
-    if (!asn1_attestation_id_result.isOk()) {
-        ALOGE("failed to gather attestation_id");
-        // Couldn't get attestation ID; just use an empty one rather than failing.
-        asn1_attestation_id_result = std::vector<uint8_t>();
-    }
-    std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;
-
-    /*
-     * The attestation application ID must not be longer than
-     * KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE, error out if gather_attestation_application_id
-     * returned such an invalid vector.
-     */
-    if (asn1_attestation_id.size() > KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE) {
-        ALOGE("BUG: Gathered Attestation Application ID is too big (%d)",
-              static_cast<int32_t>(asn1_attestation_id.size()));
-        return ErrorCode::CANNOT_ATTEST_IDS;
-    }
-
-    params->push_back(TAG_ATTESTATION_APPLICATION_ID, asn1_attestation_id);
-
-    return ResponseCode::NO_ERROR;
-}
-
-}  // anonymous namespace
-
-Status KeyStoreService::getState(int32_t userId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_GET_STATE)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-    *aidl_return = mKeyStore->getState(userId);
-    return Status::ok();
-}
-
-Status KeyStoreService::get(const String16& name, int32_t uid, ::std::vector<uint8_t>* item) {
-    uid_t targetUid = getEffectiveUid(uid);
-    if (!checkBinderPermission(P_GET, targetUid)) {
-        // see keystore/keystore.h
-        return Status::fromServiceSpecificError(
-            static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
-    }
-
-    String8 name8(name);
-    ResponseCode rc;
-    Blob keyBlob;
-    Blob charBlob;
-    LockedKeyBlobEntry lockedEntry;
-
-    std::tie(rc, keyBlob, charBlob, lockedEntry) =
-        mKeyStore->getKeyForName(name8, targetUid, TYPE_GENERIC);
-    if (rc != ResponseCode::NO_ERROR) {
-        *item = ::std::vector<uint8_t>();
-        // Return empty array if key is not found
-        // TODO: consider having returned value nullable or parse exception on the client.
-        return Status::fromServiceSpecificError(static_cast<int32_t>(rc));
-    }
-    auto resultBlob = blob2hidlVec(keyBlob);
-    // The static_cast here is needed to prevent a move, forcing a deep copy.
-    if (item) *item = static_cast<const hidl_vec<uint8_t>&>(blob2hidlVec(keyBlob));
-    return Status::ok();
-}
-
-Status KeyStoreService::insert(const String16& name, const ::std::vector<uint8_t>& item,
-                               int targetUid, int32_t flags, int32_t* aidl_return) {
-    targetUid = getEffectiveUid(targetUid);
-    KeyStoreServiceReturnCode result =
-        checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (!result.isOk()) {
-        *aidl_return = result.getErrorCode();
-        return Status::ok();
-    }
-
-    String8 name8(name);
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), targetUid);
-
-    if (!lockedEntry) {
-        ALOGE("failed to grab lock on blob entry %u_%s", targetUid, name8.string());
-        *aidl_return = static_cast<int32_t>(ResponseCode::KEY_ALREADY_EXISTS);
-        return Status::ok();
-    }
-
-    Blob keyBlob(&item[0], item.size(), nullptr, 0, ::TYPE_GENERIC);
-    keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-
-    *aidl_return = static_cast<int32_t>(mKeyStore->put(lockedEntry, keyBlob, {}));
-    return Status::ok();
-}
-
-Status KeyStoreService::del(const String16& name, int targetUid, int32_t* aidl_return) {
-    targetUid = getEffectiveUid(targetUid);
-    if (!checkBinderPermission(P_DELETE, targetUid)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-    String8 name8(name);
-    ALOGI("del %s %d", name8.string(), targetUid);
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfExists(name8.string(), targetUid);
-    if (!lockedEntry) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::KEY_NOT_FOUND);
-        return Status::ok();
-    }
-
-    ResponseCode result = mKeyStore->del(lockedEntry);
-
-    *aidl_return = static_cast<int32_t>(result);
-    return Status::ok();
-}
-
-Status KeyStoreService::exist(const String16& name, int targetUid, int32_t* aidl_return) {
-    targetUid = getEffectiveUid(targetUid);
-    if (!checkBinderPermission(P_EXIST, targetUid)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    LockedKeyBlobEntry lockedEntry =
-        mKeyStore->getLockedBlobEntryIfExists(String8(name).string(), targetUid);
-    *aidl_return =
-        static_cast<int32_t>(lockedEntry ? ResponseCode::NO_ERROR : ResponseCode::KEY_NOT_FOUND);
-    return Status::ok();
-}
-
-Status KeyStoreService::list(const String16& prefix, int32_t targetUid,
-                             ::std::vector<::android::String16>* matches) {
-    targetUid = getEffectiveUid(targetUid);
-    if (!checkBinderPermission(P_LIST, targetUid)) {
-        return Status::fromServiceSpecificError(
-            static_cast<int32_t>(ResponseCode::PERMISSION_DENIED));
-    }
-    const String8 prefix8(prefix);
-    const std::string stdPrefix(prefix8.string());
-
-    ResponseCode rc;
-    std::list<LockedKeyBlobEntry> internal_matches;
-    auto userDirName = mKeyStore->getUserStateDB().getUserStateByUid(targetUid)->getUserDirName();
-
-    std::tie(rc, internal_matches) =
-        LockedKeyBlobEntry::list(userDirName, [&](uid_t uid, const std::string& alias) {
-            std::mismatch(stdPrefix.begin(), stdPrefix.end(), alias.begin(), alias.end());
-            return uid == static_cast<uid_t>(targetUid) &&
-                   std::mismatch(stdPrefix.begin(), stdPrefix.end(), alias.begin(), alias.end())
-                           .first == stdPrefix.end();
-        });
-
-    if (rc != ResponseCode::NO_ERROR) {
-        return Status::fromServiceSpecificError(static_cast<int32_t>(rc));
-    }
-
-    for (LockedKeyBlobEntry& entry : internal_matches) {
-        matches->push_back(String16(entry->alias().substr(prefix8.size()).c_str()));
-    }
-    return Status::ok();
-}
-
-/*
- * This method will return the uids of all auth bound keys for the calling user.
- * This is intended to be used for alerting the user about which apps will be affected
- * if the password/pin is removed. Only allowed to be called by system.
- * The output is bound by the initial size of uidsOut to be compatible with Java.
- */
-Status KeyStoreService::listUidsOfAuthBoundKeys(std::vector<std::string>* uidsOut,
-                                                int32_t* aidl_return) {
-    const int32_t callingUid = IPCThreadState::self()->getCallingUid();
-    const int32_t userId = get_user_id(callingUid);
-    const int32_t appId = get_app_id(callingUid);
-    if (appId != AID_SYSTEM) {
-        ALOGE("Permission listUidsOfAuthBoundKeys denied for aid %d", appId);
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    const String8 prefix8("");
-    auto userState = mKeyStore->getUserStateDB().getUserState(userId);
-    const std::string userDirName = userState->getUserDirName();
-    auto encryptionKey = userState->getEncryptionKey();
-    auto state = userState->getState();
-    // unlock the user state
-    userState = {};
-
-    ResponseCode rc;
-    std::list<LockedKeyBlobEntry> internal_matches;
-    std::tie(rc, internal_matches) =
-        LockedKeyBlobEntry::list(userDirName, [&](uid_t, const std::string&) {
-            // Need to filter on auth bound state, so just return true.
-            return true;
-        });
-    if (rc != ResponseCode::NO_ERROR) {
-        ALOGE("Error listing blob entries for user %d", userId);
-        return Status::fromServiceSpecificError(static_cast<int32_t>(rc));
-    }
-
-    for (LockedKeyBlobEntry& entry : internal_matches) {
-        // Need to store uids as a list of strings because integer list output
-        // parameters is not supported in aidl-cpp.
-        std::string entryUid = std::to_string(entry->uid());
-        if (std::find(uidsOut->begin(), uidsOut->end(), entryUid) != uidsOut->end()) {
-            // uid already in list, skip
-            continue;
-        }
-
-        auto [rc, blob, charBlob] = entry.readBlobs(encryptionKey, state);
-        if (rc != ResponseCode::NO_ERROR && rc != ResponseCode::LOCKED) {
-            ALOGE("Error reading blob for key %s", entry->alias().c_str());
-            continue;
-        }
-
-        if (blob && blob.isEncrypted()) {
-            uidsOut->push_back(entryUid);
-        } else if (charBlob) {
-            auto [success, hwEnforced, swEnforced] = charBlob.getKeyCharacteristics();
-            if (!success) {
-                ALOGE("Error reading blob characteristics for key %s", entry->alias().c_str());
-                continue;
-            }
-            if (hwEnforced.Contains(TAG_USER_SECURE_ID) ||
-                swEnforced.Contains(TAG_USER_SECURE_ID)) {
-                uidsOut->push_back(entryUid);
-            }
-        }
-    }
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::onUserPasswordChanged(int32_t userId, const String16& password,
-                                              int32_t* aidl_return) {
-    if (!checkBinderPermission(P_PASSWORD)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    if (password.size() == 0) {
-        ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId);
-        mKeyStore->resetUser(userId, true);
-        *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-        return Status::ok();
-    } else {
-        const String8 password8(password);
-        switch (mKeyStore->getState(userId)) {
-        case ::STATE_UNINITIALIZED: {
-            // generate master key, encrypt with password, write to file,
-            // initialize mMasterKey*.
-            *aidl_return = static_cast<int32_t>(mKeyStore->initializeUser(password8, userId));
-            return Status::ok();
-        }
-        case ::STATE_NO_ERROR: {
-            // rewrite master key with new password.
-            *aidl_return = static_cast<int32_t>(mKeyStore->writeMasterKey(password8, userId));
-            return Status::ok();
-        }
-        case ::STATE_LOCKED: {
-            ALOGE("Changing user %d's password while locked, clearing old encryption", userId);
-            mKeyStore->resetUser(userId, true);
-            *aidl_return = static_cast<int32_t>(mKeyStore->initializeUser(password8, userId));
-            return Status::ok();
-        }
-        }
-        *aidl_return = static_cast<int32_t>(ResponseCode::SYSTEM_ERROR);
-        return Status::ok();
-    }
-}
-
-Status KeyStoreService::onUserAdded(int32_t userId, int32_t parentId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_USER_CHANGED)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    // Sanity check that the new user has an empty keystore.
-    if (!mKeyStore->isEmpty(userId)) {
-        ALOGW("New user %d's keystore not empty. Clearing old entries.", userId);
-    }
-    // Unconditionally clear the keystore, just to be safe.
-    mKeyStore->resetUser(userId, false);
-    if (parentId != -1) {
-        // This profile must share the same master key password as the parent profile. Because the
-        // password of the parent profile is not known here, the best we can do is copy the parent's
-        // master key and master key file. This makes this profile use the same master key as the
-        // parent profile, forever.
-        *aidl_return = static_cast<int32_t>(mKeyStore->copyMasterKey(parentId, userId));
-        return Status::ok();
-    } else {
-        *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-        return Status::ok();
-    }
-}
-
-Status KeyStoreService::onUserRemoved(int32_t userId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_USER_CHANGED)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    mKeyStore->resetUser(userId, false);
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::lock(int32_t userId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_LOCK)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    State state = mKeyStore->getState(userId);
-    if (state != ::STATE_NO_ERROR) {
-        ALOGD("calling lock in state: %d", state);
-        *aidl_return = static_cast<int32_t>(ResponseCode(state));
-        return Status::ok();
-    }
-
-    mKeyStore->getEnforcementPolicy().set_device_locked(true, userId);
-    mKeyStore->lock(userId);
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::unlock(int32_t userId, const String16& pw, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_UNLOCK)) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-
-    State state = mKeyStore->getState(userId);
-    if (state != ::STATE_LOCKED) {
-        switch (state) {
-        case ::STATE_NO_ERROR:
-            ALOGI("calling unlock when already unlocked, ignoring.");
-            break;
-        case ::STATE_UNINITIALIZED:
-            ALOGE("unlock called on uninitialized keystore.");
-            break;
-        default:
-            ALOGE("unlock called on keystore in unknown state: %d", state);
-            break;
-        }
-        *aidl_return = static_cast<int32_t>(ResponseCode(state));
-        return Status::ok();
-    }
-
-    mKeyStore->getEnforcementPolicy().set_device_locked(false, userId);
-    const String8 password8(pw);
-    // read master key, decrypt with password, initialize mMasterKey*.
-    *aidl_return = static_cast<int32_t>(mKeyStore->readMasterKey(password8, userId));
-    return Status::ok();
-}
-
-Status KeyStoreService::isEmpty(int32_t userId, int32_t* aidl_return) {
-    if (!checkBinderPermission(P_IS_EMPTY)) {
-        *aidl_return = static_cast<int32_t>(false);
-        return Status::ok();
-    }
-
-    *aidl_return = static_cast<int32_t>(mKeyStore->isEmpty(userId));
-    return Status::ok();
-}
-
-Status KeyStoreService::grant(const String16& name, int32_t granteeUid,
-                              ::android::String16* aidl_return) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    auto result =
-        checkBinderPermissionAndKeystoreState(P_GRANT, /*targetUid=*/-1, /*checkUnlocked=*/false);
-    if (!result.isOk()) {
-        *aidl_return = String16();
-        return Status::ok();
-    }
-
-    String8 name8(name);
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfExists(name8.string(), callingUid);
-    if (!lockedEntry) {
-        *aidl_return = String16();
-        return Status::ok();
-    }
-
-    *aidl_return = String16(mKeyStore->addGrant(lockedEntry, granteeUid).c_str());
-    return Status::ok();
-}
-
-Status KeyStoreService::ungrant(const String16& name, int32_t granteeUid, int32_t* aidl_return) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    KeyStoreServiceReturnCode result =
-        checkBinderPermissionAndKeystoreState(P_GRANT, /*targetUid=*/-1, /*checkUnlocked=*/false);
-    if (!result.isOk()) {
-        *aidl_return = result.getErrorCode();
-        return Status::ok();
-    }
-
-    String8 name8(name);
-
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfExists(name8.string(), callingUid);
-    if (!lockedEntry) {
-        *aidl_return = static_cast<int32_t>(ResponseCode::KEY_NOT_FOUND);
-    }
-
-    *aidl_return = mKeyStore->removeGrant(lockedEntry, granteeUid);
-    return Status::ok();
-}
-
-Status KeyStoreService::getmtime(const String16& name, int32_t uid, int64_t* time) {
-    uid_t targetUid = getEffectiveUid(uid);
-    if (!checkBinderPermission(P_GET, targetUid)) {
-        ALOGW("permission denied for %d: getmtime", targetUid);
-        *time = -1L;
-        return Status::ok();
-    }
-    String8 name8(name);
-
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfExists(name8.string(), targetUid);
-    if (!lockedEntry) {
-        ALOGW("could not access key with alias %s for getmtime", name8.string());
-        *time = -1L;
-        return Status::ok();
-    }
-
-    std::string filename = lockedEntry->getKeyBlobPath();
-
-    int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_NOFOLLOW, O_RDONLY));
-    if (fd < 0) {
-        ALOGW("could not open %s for getmtime", filename.c_str());
-        *time = -1L;
-        return Status::ok();
-    }
-
-    struct stat s;
-    int ret = fstat(fd, &s);
-    close(fd);
-    if (ret == -1) {
-        ALOGW("could not stat %s for getmtime", filename.c_str());
-        *time = -1L;
-        return Status::ok();
-    }
-
-    *time = static_cast<int64_t>(s.st_mtime);
-    return Status::ok();
-}
-
-Status KeyStoreService::is_hardware_backed(const String16& keyType, int32_t* aidl_return) {
-    *aidl_return = static_cast<int32_t>(mKeyStore->isHardwareBacked(keyType) ? 1 : 0);
-    return Status::ok();
-}
-
-Status KeyStoreService::clear_uid(int64_t targetUid64, int32_t* _aidl_return) {
-    uid_t targetUid = getEffectiveUid(targetUid64);
-    if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-    ALOGI("clear_uid %" PRId64, targetUid64);
-
-    mKeyStore->removeAllGrantsToUid(targetUid);
-
-    ResponseCode rc;
-    std::list<LockedKeyBlobEntry> entries;
-    auto userDirName = mKeyStore->getUserStateDB().getUserStateByUid(targetUid)->getUserDirName();
-
-    // list has a fence making sure no workers are modifying blob files before iterating the
-    // data base. All returned entries are locked.
-    std::tie(rc, entries) = LockedKeyBlobEntry::list(
-        userDirName, [&](uid_t uid, const std::string&) -> bool { return uid == targetUid; });
-
-    if (rc != ResponseCode::NO_ERROR) {
-        return AIDL_RETURN(rc);
-    }
-
-    for (LockedKeyBlobEntry& lockedEntry : entries) {
-        if (get_app_id(targetUid) == AID_SYSTEM) {
-            Blob keyBlob;
-            Blob charBlob;
-            std::tie(rc, keyBlob, charBlob) = mKeyStore->get(lockedEntry);
-            if (rc == ResponseCode::NO_ERROR && keyBlob.isCriticalToDeviceEncryption()) {
-                // Do not clear keys critical to device encryption under system uid.
-                continue;
-            }
-        }
-        mKeyStore->del(lockedEntry);
-    }
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::addRngEntropy(
-    const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
-    const ::std::vector<uint8_t>& entropy, int32_t flags, int32_t* _aidl_return) {
-    auto device = mKeyStore->getDevice(flagsToSecurityLevel(flags));
-    if (!device) {
-        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-    }
-
-    device->addRngEntropy(entropy, [device, cb](Return<ErrorCode> rc) {
-        cb->onFinished(KeyStoreServiceReturnCode(KS_HANDLE_HIDL_ERROR(device, rc)));
-    });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::generateKey(
-    const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
-    const String16& name, const KeymasterArguments& params, const ::std::vector<uint8_t>& entropy,
-    int uid, int flags, int32_t* _aidl_return) {
-    uid = getEffectiveUid(uid);
-    auto logOnScopeExit = android::base::make_scope_guard([&] {
-        if (__android_log_security()) {
-            android_log_event_list(SEC_TAG_AUTH_KEY_GENERATED)
-                << int32_t(*_aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
-                << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
-        }
-    });
-    KeyStoreServiceReturnCode rc =
-        checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-    if ((flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION) && get_app_id(uid) != AID_SYSTEM) {
-        ALOGE("Non-system uid %d cannot set FLAG_CRITICAL_TO_DEVICE_ENCRYPTION", uid);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    if (containsTag(params.getParameters(), Tag::INCLUDE_UNIQUE_ID)) {
-        if (!checkBinderPermission(P_GEN_UNIQUE_ID)) {
-            return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-        }
-    }
-
-    SecurityLevel securityLevel = flagsToSecurityLevel(flags);
-    auto dev = mKeyStore->getDevice(securityLevel);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-    }
-
-    String8 name8(name);
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), uid);
-    if (!lockedEntry) {
-        return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
-    }
-
-    logOnScopeExit.Disable();
-
-    dev->generateKey(
-        std::move(lockedEntry), params.getParameters(), entropy, flags,
-        [cb, uid, name](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
-            if (__android_log_security()) {
-                android_log_event_list(SEC_TAG_AUTH_KEY_GENERATED)
-                    << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
-            }
-            cb->onFinished(rc,
-                           android::security::keymaster::KeyCharacteristics(keyCharacteristics));
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::getKeyCharacteristics(
-    const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
-    const String16& name, const ::android::security::keymaster::KeymasterBlob& clientId,
-    const ::android::security::keymaster::KeymasterBlob& appData, int32_t uid,
-    int32_t* _aidl_return) {
-
-    uid_t targetUid = getEffectiveUid(uid);
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (!is_granted_to(callingUid, targetUid)) {
-        ALOGW("uid %d not permitted to act for uid %d in getKeyCharacteristics", callingUid,
-              targetUid);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    String8 name8(name);
-
-    ResponseCode rc;
-    Blob keyBlob;
-    Blob charBlob;
-    LockedKeyBlobEntry lockedEntry;
-
-    std::tie(rc, keyBlob, charBlob, lockedEntry) =
-        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
-
-    if (rc != ResponseCode::NO_ERROR) {
-        return AIDL_RETURN(rc);
-    }
-
-    auto dev = mKeyStore->getDevice(keyBlob);
-    if (!dev) {
-        return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
-    }
-
-    // If the charBlob is up to date, it simply moves the argument blobs to the returned blobs
-    // and extracts the characteristics on the way. Otherwise it updates the cache file with data
-    // from keymaster. It may also upgrade the key blob.
-    dev->getKeyCharacteristics(
-        std::move(lockedEntry), clientId.getData(), appData.getData(), std::move(keyBlob),
-        std::move(charBlob),
-        [cb](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
-            cb->onFinished(rc,
-                           android::security::keymaster::KeyCharacteristics(keyCharacteristics));
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::importKey(
-    const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
-    const String16& name, const KeymasterArguments& params, int32_t format,
-    const ::std::vector<uint8_t>& keyData, int uid, int flags, int32_t* _aidl_return) {
-    uid = getEffectiveUid(uid);
-    auto logOnScopeExit = android::base::make_scope_guard([&] {
-        if (__android_log_security()) {
-            android_log_event_list(SEC_TAG_KEY_IMPORTED)
-                << int32_t(*_aidl_return == static_cast<int32_t>(ResponseCode::NO_ERROR))
-                << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
-        }
-    });
-    KeyStoreServiceReturnCode rc =
-        checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (!rc.isOk()) {
-        LOG(ERROR) << "permissission denied";
-        return AIDL_RETURN(rc);
-    }
-    if ((flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION) && get_app_id(uid) != AID_SYSTEM) {
-        ALOGE("Non-system uid %d cannot set FLAG_CRITICAL_TO_DEVICE_ENCRYPTION", uid);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    SecurityLevel securityLevel = flagsToSecurityLevel(flags);
-    auto dev = mKeyStore->getDevice(securityLevel);
-    if (!dev) {
-        LOG(ERROR) << "importKey - cound not get keymaster device";
-        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-    }
-
-    String8 name8(name);
-    auto lockedEntry = mKeyStore->getLockedBlobEntryIfNotExists(name8.string(), uid);
-    if (!lockedEntry) {
-        LOG(ERROR) << "importKey - key: " << name8.string() << " " << int(uid)
-                   << " already exists.";
-        return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
-    }
-
-    logOnScopeExit.Disable();
-
-    dev->importKey(
-        std::move(lockedEntry), params.getParameters(), KeyFormat(format), keyData, flags,
-        [cb, uid, name](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
-            if (__android_log_security()) {
-                android_log_event_list(SEC_TAG_KEY_IMPORTED)
-                    << rc.isOk() << String8(name) << int32_t(uid) << LOG_ID_SECURITY;
-            }
-            cb->onFinished(rc,
-                           android::security::keymaster::KeyCharacteristics(keyCharacteristics));
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::exportKey(
-    const ::android::sp<::android::security::keystore::IKeystoreExportKeyCallback>& cb,
-    const String16& name, int32_t format,
-    const ::android::security::keymaster::KeymasterBlob& clientId,
-    const ::android::security::keymaster::KeymasterBlob& appData, int32_t uid,
-    int32_t* _aidl_return) {
-
-    uid_t targetUid = getEffectiveUid(uid);
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (!is_granted_to(callingUid, targetUid)) {
-        ALOGW("uid %d not permitted to act for uid %d in exportKey", callingUid, targetUid);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    String8 name8(name);
-
-    KeyStoreServiceReturnCode rc;
-    Blob keyBlob;
-    Blob charBlob;
-    LockedKeyBlobEntry lockedEntry;
-
-    std::tie(rc, keyBlob, charBlob, lockedEntry) =
-        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-
-    auto dev = mKeyStore->getDevice(keyBlob);
-
-    dev->exportKey(std::move(lockedEntry), KeyFormat(format), clientId.getData(), appData.getData(),
-                   std::move(keyBlob), std::move(charBlob),
-                   [cb](ExportResult exportResult) { cb->onFinished(exportResult); });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::begin(const sp<IKeystoreOperationResultCallback>& cb,
-                              const sp<IBinder>& appToken, const String16& name, int32_t purpose,
-                              bool pruneable, const KeymasterArguments& params,
-                              const ::std::vector<uint8_t>& entropy, int32_t uid,
-                              int32_t* _aidl_return) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    uid_t targetUid = getEffectiveUid(uid);
-    if (!is_granted_to(callingUid, targetUid)) {
-        ALOGW("uid %d not permitted to act for uid %d in begin", callingUid, targetUid);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-    if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) {
-        ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid);
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-    if (!checkAllowedOperationParams(params.getParameters())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    String8 name8(name);
-    Blob keyBlob;
-    Blob charBlob;
-    LockedKeyBlobEntry lockedEntry;
-    ResponseCode rc;
-
-    std::tie(rc, keyBlob, charBlob, lockedEntry) =
-        mKeyStore->getKeyForName(name8, targetUid, TYPE_KEYMASTER_10);
-
-    if (rc == ResponseCode::LOCKED && keyBlob.isSuperEncrypted()) {
-        return AIDL_RETURN(ErrorCode::KEY_USER_NOT_AUTHENTICATED);
-    }
-    if (rc != ResponseCode::NO_ERROR) return AIDL_RETURN(rc);
-
-    auto dev = mKeyStore->getDevice(keyBlob);
-    AuthorizationSet opParams = params.getParameters();
-
-    dev->begin(std::move(lockedEntry), appToken, std::move(keyBlob), std::move(charBlob), pruneable,
-               static_cast<KeyPurpose>(purpose), std::move(opParams), entropy,
-               [this, cb, dev](OperationResult result_) {
-                   if (result_.resultCode.isOk() ||
-                       result_.resultCode == ResponseCode::OP_AUTH_NEEDED) {
-                       mKeyStore->addOperationDevice(result_.token, dev);
-                   }
-                   cb->onFinished(result_);
-               });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::update(const ::android::sp<IKeystoreOperationResultCallback>& cb,
-                               const ::android::sp<::android::IBinder>& token,
-                               const ::android::security::keymaster::KeymasterArguments& params,
-                               const ::std::vector<uint8_t>& input, int32_t* _aidl_return) {
-    if (!checkAllowedOperationParams(params.getParameters())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    auto dev = mKeyStore->getOperationDevice(token);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
-    }
-
-    dev->update(token, params.getParameters(), input, [this, cb, token](OperationResult result_) {
-        if (!result_.resultCode.isOk()) {
-            mKeyStore->removeOperationDevice(token);
-        }
-        cb->onFinished(result_);
-    });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::finish(const ::android::sp<IKeystoreOperationResultCallback>& cb,
-                               const ::android::sp<::android::IBinder>& token,
-                               const ::android::security::keymaster::KeymasterArguments& params,
-                               const ::std::vector<uint8_t>& input,
-                               const ::std::vector<uint8_t>& signature,
-                               const ::std::vector<uint8_t>& entropy, int32_t* _aidl_return) {
-    if (!checkAllowedOperationParams(params.getParameters())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    auto dev = mKeyStore->getOperationDevice(token);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
-    }
-
-    dev->finish(token, params.getParameters(), input, signature, entropy,
-                [this, cb, token](OperationResult result_) {
-                    mKeyStore->removeOperationDevice(token);
-                    cb->onFinished(result_);
-                });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::abort(const ::android::sp<IKeystoreResponseCallback>& cb,
-                              const ::android::sp<::android::IBinder>& token,
-                              int32_t* _aidl_return) {
-    auto dev = mKeyStore->getOperationDevice(token);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::INVALID_OPERATION_HANDLE);
-    }
-
-    dev->abort(token, [this, cb, token](KeyStoreServiceReturnCode rc) {
-        mKeyStore->removeOperationDevice(token);
-        cb->onFinished(rc);
-    });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVector,
-                                     int32_t* aidl_return) {
-
-    // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
-    // receive a HardwareAuthToken, rather than an opaque byte array.
-
-    if (!checkBinderPermission(P_ADD_AUTH)) {
-        ALOGW("addAuthToken: permission denied for %d", IPCThreadState::self()->getCallingUid());
-        *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
-        return Status::ok();
-    }
-    if (authTokenAsVector.size() != sizeof(hw_auth_token_t)) {
-        *aidl_return = KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT).getErrorCode();
-        return Status::ok();
-    }
-
-    hw_auth_token_t authToken;
-    memcpy(reinterpret_cast<void*>(&authToken), authTokenAsVector.data(), sizeof(hw_auth_token_t));
-    if (authToken.version != 0) {
-        *aidl_return = KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT).getErrorCode();
-        return Status::ok();
-    }
-
-    mKeyStore->getAuthTokenTable().AddAuthenticationToken(
-        hidlVec2AuthToken(hidl_vec<uint8_t>(authTokenAsVector)));
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::getTokensForCredstore(int64_t challenge, int64_t secureUserId,
-                                              int32_t authTokenMaxAgeMillis,
-                                              const ::android::sp<ICredstoreTokenCallback>& cb) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (callingUid != AID_CREDSTORE) {
-        return Status::fromServiceSpecificError(static_cast<int32_t>(0));
-    }
-
-    auto [err, authToken] = mKeyStore->getAuthTokenTable().FindAuthorizationForCredstore(
-        challenge, secureUserId, authTokenMaxAgeMillis);
-    // It's entirely possible we couldn't find an authToken (e.g. no user auth
-    // happened within the requested deadline) and in that case, we just
-    // callback immediately signaling success but just not returning any tokens.
-    if (err != AuthTokenTable::OK) {
-        cb->onFinished(true, {} /* serializedAuthToken */, {} /* serializedVerificationToken */);
-        return Status::ok();
-    }
-
-    // If we did find an authToken, get a verificationToken as well...
-    //
-    std::vector<uint8_t> serializedAuthToken = authToken2HidlVec(authToken);
-    std::vector<uint8_t> serializedVerificationToken;
-    std::shared_ptr<KeymasterWorker> dev = mKeyStore->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
-    if (!dev) {
-        LOG(ERROR) << "Unable to get KM device for SecurityLevel::TRUSTED_ENVIRONMENT";
-        dev = mKeyStore->getDevice(SecurityLevel::SOFTWARE);
-        if (!dev) {
-            LOG(ERROR) << "Unable to get KM device for SecurityLevel::SOFTWARE";
-            cb->onFinished(false, {}, {});
-            return Status::fromServiceSpecificError(static_cast<int32_t>(0));
-        }
-    }
-
-    dev->verifyAuthorization(
-        challenge, {} /* params */, authToken,
-        [serializedAuthToken, cb](KeyStoreServiceReturnCode rc, HardwareAuthToken,
-                                  VerificationToken verificationToken) {
-            if (rc != ErrorCode::OK) {
-                LOG(ERROR) << "verifyAuthorization failed, rc=" << rc;
-                cb->onFinished(false, {}, {});
-                return;
-            }
-            std::optional<std::vector<uint8_t>> serializedVerificationToken =
-                serializeVerificationToken(verificationToken);
-            if (!serializedVerificationToken) {
-                LOG(ERROR) << "Error serializing verificationToken";
-                cb->onFinished(false, {}, {});
-                return;
-            }
-            cb->onFinished(true, serializedAuthToken, serializedVerificationToken.value());
-        });
-
-    return Status::ok();
-}
-
-bool isDeviceIdAttestationRequested(const KeymasterArguments& params) {
-    const hardware::hidl_vec<KeyParameter>& paramsVec = params.getParameters();
-    for (size_t i = 0; i < paramsVec.size(); ++i) {
-        switch (paramsVec[i].tag) {
-        case Tag::ATTESTATION_ID_BRAND:
-        case Tag::ATTESTATION_ID_DEVICE:
-        case Tag::ATTESTATION_ID_MANUFACTURER:
-        case Tag::ATTESTATION_ID_MODEL:
-        case Tag::ATTESTATION_ID_PRODUCT:
-        case Tag::ATTESTATION_ID_IMEI:
-        case Tag::ATTESTATION_ID_MEID:
-        case Tag::ATTESTATION_ID_SERIAL:
-            return true;
-        default:
-            continue;
-        }
-    }
-    return false;
-}
-
-Status KeyStoreService::attestKey(
-    const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
-    const String16& name, const KeymasterArguments& params, int32_t* _aidl_return) {
-    // check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
-    if (!checkAllowedOperationParams(params.getParameters())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-
-    if (isDeviceIdAttestationRequested(params) && (get_app_id(callingUid) != AID_SYSTEM)) {
-        return AIDL_RETURN(KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT));
-    }
-
-    AuthorizationSet mutableParams = params.getParameters();
-    KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
-
-    auto logErrorOnReturn = android::base::make_scope_guard(
-        [&] { logKeystoreKeyAttestationEvent(false /*wasSuccessful*/, rc.getErrorCode()); });
-
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-
-    String8 name8(name);
-    Blob keyBlob;
-    Blob charBlob;
-    LockedKeyBlobEntry lockedEntry;
-
-    std::tie(rc, keyBlob, charBlob, lockedEntry) =
-        mKeyStore->getKeyForName(name8, callingUid, TYPE_KEYMASTER_10);
-
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-
-    logErrorOnReturn.Disable();
-
-    auto dev = mKeyStore->getDevice(keyBlob);
-    auto hidlKey = blob2hidlVec(keyBlob);
-    dev->attestKey(
-        std::move(hidlKey), mutableParams.hidl_data(),
-        [dev, cb](Return<void> rc,
-                  std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
-            auto& [ret, certChain] = hidlResult;
-            if (!rc.isOk()) {
-                logKeystoreKeyAttestationEvent(false /*wasSuccessful*/,
-                                               static_cast<int32_t>(ResponseCode::SYSTEM_ERROR));
-                cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
-            } else if (ret != ErrorCode::OK) {
-                KeyStoreServiceReturnCode ksrc(ret);
-                logKeystoreKeyAttestationEvent(false /*wasSuccessful*/, ksrc.getErrorCode());
-                dev->logIfKeymasterVendorError(ret);
-                cb->onFinished(ksrc, {});
-            } else {
-                KeyStoreServiceReturnCode ksrc(ret);
-                logKeystoreKeyAttestationEvent(true /*wasSuccessful*/, ksrc.getErrorCode());
-                cb->onFinished(ksrc, KeymasterCertificateChain(std::move(certChain)));
-            }
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-// My IDE defines "CAPTURE_MOVE(x) x" because it does not understand generalized lambda captures.
-// It should never be redefined by a build system though.
-#ifndef CAPTURE_MOVE
-#define CAPTURE_MOVE(x) x = std::move(x)
-#endif
-
-Status KeyStoreService::attestDeviceIds(
-    const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
-    const KeymasterArguments& params, int32_t* _aidl_return) {
-    // check null output if method signature is updated and return ErrorCode::OUTPUT_PARAMETER_NULL
-
-    if (!checkAllowedOperationParams(params.getParameters())) {
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    if (!isDeviceIdAttestationRequested(params)) {
-        // There is an attestKey() method for attesting keys without device ID attestation.
-        return AIDL_RETURN(ErrorCode::INVALID_ARGUMENT);
-    }
-
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
-    if (binder == nullptr) {
-        return AIDL_RETURN(ErrorCode::CANNOT_ATTEST_IDS);
-    }
-    if (!interface_cast<IPermissionController>(binder)->checkPermission(
-            String16("android.permission.READ_PRIVILEGED_PHONE_STATE"),
-            IPCThreadState::self()->getCallingPid(), callingUid)) {
-        return AIDL_RETURN(ErrorCode::CANNOT_ATTEST_IDS);
-    }
-
-    AuthorizationSet mutableParams = params.getParameters();
-    KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-
-    // Generate temporary key.
-    auto dev = mKeyStore->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
-
-    if (!dev) {
-        return AIDL_RETURN(ResponseCode::SYSTEM_ERROR);
-    }
-
-
-    AuthorizationSet keyCharacteristics;
-    keyCharacteristics.push_back(TAG_PURPOSE, KeyPurpose::VERIFY);
-    keyCharacteristics.push_back(TAG_ALGORITHM, Algorithm::EC);
-    keyCharacteristics.push_back(TAG_DIGEST, Digest::SHA_2_256);
-    keyCharacteristics.push_back(TAG_NO_AUTH_REQUIRED);
-    keyCharacteristics.push_back(TAG_EC_CURVE, EcCurve::P_256);
-
-    std::promise<KeyStoreServiceReturnCode> resultPromise;
-    auto resultFuture = resultPromise.get_future();
-
-    dev->generateKey(
-        keyCharacteristics.hidl_data(),
-        [cb, dev, CAPTURE_MOVE(mutableParams)](
-            Return<void> rc,
-            std::tuple<ErrorCode, ::std::vector<uint8_t>, KeyCharacteristics>&& hidlResult) {
-            auto& [ret, hidlKeyBlob_, dummyCharacteristics] = hidlResult;
-            auto hidlKeyBlob = std::move(hidlKeyBlob_);
-            if (!rc.isOk()) {
-                cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
-                return;
-            }
-            if (ret != ErrorCode::OK) {
-                dev->logIfKeymasterVendorError(ret);
-                cb->onFinished(KeyStoreServiceReturnCode(ret), {});
-                return;
-            }
-            dev->attestKey(
-                hidlKeyBlob, mutableParams.hidl_data(),
-                [cb, dev,
-                 hidlKeyBlob](Return<void> rc,
-                              std::tuple<ErrorCode, hidl_vec<hidl_vec<uint8_t>>>&& hidlResult) {
-                    auto& [ret, certChain] = hidlResult;
-                    // schedule temp key for deletion
-                    dev->deleteKey(std::move(hidlKeyBlob), [dev](Return<ErrorCode> rc) {
-                        // log error but don't return an error
-                        KS_HANDLE_HIDL_ERROR(dev, rc);
-                    });
-                    if (!rc.isOk()) {
-                        cb->onFinished(KeyStoreServiceReturnCode(ResponseCode::SYSTEM_ERROR), {});
-                        return;
-                    }
-                    if (ret == ErrorCode::OK) {
-                        cb->onFinished(
-                            KeyStoreServiceReturnCode(ret),
-                            ::android::security::keymaster::KeymasterCertificateChain(certChain));
-                    } else {
-                        dev->logIfKeymasterVendorError(ret);
-                        cb->onFinished(KeyStoreServiceReturnCode(ret), {});
-                    }
-                });
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::onDeviceOffBody(int32_t* aidl_return) {
-    // TODO(tuckeris): add permission check.  This should be callable from ClockworkHome only.
-    mKeyStore->getAuthTokenTable().onDeviceOffBody();
-    *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
-    return Status::ok();
-}
-
-Status KeyStoreService::importWrappedKey(
-    const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
-    const ::android::String16& wrappedKeyAlias, const ::std::vector<uint8_t>& wrappedKey,
-    const ::android::String16& wrappingKeyAlias, const ::std::vector<uint8_t>& maskingKey,
-    const KeymasterArguments& params, int64_t rootSid, int64_t fingerprintSid,
-    int32_t* _aidl_return) {
-
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-
-    if (!checkBinderPermission(P_INSERT, callingUid)) {
-        return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-    }
-
-    String8 wrappingKeyName8(wrappingKeyAlias);
-
-    KeyStoreServiceReturnCode rc;
-    Blob wrappingKeyBlob;
-    Blob wrappingCharBlob;
-    LockedKeyBlobEntry wrappingLockedEntry;
-
-    std::tie(rc, wrappingKeyBlob, wrappingCharBlob, wrappingLockedEntry) =
-        mKeyStore->getKeyForName(wrappingKeyName8, callingUid, TYPE_KEYMASTER_10);
-    if (!rc.isOk()) {
-        return AIDL_RETURN(rc);
-    }
-
-    String8 wrappedKeyName8(wrappedKeyAlias);
-    auto wrappedLockedEntry =
-        mKeyStore->getLockedBlobEntryIfNotExists(wrappedKeyName8.string(), callingUid);
-    if (!wrappedLockedEntry) {
-        return AIDL_RETURN(ResponseCode::KEY_ALREADY_EXISTS);
-    }
-
-    SecurityLevel securityLevel = wrappingKeyBlob.getSecurityLevel();
-    auto dev = mKeyStore->getDevice(securityLevel);
-    if (!dev) {
-        return AIDL_RETURN(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
-    }
-
-    dev->importWrappedKey(
-        std::move(wrappingLockedEntry), std::move(wrappedLockedEntry), wrappedKey, maskingKey,
-        params.getParameters(), std::move(wrappingKeyBlob), std::move(wrappingCharBlob), rootSid,
-        fingerprintSid, [cb](KeyStoreServiceReturnCode rc, KeyCharacteristics keyCharacteristics) {
-            cb->onFinished(rc,
-                           ::android::security::keymaster::KeyCharacteristics(keyCharacteristics));
-        });
-
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-Status KeyStoreService::presentConfirmationPrompt(const sp<IBinder>& listener,
-                                                  const String16& promptText,
-                                                  const ::std::vector<uint8_t>& extraData,
-                                                  const String16& locale, int32_t uiOptionsAsFlags,
-                                                  int32_t* aidl_return) {
-    return mKeyStore->getConfirmationManager().presentConfirmationPrompt(
-        listener, promptText, extraData, locale, uiOptionsAsFlags, aidl_return);
-}
-
-Status KeyStoreService::cancelConfirmationPrompt(const sp<IBinder>& listener,
-                                                 int32_t* aidl_return) {
-    return mKeyStore->getConfirmationManager().cancelConfirmationPrompt(listener, aidl_return);
-}
-
-Status KeyStoreService::isConfirmationPromptSupported(bool* aidl_return) {
-    return mKeyStore->getConfirmationManager().isConfirmationPromptSupported(aidl_return);
-}
-
-/**
- * Get the effective target uid for a binder operation that takes an
- * optional uid as the target.
- */
-uid_t KeyStoreService::getEffectiveUid(int32_t targetUid) {
-    if (targetUid == UID_SELF) {
-        return IPCThreadState::self()->getCallingUid();
-    }
-    return static_cast<uid_t>(targetUid);
-}
-
-/**
- * Check if the caller of the current binder method has the required
- * permission and if acting on other uids the grants to do so.
- */
-bool KeyStoreService::checkBinderPermission(perm_t permission, int32_t targetUid) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    pid_t spid = IPCThreadState::self()->getCallingPid();
-    const char* ssid = IPCThreadState::self()->getCallingSid();
-    if (!has_permission(callingUid, permission, spid, ssid)) {
-        ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
-        return false;
-    }
-    if (!is_granted_to(callingUid, getEffectiveUid(targetUid))) {
-        ALOGW("uid %d not granted to act for %d", callingUid, targetUid);
-        return false;
-    }
-    return true;
-}
-
-/**
- * Check if the caller of the current binder method has the required
- * permission and the target uid is the caller or the caller is system.
- */
-bool KeyStoreService::checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    pid_t spid = IPCThreadState::self()->getCallingPid();
-    const char* ssid = IPCThreadState::self()->getCallingSid();
-    if (!has_permission(callingUid, permission, spid, ssid)) {
-        ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
-        return false;
-    }
-    return getEffectiveUid(targetUid) == callingUid || callingUid == AID_SYSTEM;
-}
-
-/**
- * Check if the caller of the current binder method has the required
- * permission or the target of the operation is the caller's uid. This is
- * for operation where the permission is only for cross-uid activity and all
- * uids are allowed to act on their own (ie: clearing all entries for a
- * given uid).
- */
-bool KeyStoreService::checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid) {
-    uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (getEffectiveUid(targetUid) == callingUid) {
-        return true;
-    } else {
-        return checkBinderPermission(permission, targetUid);
-    }
-}
-
-/**
- * Helper method to check that the caller has the required permission as
- * well as the keystore is in the unlocked state if checkUnlocked is true.
- *
- * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and
- * otherwise the state of keystore when not unlocked and checkUnlocked is
- * true.
- */
-KeyStoreServiceReturnCode
-KeyStoreService::checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid,
-                                                       bool checkUnlocked) {
-    if (!checkBinderPermission(permission, targetUid)) {
-        return ResponseCode::PERMISSION_DENIED;
-    }
-    State state = mKeyStore->getState(get_user_id(getEffectiveUid(targetUid)));
-    if (checkUnlocked && !isKeystoreUnlocked(state)) {
-        // All State values coincide with ResponseCodes
-        return static_cast<ResponseCode>(state);
-    }
-
-    return ResponseCode::NO_ERROR;
-}
-
-bool KeyStoreService::isKeystoreUnlocked(State state) {
-    switch (state) {
-    case ::STATE_NO_ERROR:
-        return true;
-    case ::STATE_UNINITIALIZED:
-    case ::STATE_LOCKED:
-        return false;
-    }
-    return false;
-}
-
-/**
- * Check that all KeyParameters provided by the application are allowed. Any parameter that keystore
- * adds itself should be disallowed here.
- */
-bool KeyStoreService::checkAllowedOperationParams(const hidl_vec<KeyParameter>& params) {
-    for (size_t i = 0; i < params.size(); ++i) {
-        switch (params[i].tag) {
-        case Tag::ATTESTATION_APPLICATION_ID:
-        case Tag::RESET_SINCE_ID_ROTATION:
-            return false;
-        default:
-            break;
-        }
-    }
-    return true;
-}
-
-Status KeyStoreService::onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
-                                                    int32_t* _aidl_return) {
-    if (isShowing) {
-        if (!checkBinderPermission(P_LOCK, UID_SELF)) {
-            LOG(WARNING) << "onKeyguardVisibilityChanged called with isShowing == true but "
-                            "without LOCK permission";
-            return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-        }
-    } else {
-        if (!checkBinderPermission(P_UNLOCK, UID_SELF)) {
-            LOG(WARNING) << "onKeyguardVisibilityChanged called with isShowing == false but "
-                            "without UNLOCK permission";
-            return AIDL_RETURN(ResponseCode::PERMISSION_DENIED);
-        }
-    }
-    mKeyStore->getEnforcementPolicy().set_device_locked(isShowing, userId);
-    return AIDL_RETURN(ResponseCode::NO_ERROR);
-}
-
-}  // namespace keystore
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
deleted file mode 100644
index 5fdddb9..0000000
--- a/keystore/key_store_service.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 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_KEYSTORE_SERVICE_H_
-#define KEYSTORE_KEYSTORE_SERVICE_H_
-
-#include <android/security/keystore/BnKeystoreService.h>
-
-#include "auth_token_table.h"
-#include "confirmation_manager.h"
-
-#include "KeyStore.h"
-#include "keystore_keymaster_enforcement.h"
-#include "operation.h"
-#include "permissions.h"
-
-#include <keystore/ExportResult.h>
-#include <keystore/KeyCharacteristics.h>
-#include <keystore/KeymasterArguments.h>
-#include <keystore/KeymasterBlob.h>
-#include <keystore/KeymasterCertificateChain.h>
-#include <keystore/OperationResult.h>
-#include <keystore/keystore_return_types.h>
-
-#include <mutex>
-
-namespace keystore {
-
-// Class provides implementation for generated BnKeystoreService.h based on
-// gen/aidl/android/security/BnKeystoreService.h generated from
-// java/android/security/IKeystoreService.aidl Note that all generated methods return binder::Status
-// and use last arguments to send actual result to the caller. Private methods don't need to handle
-// binder::Status. Input parameters cannot be null unless annotated with @nullable in .aidl file.
-class KeyStoreService : public android::security::keystore::BnKeystoreService {
-  public:
-    explicit KeyStoreService(sp<KeyStore> keyStore) : mKeyStore(keyStore) {}
-    virtual ~KeyStoreService() = default;
-
-    void binderDied(const android::wp<android::IBinder>& who);
-
-    ::android::binder::Status getState(int32_t userId, int32_t* _aidl_return) override;
-    ::android::binder::Status get(const ::android::String16& name, int32_t uid,
-                                  ::std::vector<uint8_t>* _aidl_return) override;
-    ::android::binder::Status insert(const ::android::String16& name,
-                                     const ::std::vector<uint8_t>& item, int32_t uid, int32_t flags,
-                                     int32_t* _aidl_return) override;
-    ::android::binder::Status del(const ::android::String16& name, int32_t uid,
-                                  int32_t* _aidl_return) override;
-    ::android::binder::Status exist(const ::android::String16& name, int32_t uid,
-                                    int32_t* _aidl_return) override;
-    ::android::binder::Status list(const ::android::String16& namePrefix, int32_t uid,
-                                   ::std::vector<::android::String16>* _aidl_return) override;
-    ::android::binder::Status listUidsOfAuthBoundKeys(std::vector<::std::string>* uids,
-                                                      int32_t* _aidl_return) override;
-
-    ::android::binder::Status onUserPasswordChanged(int32_t userId,
-                                                    const ::android::String16& newPassword,
-                                                    int32_t* _aidl_return) override;
-    ::android::binder::Status lock(int32_t userId, int32_t* _aidl_return) override;
-    ::android::binder::Status unlock(int32_t userId, const ::android::String16& userPassword,
-                                     int32_t* _aidl_return) override;
-    ::android::binder::Status isEmpty(int32_t userId, int32_t* _aidl_return) override;
-    ::android::binder::Status grant(const ::android::String16& name, int32_t granteeUid,
-                                    ::android::String16* _aidl_return) override;
-    ::android::binder::Status ungrant(const ::android::String16& name, int32_t granteeUid,
-                                      int32_t* _aidl_return) override;
-    ::android::binder::Status getmtime(const ::android::String16& name, int32_t uid,
-                                       int64_t* _aidl_return) override;
-    ::android::binder::Status is_hardware_backed(const ::android::String16& string,
-                                                 int32_t* _aidl_return) override;
-    ::android::binder::Status clear_uid(int64_t uid, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    addRngEntropy(const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
-                  const ::std::vector<uint8_t>& data, int32_t flags,
-                  int32_t* _aidl_return) override;
-    ::android::binder::Status generateKey(
-        const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
-        const ::android::String16& alias,
-        const ::android::security::keymaster::KeymasterArguments& arguments,
-        const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t flags,
-        int32_t* _aidl_return) override;
-    ::android::binder::Status getKeyCharacteristics(
-        const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
-        const ::android::String16& alias,
-        const ::android::security::keymaster::KeymasterBlob& clientId,
-        const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
-        int32_t* _aidl_return) override;
-    ::android::binder::Status importKey(
-        const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
-        const ::android::String16& alias,
-        const ::android::security::keymaster::KeymasterArguments& arguments, int32_t format,
-        const ::std::vector<uint8_t>& keyData, int32_t uid, int32_t flags,
-        int32_t* _aidl_return) override;
-    ::android::binder::Status
-    exportKey(const ::android::sp<::android::security::keystore::IKeystoreExportKeyCallback>& cb,
-              const ::android::String16& alias, int32_t format,
-              const ::android::security::keymaster::KeymasterBlob& clientId,
-              const ::android::security::keymaster::KeymasterBlob& appId, int32_t uid,
-              int32_t* _aidl_return) override;
-    ::android::binder::Status
-    begin(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
-          const ::android::sp<::android::IBinder>& appToken, const ::android::String16& alias,
-          int32_t purpose, bool pruneable,
-          const ::android::security::keymaster::KeymasterArguments& params,
-          const ::std::vector<uint8_t>& entropy, int32_t uid, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    update(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
-           const ::android::sp<::android::IBinder>& token,
-           const ::android::security::keymaster::KeymasterArguments& params,
-           const ::std::vector<uint8_t>& input, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    finish(const ::android::sp<::android::security::keystore::IKeystoreOperationResultCallback>& cb,
-           const ::android::sp<::android::IBinder>& token,
-           const ::android::security::keymaster::KeymasterArguments& params,
-           const ::std::vector<uint8_t>& input, const ::std::vector<uint8_t>& signature,
-           const ::std::vector<uint8_t>& entropy, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    abort(const ::android::sp<::android::security::keystore::IKeystoreResponseCallback>& cb,
-          const ::android::sp<::android::IBinder>& token, int32_t* _aidl_return) override;
-    ::android::binder::Status addAuthToken(const ::std::vector<uint8_t>& authToken,
-                                           int32_t* _aidl_return) override;
-    ::android::binder::Status getTokensForCredstore(
-        int64_t challenge, int64_t secureUserId, int32_t authTokenMaxAge,
-        const ::android::sp<::android::security::keystore::ICredstoreTokenCallback>& cb) override;
-    ::android::binder::Status onUserAdded(int32_t userId, int32_t parentId,
-                                          int32_t* _aidl_return) override;
-    ::android::binder::Status onUserRemoved(int32_t userId, int32_t* _aidl_return) override;
-    ::android::binder::Status attestKey(
-        const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
-        const ::android::String16& alias,
-        const ::android::security::keymaster::KeymasterArguments& params,
-        int32_t* _aidl_return) override;
-    ::android::binder::Status attestDeviceIds(
-        const ::android::sp<::android::security::keystore::IKeystoreCertificateChainCallback>& cb,
-        const ::android::security::keymaster::KeymasterArguments& params,
-        int32_t* _aidl_return) override;
-    ::android::binder::Status onDeviceOffBody(int32_t* _aidl_return) override;
-
-    ::android::binder::Status importWrappedKey(
-        const ::android::sp<::android::security::keystore::IKeystoreKeyCharacteristicsCallback>& cb,
-        const ::android::String16& wrappedKeyAlias, const ::std::vector<uint8_t>& wrappedKey,
-        const ::android::String16& wrappingKeyAlias, const ::std::vector<uint8_t>& maskingKey,
-        const ::android::security::keymaster::KeymasterArguments& params, int64_t rootSid,
-        int64_t fingerprintSid, int32_t* _aidl_return) override;
-
-    ::android::binder::Status presentConfirmationPrompt(
-        const ::android::sp<::android::IBinder>& listener, const ::android::String16& promptText,
-        const ::std::vector<uint8_t>& extraData, const ::android::String16& locale,
-        int32_t uiOptionsAsFlags, int32_t* _aidl_return) override;
-    ::android::binder::Status
-    cancelConfirmationPrompt(const ::android::sp<::android::IBinder>& listener,
-                             int32_t* _aidl_return) override;
-    ::android::binder::Status isConfirmationPromptSupported(bool* _aidl_return) override;
-
-    ::android::binder::Status onKeyguardVisibilityChanged(bool isShowing, int32_t userId,
-                                                          int32_t* _aidl_return) override;
-
-  private:
-    static const int32_t UID_SELF = -1;
-
-    /**
-     * Get the effective target uid for a binder operation that takes an
-     * optional uid as the target.
-     */
-    uid_t getEffectiveUid(int32_t targetUid);
-
-    /**
-     * Check if the caller of the current binder method has the required
-     * permission and if acting on other uids the grants to do so.
-     */
-    bool checkBinderPermission(perm_t permission, int32_t targetUid = UID_SELF);
-
-    /**
-     * Check if the caller of the current binder method has the required
-     * permission and the target uid is the caller or the caller is system.
-     */
-    bool checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid);
-
-    /**
-     * Check if the caller of the current binder method has the required
-     * permission or the target of the operation is the caller's uid. This is
-     * for operation where the permission is only for cross-uid activity and all
-     * uids are allowed to act on their own (ie: clearing all entries for a
-     * given uid).
-     */
-    bool checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid);
-
-    /**
-     * Helper method to check that the caller has the required permission as
-     * well as the keystore is in the unlocked state if checkUnlocked is true.
-     *
-     * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and
-     * otherwise the state of keystore when not unlocked and checkUnlocked is
-     * true.
-     */
-    KeyStoreServiceReturnCode checkBinderPermissionAndKeystoreState(perm_t permission,
-                                                                    int32_t targetUid = -1,
-                                                                    bool checkUnlocked = true);
-
-    bool isKeystoreUnlocked(State state);
-
-    /**
-     * Check that all keymaster_key_param_t's provided by the application are
-     * allowed. Any parameter that keystore adds itself should be disallowed here.
-     */
-    bool checkAllowedOperationParams(const hidl_vec<KeyParameter>& params);
-
-    void addLegacyBeginParams(const android::String16& name, AuthorizationSet* params);
-
-    KeyStoreServiceReturnCode doLegacySignVerify(const android::String16& name,
-                                                 const hidl_vec<uint8_t>& data,
-                                                 hidl_vec<uint8_t>* out,
-                                                 const hidl_vec<uint8_t>& signature,
-                                                 KeyPurpose purpose);
-
-    /**
-     * Adds a Confirmation Token to the key parameters if needed.
-     */
-    void appendConfirmationTokenIfNeeded(const KeyCharacteristics& keyCharacteristics,
-                                         std::vector<KeyParameter>* params);
-
-    sp<KeyStore> mKeyStore;
-};
-
-};  // namespace keystore
-
-#endif  // KEYSTORE_KEYSTORE_SERVICE_H_
diff --git a/keystore/keyblob_utils.cpp b/keystore/keyblob_utils.cpp
deleted file mode 100644
index 6c2fac9..0000000
--- a/keystore/keyblob_utils.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2012 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 <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <keystore/keystore.h>
-
-/**
- * When a key is being migrated from a software keymaster implementation
- * to a hardware keymaster implementation, the first 4 bytes of the key_blob
- * given to the hardware implementation will be equal to SOFT_KEY_MAGIC.
- * The hardware implementation should import these PKCS#8 format keys which
- * are encoded like this:
- *
- * 4-byte SOFT_KEY_MAGIC
- *
- * 4-byte 32-bit integer big endian for public_key_length. This may be zero
- *     length which indicates the public key should be derived from the
- *     private key.
- *
- * public_key_length bytes of public key (may be empty)
- *
- * 4-byte 32-bit integer big endian for private_key_length
- *
- * private_key_length bytes of private key
- */
-static const uint8_t SOFT_KEY_MAGIC[] = { 'P', 'K', '#', '8' };
-
-size_t get_softkey_header_size() {
-    return sizeof(SOFT_KEY_MAGIC);
-}
-
-uint8_t* add_softkey_header(uint8_t* key_blob, size_t key_blob_length) {
-    if (key_blob_length < sizeof(SOFT_KEY_MAGIC)) {
-        return nullptr;
-    }
-
-    memcpy(key_blob, SOFT_KEY_MAGIC, sizeof(SOFT_KEY_MAGIC));
-
-    return key_blob + sizeof(SOFT_KEY_MAGIC);
-}
-
-bool is_softkey(const uint8_t* key_blob, const size_t key_blob_length) {
-    if (key_blob_length < sizeof(SOFT_KEY_MAGIC)) {
-        return false;
-    }
-
-    return !memcmp(key_blob, SOFT_KEY_MAGIC, sizeof(SOFT_KEY_MAGIC));
-}
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
deleted file mode 100644
index a17cd94..0000000
--- a/keystore/keymaster_enforcement.cpp
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#define LOG_TAG "keystore"
-
-#include "keymaster_enforcement.h"
-
-#include <assert.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>
-
-#include <openssl/evp.h>
-
-#include <hardware/hw_auth_token.h>
-#include <log/log.h>
-
-#include <list>
-
-#include <keystore/keystore_hidl_support.h>
-
-namespace keystore {
-
-bool is_public_key_algorithm(const AuthorizationSet& auth_set) {
-    auto algorithm = auth_set.GetTagValue(TAG_ALGORITHM);
-    return algorithm.isOk() &&
-           (algorithm.value() == Algorithm::RSA || algorithm.value() == Algorithm::EC);
-}
-
-static ErrorCode authorized_purpose(const KeyPurpose purpose, const AuthorizationSet& auth_set) {
-    switch (purpose) {
-    case KeyPurpose::VERIFY:
-    case KeyPurpose::ENCRYPT:
-    case KeyPurpose::SIGN:
-    case KeyPurpose::DECRYPT:
-        if (auth_set.Contains(TAG_PURPOSE, purpose)) return ErrorCode::OK;
-        return ErrorCode::INCOMPATIBLE_PURPOSE;
-
-    default:
-        return ErrorCode::UNSUPPORTED_PURPOSE;
-    }
-}
-
-inline bool is_origination_purpose(KeyPurpose purpose) {
-    return purpose == KeyPurpose::ENCRYPT || purpose == KeyPurpose::SIGN;
-}
-
-inline bool is_usage_purpose(KeyPurpose purpose) {
-    return purpose == KeyPurpose::DECRYPT || purpose == KeyPurpose::VERIFY;
-}
-
-KeymasterEnforcement::KeymasterEnforcement(uint32_t max_access_time_map_size,
-                                           uint32_t max_access_count_map_size)
-    : access_time_map_(max_access_time_map_size), access_count_map_(max_access_count_map_size) {}
-
-KeymasterEnforcement::~KeymasterEnforcement() {
-}
-
-ErrorCode KeymasterEnforcement::AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
-                                                   const AuthorizationSet& auth_set,
-                                                   const AuthorizationSet& operation_params,
-                                                   const HardwareAuthToken& auth_token,
-                                                   uint64_t op_handle, bool is_begin_operation) {
-    if (is_public_key_algorithm(auth_set)) {
-        switch (purpose) {
-        case KeyPurpose::ENCRYPT:
-        case KeyPurpose::VERIFY:
-            /* Public key operations are always authorized. */
-            return ErrorCode::OK;
-
-        case KeyPurpose::DECRYPT:
-        case KeyPurpose::SIGN:
-            break;
-
-        case KeyPurpose::WRAP_KEY:
-            return ErrorCode::INCOMPATIBLE_PURPOSE;
-        };
-    };
-
-    if (is_begin_operation)
-        return AuthorizeBegin(purpose, keyid, auth_set, operation_params, auth_token);
-    else
-        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
-}
-
-// For update and finish the only thing to check is user authentication, and then only if it's not
-// timeout-based.
-ErrorCode KeymasterEnforcement::AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
-                                                        const HardwareAuthToken& auth_token,
-                                                        uint64_t op_handle) {
-    int auth_type_index = -1;
-    for (size_t pos = 0; pos < auth_set.size(); ++pos) {
-        switch (auth_set[pos].tag) {
-        case Tag::NO_AUTH_REQUIRED:
-        case Tag::AUTH_TIMEOUT:
-            // If no auth is required or if auth is timeout-based, we have nothing to check.
-            return ErrorCode::OK;
-
-        case Tag::USER_AUTH_TYPE:
-            auth_type_index = pos;
-            break;
-
-        default:
-            break;
-        }
-    }
-
-    // Note that at this point we should be able to assume that authentication is required, because
-    // authentication is required if KM_TAG_NO_AUTH_REQUIRED is absent.  However, there are legacy
-    // keys which have no authentication-related tags, so we assume that absence is equivalent to
-    // presence of KM_TAG_NO_AUTH_REQUIRED.
-    //
-    // So, if we found KM_TAG_USER_AUTH_TYPE or if we find KM_TAG_USER_SECURE_ID then authentication
-    // is required.  If we find neither, then we assume authentication is not required and return
-    // success.
-    bool authentication_required = (auth_type_index != -1);
-    for (auto& param : auth_set) {
-        auto user_secure_id = authorizationValue(TAG_USER_SECURE_ID, param);
-        if (user_secure_id.isOk()) {
-            authentication_required = true;
-            int auth_timeout_index = -1;
-            if (auth_token.mac.size() &&
-                AuthTokenMatches(auth_set, auth_token, user_secure_id.value(), auth_type_index,
-                                 auth_timeout_index, op_handle, false /* is_begin_operation */))
-                return ErrorCode::OK;
-        }
-    }
-
-    if (authentication_required) return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
-
-    return ErrorCode::OK;
-}
-
-ErrorCode KeymasterEnforcement::AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
-                                               const AuthorizationSet& auth_set,
-                                               const AuthorizationSet& operation_params,
-                                               NullOr<const HardwareAuthToken&> auth_token) {
-    // Find some entries that may be needed to handle KM_TAG_USER_SECURE_ID
-    int auth_timeout_index = -1;
-    int auth_type_index = -1;
-    int no_auth_required_index = -1;
-    for (size_t pos = 0; pos < auth_set.size(); ++pos) {
-        switch (auth_set[pos].tag) {
-        case Tag::AUTH_TIMEOUT:
-            auth_timeout_index = pos;
-            break;
-        case Tag::USER_AUTH_TYPE:
-            auth_type_index = pos;
-            break;
-        case Tag::NO_AUTH_REQUIRED:
-            no_auth_required_index = pos;
-            break;
-        default:
-            break;
-        }
-    }
-
-    ErrorCode error = authorized_purpose(purpose, auth_set);
-    if (error != ErrorCode::OK) return error;
-
-    // If successful, and if key has a min time between ops, this will be set to the time limit
-    uint32_t min_ops_timeout = UINT32_MAX;
-
-    bool update_access_count = false;
-    bool caller_nonce_authorized_by_key = false;
-    bool authentication_required = false;
-    bool auth_token_matched = false;
-    bool unlocked_device_required = false;
-    int32_t user_id = -1;
-
-    for (auto& param : auth_set) {
-
-        // KM_TAG_PADDING_OLD and KM_TAG_DIGEST_OLD aren't actually members of the enum, so we can't
-        // switch on them.  There's nothing to validate for them, though, so just ignore them.
-        if (int32_t(param.tag) == KM_TAG_PADDING_OLD || int32_t(param.tag) == KM_TAG_DIGEST_OLD)
-            continue;
-
-        switch (param.tag) {
-
-        case Tag::ACTIVE_DATETIME: {
-            auto date = authorizationValue(TAG_ACTIVE_DATETIME, param);
-            if (date.isOk() && !activation_date_valid(date.value()))
-                return ErrorCode::KEY_NOT_YET_VALID;
-            break;
-        }
-        case Tag::ORIGINATION_EXPIRE_DATETIME: {
-            auto date = authorizationValue(TAG_ORIGINATION_EXPIRE_DATETIME, param);
-            if (is_origination_purpose(purpose) && date.isOk() &&
-                expiration_date_passed(date.value()))
-                return ErrorCode::KEY_EXPIRED;
-            break;
-        }
-        case Tag::USAGE_EXPIRE_DATETIME: {
-            auto date = authorizationValue(TAG_USAGE_EXPIRE_DATETIME, param);
-            if (is_usage_purpose(purpose) && date.isOk() && expiration_date_passed(date.value()))
-                return ErrorCode::KEY_EXPIRED;
-            break;
-        }
-        case Tag::MIN_SECONDS_BETWEEN_OPS: {
-            auto min_ops_timeout = authorizationValue(TAG_MIN_SECONDS_BETWEEN_OPS, param);
-            if (min_ops_timeout.isOk() && !MinTimeBetweenOpsPassed(min_ops_timeout.value(), keyid))
-                return ErrorCode::KEY_RATE_LIMIT_EXCEEDED;
-            break;
-        }
-        case Tag::MAX_USES_PER_BOOT: {
-            auto max_users = authorizationValue(TAG_MAX_USES_PER_BOOT, param);
-            update_access_count = true;
-            if (max_users.isOk() && !MaxUsesPerBootNotExceeded(keyid, max_users.value()))
-                return ErrorCode::KEY_MAX_OPS_EXCEEDED;
-            break;
-        }
-        case Tag::USER_SECURE_ID:
-            if (no_auth_required_index != -1) {
-                // Key has both KM_TAG_USER_SECURE_ID and KM_TAG_NO_AUTH_REQUIRED
-                return ErrorCode::INVALID_KEY_BLOB;
-            }
-
-            if (auth_timeout_index != -1) {
-                auto secure_id = authorizationValue(TAG_USER_SECURE_ID, param);
-                authentication_required = true;
-                if (secure_id.isOk() && auth_token.isOk() &&
-                    AuthTokenMatches(auth_set, auth_token.value(), secure_id.value(),
-                                     auth_type_index, auth_timeout_index, 0 /* op_handle */,
-                                     true /* is_begin_operation */))
-                    auth_token_matched = true;
-            }
-            break;
-
-        case Tag::USER_ID:
-            user_id = authorizationValue(TAG_USER_ID, param).value();
-            break;
-
-        case Tag::CALLER_NONCE:
-            caller_nonce_authorized_by_key = true;
-            break;
-
-        case Tag::UNLOCKED_DEVICE_REQUIRED:
-            unlocked_device_required = true;
-            break;
-
-        /* Tags should never be in key auths. */
-        case Tag::INVALID:
-        case Tag::ROOT_OF_TRUST:
-        case Tag::APPLICATION_DATA:
-        case Tag::ATTESTATION_CHALLENGE:
-        case Tag::ATTESTATION_APPLICATION_ID:
-        case Tag::ATTESTATION_ID_BRAND:
-        case Tag::ATTESTATION_ID_DEVICE:
-        case Tag::ATTESTATION_ID_PRODUCT:
-        case Tag::ATTESTATION_ID_SERIAL:
-        case Tag::ATTESTATION_ID_IMEI:
-        case Tag::ATTESTATION_ID_MEID:
-        case Tag::ATTESTATION_ID_MANUFACTURER:
-        case Tag::ATTESTATION_ID_MODEL:
-            return ErrorCode::INVALID_KEY_BLOB;
-
-        /* Tags used for cryptographic parameters in keygen.  Nothing to enforce. */
-        case Tag::PURPOSE:
-        case Tag::ALGORITHM:
-        case Tag::KEY_SIZE:
-        case Tag::BLOCK_MODE:
-        case Tag::DIGEST:
-        case Tag::MAC_LENGTH:
-        case Tag::PADDING:
-        case Tag::NONCE:
-        case Tag::MIN_MAC_LENGTH:
-        case Tag::EC_CURVE:
-
-        /* Tags not used for operations. */
-        case Tag::BLOB_USAGE_REQUIREMENTS:
-
-        /* Algorithm specific parameters not used for access control. */
-        case Tag::RSA_PUBLIC_EXPONENT:
-
-        /* Informational tags. */
-        case Tag::CREATION_DATETIME:
-        case Tag::ORIGIN:
-        case Tag::ROLLBACK_RESISTANCE:
-
-        /* Tags handled when KM_TAG_USER_SECURE_ID is handled */
-        case Tag::NO_AUTH_REQUIRED:
-        case Tag::USER_AUTH_TYPE:
-        case Tag::AUTH_TIMEOUT:
-
-        /* Tag to provide data to operations. */
-        case Tag::ASSOCIATED_DATA:
-
-        /* Tags that are implicitly verified by secure side */
-        case Tag::APPLICATION_ID:
-        case Tag::BOOT_PATCHLEVEL:
-        case Tag::OS_PATCHLEVEL:
-        case Tag::OS_VERSION:
-        case Tag::TRUSTED_USER_PRESENCE_REQUIRED:
-        case Tag::VENDOR_PATCHLEVEL:
-
-        /* TODO(swillden): Handle these */
-        case Tag::INCLUDE_UNIQUE_ID:
-        case Tag::UNIQUE_ID:
-        case Tag::RESET_SINCE_ID_ROTATION:
-        case Tag::ALLOW_WHILE_ON_BODY:
-        case Tag::HARDWARE_TYPE:
-        case Tag::TRUSTED_CONFIRMATION_REQUIRED:
-        case Tag::CONFIRMATION_TOKEN:
-            break;
-
-        case Tag::BOOTLOADER_ONLY:
-            return ErrorCode::INVALID_KEY_BLOB;
-        }
-    }
-
-    if (unlocked_device_required && is_device_locked(user_id)) {
-        switch (purpose) {
-        case KeyPurpose::ENCRYPT:
-        case KeyPurpose::VERIFY:
-            /* These are okay */
-            break;
-        case KeyPurpose::DECRYPT:
-        case KeyPurpose::SIGN:
-        case KeyPurpose::WRAP_KEY:
-            return ErrorCode::DEVICE_LOCKED;
-        };
-    }
-
-    if (authentication_required && !auth_token_matched) {
-        ALOGE("Auth required but no matching auth token found");
-        return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
-    }
-
-    if (!caller_nonce_authorized_by_key && is_origination_purpose(purpose) &&
-        operation_params.Contains(Tag::NONCE))
-        return ErrorCode::CALLER_NONCE_PROHIBITED;
-
-    if (min_ops_timeout != UINT32_MAX) {
-        if (!access_time_map_.UpdateKeyAccessTime(keyid, get_current_time(), min_ops_timeout)) {
-            ALOGE("Rate-limited keys table full.  Entries will time out.");
-            return ErrorCode::TOO_MANY_OPERATIONS;
-        }
-    }
-
-    if (update_access_count) {
-        if (!access_count_map_.IncrementKeyAccessCount(keyid)) {
-            ALOGE("Usage count-limited keys table full, until reboot.");
-            return ErrorCode::TOO_MANY_OPERATIONS;
-        }
-    }
-
-    return ErrorCode::OK;
-}
-
-class EvpMdCtx {
-  public:
-    EvpMdCtx() { EVP_MD_CTX_init(&ctx_); }
-    ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); }
-
-    EVP_MD_CTX* get() { return &ctx_; }
-
-  private:
-    EVP_MD_CTX ctx_;
-};
-
-/* static */
-std::optional<km_id_t> KeymasterEnforcement::CreateKeyId(const hidl_vec<uint8_t>& key_blob) {
-    EvpMdCtx ctx;
-    km_id_t keyid;
-
-    uint8_t hash[EVP_MAX_MD_SIZE];
-    unsigned int hash_len;
-    if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr /* ENGINE */) &&
-        EVP_DigestUpdate(ctx.get(), &key_blob[0], key_blob.size()) &&
-        EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) {
-        assert(hash_len >= sizeof(keyid));
-        memcpy(&keyid, hash, sizeof(keyid));
-        return keyid;
-    }
-
-    return {};
-}
-
-bool KeymasterEnforcement::MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid) {
-    uint32_t last_access_time;
-    if (!access_time_map_.LastKeyAccessTime(keyid, &last_access_time)) return true;
-    return min_time_between <= static_cast<int64_t>(get_current_time()) - last_access_time;
-}
-
-bool KeymasterEnforcement::MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses) {
-    uint32_t key_access_count;
-    if (!access_count_map_.KeyAccessCount(keyid, &key_access_count)) return true;
-    return key_access_count < max_uses;
-}
-
-template <typename IntType, uint32_t byteOrder> struct choose_hton;
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
-    inline static IntType hton(const IntType& value) {
-        IntType result = 0;
-        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
-        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
-        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
-            *(outbytes++) = inbytes[i];
-        }
-        return result;
-    }
-};
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
-    inline static IntType hton(const IntType& value) { return value; }
-};
-
-template <typename IntType> inline IntType hton(const IntType& value) {
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-template <typename IntType> inline IntType ntoh(const IntType& value) {
-    // same operation and hton
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-bool KeymasterEnforcement::AuthTokenMatches(const AuthorizationSet& auth_set,
-                                            const HardwareAuthToken& auth_token,
-                                            const uint64_t user_secure_id,
-                                            const int auth_type_index, const int auth_timeout_index,
-                                            const uint64_t op_handle,
-                                            bool is_begin_operation) const {
-    assert(auth_type_index < static_cast<int>(auth_set.size()));
-    assert(auth_timeout_index < static_cast<int>(auth_set.size()));
-
-    if (!ValidateTokenSignature(auth_token)) {
-        ALOGE("Auth token signature invalid");
-        return false;
-    }
-
-    if (auth_timeout_index == -1 && op_handle && op_handle != auth_token.challenge) {
-        ALOGE("Auth token has the challenge %" PRIu64 ", need %" PRIu64, auth_token.challenge,
-              op_handle);
-        return false;
-    }
-
-    if (user_secure_id != auth_token.userId && user_secure_id != auth_token.authenticatorId) {
-        ALOGI("Auth token SIDs %" PRIu64 " and %" PRIu64 " do not match key SID %" PRIu64,
-              auth_token.userId, auth_token.authenticatorId, user_secure_id);
-        return false;
-    }
-
-    if (auth_type_index < 0 || auth_type_index > static_cast<int>(auth_set.size())) {
-        ALOGE("Auth required but no auth type found");
-        return false;
-    }
-
-    assert(auth_set[auth_type_index].tag == TAG_USER_AUTH_TYPE);
-    auto key_auth_type_mask = authorizationValue(TAG_USER_AUTH_TYPE, auth_set[auth_type_index]);
-    if (!key_auth_type_mask.isOk()) return false;
-
-    if ((uint32_t(key_auth_type_mask.value()) & auth_token.authenticatorType) == 0) {
-        ALOGE("Key requires match of auth type mask 0%uo, but token contained 0%uo",
-              key_auth_type_mask.value(), auth_token.authenticatorType);
-        return false;
-    }
-
-    if (auth_timeout_index != -1 && is_begin_operation) {
-        assert(auth_set[auth_timeout_index].tag == TAG_AUTH_TIMEOUT);
-        auto auth_token_timeout =
-            authorizationValue(TAG_AUTH_TIMEOUT, auth_set[auth_timeout_index]);
-        if (!auth_token_timeout.isOk()) return false;
-
-        if (auth_token_timed_out(auth_token, auth_token_timeout.value())) {
-            ALOGE("Auth token has timed out");
-            return false;
-        }
-    }
-
-    // Survived the whole gauntlet.  We have authentage!
-    return true;
-}
-
-bool AccessTimeMap::LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const {
-    std::lock_guard<std::mutex> lock(list_lock_);
-    for (auto& entry : last_access_list_)
-        if (entry.keyid == keyid) {
-            *last_access_time = entry.access_time;
-            return true;
-        }
-    return false;
-}
-
-bool AccessTimeMap::UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout) {
-    std::lock_guard<std::mutex> lock(list_lock_);
-    for (auto iter = last_access_list_.begin(); iter != last_access_list_.end();) {
-        if (iter->keyid == keyid) {
-            iter->access_time = current_time;
-            return true;
-        }
-
-        // Expire entry if possible.
-        assert(current_time >= iter->access_time);
-        if (current_time - iter->access_time >= iter->timeout)
-            iter = last_access_list_.erase(iter);
-        else
-            ++iter;
-    }
-
-    if (last_access_list_.size() >= max_size_) return false;
-
-    AccessTime new_entry;
-    new_entry.keyid = keyid;
-    new_entry.access_time = current_time;
-    new_entry.timeout = timeout;
-    last_access_list_.push_front(new_entry);
-    return true;
-}
-
-bool AccessCountMap::KeyAccessCount(km_id_t keyid, uint32_t* count) const {
-    std::lock_guard<std::mutex> lock(list_lock_);
-    for (auto& entry : access_count_list_)
-        if (entry.keyid == keyid) {
-            *count = entry.access_count;
-            return true;
-        }
-    return false;
-}
-
-bool AccessCountMap::IncrementKeyAccessCount(km_id_t keyid) {
-    std::lock_guard<std::mutex> lock(list_lock_);
-    for (auto& entry : access_count_list_)
-        if (entry.keyid == keyid) {
-            // Note that the 'if' below will always be true because KM_TAG_MAX_USES_PER_BOOT is a
-            // uint32_t, and as soon as entry.access_count reaches the specified maximum value
-            // operation requests will be rejected and access_count won't be incremented any more.
-            // And, besides, UINT64_MAX is huge.  But we ensure that it doesn't wrap anyway, out of
-            // an abundance of caution.
-            if (entry.access_count < UINT64_MAX) ++entry.access_count;
-            return true;
-        }
-
-    if (access_count_list_.size() >= max_size_) return false;
-
-    AccessCount new_entry;
-    new_entry.keyid = keyid;
-    new_entry.access_count = 1;
-    access_count_list_.push_front(new_entry);
-    return true;
-}
-}; /* namespace keystore */
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
deleted file mode 100644
index 9bfb225..0000000
--- a/keystore/keymaster_enforcement.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2014 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_KEYMASTER_ENFORCEMENT_H
-#define KEYSTORE_KEYMASTER_ENFORCEMENT_H
-
-#include <stdio.h>
-
-#include <keystore/keymaster_types.h>
-
-#include <list>
-#include <mutex>
-#include <optional>
-
-namespace keystore {
-
-typedef uint64_t km_id_t;
-
-class KeymasterEnforcementContext {
-  public:
-    virtual ~KeymasterEnforcementContext() {}
-    /*
-     * Get current time.
-     */
-};
-
-class AccessTimeMap {
-  public:
-    explicit AccessTimeMap(uint32_t max_size) : max_size_(max_size) {}
-
-    /* If the key is found, returns true and fills \p last_access_time.  If not found returns
-     * false. */
-    bool LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const;
-
-    /* Updates the last key access time with the currentTime parameter.  Adds the key if
-     * needed, returning false if key cannot be added because list is full. */
-    bool UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout);
-
-  private:
-    mutable std::mutex list_lock_;
-    struct AccessTime {
-        km_id_t keyid;
-        uint32_t access_time;
-        uint32_t timeout;
-    };
-    std::list<AccessTime> last_access_list_;
-    const uint32_t max_size_;
-};
-
-class AccessCountMap {
-  public:
-    explicit AccessCountMap(uint32_t max_size) : max_size_(max_size) {}
-
-    /* If the key is found, returns true and fills \p count.  If not found returns
-     * false. */
-    bool KeyAccessCount(km_id_t keyid, uint32_t* count) const;
-
-    /* Increments key access count, adding an entry if the key has never been used.  Returns
-     * false if the list has reached maximum size. */
-    bool IncrementKeyAccessCount(km_id_t keyid);
-
-  private:
-    mutable std::mutex list_lock_;
-    struct AccessCount {
-        km_id_t keyid;
-        uint64_t access_count;
-    };
-    std::list<AccessCount> access_count_list_;
-    const uint32_t max_size_;
-};
-
-class KeymasterEnforcement {
-  public:
-    /**
-     * Construct a KeymasterEnforcement.
-     */
-    KeymasterEnforcement(uint32_t max_access_time_map_size, uint32_t max_access_count_map_size);
-    virtual ~KeymasterEnforcement();
-
-    /**
-     * Iterates through the authorization set and returns the corresponding keymaster error. Will
-     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
-     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
-     */
-    ErrorCode AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
-                                 const AuthorizationSet& auth_set,
-                                 const AuthorizationSet& operation_params,
-                                 const HardwareAuthToken& auth_token, uint64_t op_handle,
-                                 bool is_begin_operation);
-
-    /**
-     * Iterates through the authorization set and returns the corresponding keymaster error. Will
-     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
-     * the given operation params. Used for encrypt, decrypt sign, and verify.
-     */
-    ErrorCode AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
-                             const AuthorizationSet& auth_set,
-                             const AuthorizationSet& operation_params,
-                             NullOr<const HardwareAuthToken&> auth_token);
-
-    /**
-     * Iterates through the authorization set and returns the corresponding keymaster error. Will
-     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
-     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
-     */
-    ErrorCode AuthorizeUpdate(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
-                              uint64_t op_handle) {
-        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
-    }
-
-    /**
-     * Iterates through the authorization set and returns the corresponding keymaster error. Will
-     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
-     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
-     */
-    ErrorCode AuthorizeFinish(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
-                              uint64_t op_handle) {
-        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
-    }
-
-    /**
-     * Creates a key ID for use in subsequent calls to AuthorizeOperation.  Clients needn't use this
-     * method of creating key IDs, as long as they use something consistent and unique.  This method
-     * hashes the key blob.
-     *
-     * Returns false if an error in the crypto library prevents creation of an ID.
-     */
-    static std::optional<km_id_t> CreateKeyId(const hidl_vec<uint8_t>& key_blob);
-
-    //
-    // Methods that must be implemented by subclasses
-    //
-    // The time-related methods address the fact that different enforcement contexts may have
-    // different time-related capabilities.  In particular:
-    //
-    // - They may or may not be able to check dates against real-world clocks.
-    //
-    // - They may or may not be able to check timestampls against authentication trustlets (minters
-    //   of hw_auth_token_t structs).
-    //
-    // - They must have some time source for relative times, but may not be able to provide more
-    //   than reliability and monotonicity.
-
-    /*
-     * Returns true if the specified activation date has passed, or if activation cannot be
-     * enforced.
-     */
-    virtual bool activation_date_valid(uint64_t activation_date) const = 0;
-
-    /*
-     * Returns true if the specified expiration date has passed.  Returns false if it has not, or if
-     * expiration cannot be enforced.
-     */
-    virtual bool expiration_date_passed(uint64_t expiration_date) const = 0;
-
-    /*
-     * Returns true if the specified auth_token is older than the specified timeout.
-     */
-    virtual bool auth_token_timed_out(const HardwareAuthToken& token, uint32_t timeout) const = 0;
-
-    /*
-     * Get current time in seconds from some starting point.  This value is used to compute relative
-     * times between events.  It must be monotonically increasing, and must not skip or lag.  It
-     * need not have any relation to any external time standard (other than the duration of
-     * "second").
-     *
-     * On POSIX systems, it's recommented to use clock_gettime(CLOCK_MONOTONIC, ...) to implement
-     * this method.
-     */
-    virtual uint32_t get_current_time() const = 0;
-
-    /*
-     * Returns true if the specified auth_token has a valid signature, or if signature validation is
-     * not available.
-     */
-    virtual bool ValidateTokenSignature(const HardwareAuthToken& token) const = 0;
-
-    /*
-     * Returns true if the device screen is currently locked for the specified user.
-     */
-    virtual bool is_device_locked(int32_t userId) const = 0;
-
-  private:
-    ErrorCode AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
-                                      const HardwareAuthToken& auth_token, uint64_t op_handle);
-
-    bool MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid);
-    bool MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses);
-    bool AuthTokenMatches(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
-                          const uint64_t user_secure_id, const int auth_type_index,
-                          const int auth_timeout_index, const uint64_t op_handle,
-                          bool is_begin_operation) const;
-
-    AccessTimeMap access_time_map_;
-    AccessCountMap access_count_map_;
-};
-
-}; /* namespace keystore */
-
-#endif  // KEYSTORE_KEYMASTER_ENFORCEMENT_H
diff --git a/keystore/keymaster_worker.cpp b/keystore/keymaster_worker.cpp
deleted file mode 100644
index 7481a1e..0000000
--- a/keystore/keymaster_worker.cpp
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
-**
-** Copyright 2018, 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.
-*/
-#define LOG_TAG "keymaster_worker"
-
-#include "keymaster_worker.h"
-
-#include "keystore_utils.h"
-
-#include <android-base/logging.h>
-
-#include <log/log_event_list.h>
-
-#include <private/android_logger.h>
-
-#include "KeyStore.h"
-#include "keymaster_enforcement.h"
-
-#include "key_creation_log_handler.h"
-#include "keystore_utils.h"
-
-#include <chrono>
-
-namespace keystore {
-
-using namespace std::chrono;
-
-constexpr size_t kMaxOperations = 15;
-
-using AndroidKeymasterArguments = android::security::keymaster::KeymasterArguments;
-using android::security::keymaster::ExportResult;
-using android::security::keymaster::operationFailed;
-using android::security::keymaster::OperationResult;
-
-Worker::Worker() {}
-Worker::~Worker() {
-    std::unique_lock<std::mutex> lock(pending_requests_mutex_);
-    terminate_ = true;
-    pending_requests_cond_var_.notify_all();
-    pending_requests_cond_var_.wait(lock, [this] { return !running_; });
-}
-void Worker::addRequest(WorkerTask request) {
-    std::unique_lock<std::mutex> lock(pending_requests_mutex_);
-    bool start_thread = !running_;
-    running_ = true;
-    pending_requests_.push(std::move(request));
-    lock.unlock();
-    pending_requests_cond_var_.notify_all();
-    if (start_thread) {
-        auto worker = std::thread([this] {
-            std::unique_lock<std::mutex> lock(pending_requests_mutex_);
-            while (running_) {
-                // Wait for 30s if the request queue is empty, then kill die.
-                // Die immediately if termiate_ was set which happens in the destructor.
-                auto status = pending_requests_cond_var_.wait_for(
-                    lock, 30s, [this]() { return !pending_requests_.empty() || terminate_; });
-                if (status && !terminate_) {
-                    auto request = std::move(pending_requests_.front());
-                    lock.unlock();
-                    request();
-                    lock.lock();
-                    pending_requests_.pop();
-                } else {
-                    running_ = false;
-                }
-                pending_requests_cond_var_.notify_all();
-            }
-        });
-        worker.detach();
-    }
-}
-
-KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore)
-    : keymasterDevice_(std::move(keymasterDevice)), operationMap_(keyStore), keyStore_(keyStore) {
-    // make sure that hal version is cached.
-    if (keymasterDevice_) keymasterDevice_->halVersion();
-}
-
-void KeymasterWorker::logIfKeymasterVendorError(ErrorCode ec) const {
-    keymasterDevice_->logIfKeymasterVendorError(ec);
-}
-
-void KeymasterWorker::deleteOldKeyOnUpgrade(const LockedKeyBlobEntry& blobfile, Blob keyBlob) {
-    // if we got the blob successfully, we try and delete it from the keymaster device
-    auto& dev = keymasterDevice_;
-    uid_t uid = blobfile->uid();
-    const auto& alias = blobfile->alias();
-
-    if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
-        auto ret = KS_HANDLE_HIDL_ERROR(dev, dev->deleteKey(blob2hidlVec(keyBlob)));
-        // A device doesn't have to implement delete_key.
-        bool success = ret == ErrorCode::OK || ret == ErrorCode::UNIMPLEMENTED;
-        if (__android_log_security()) {
-            android_log_event_list(SEC_TAG_KEY_DESTROYED)
-                << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
-        }
-        if (!success) {
-            LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid << " failed";
-        }
-    }
-}
-
-std::tuple<KeyStoreServiceReturnCode, Blob>
-KeymasterWorker::upgradeKeyBlob(const LockedKeyBlobEntry& lockedEntry,
-                                const AuthorizationSet& params) {
-    LOG(INFO) << "upgradeKeyBlob " << lockedEntry->alias() << " " << (uint32_t)lockedEntry->uid();
-
-    std::tuple<KeyStoreServiceReturnCode, Blob> result;
-
-    auto userState = keyStore_->getUserStateDB().getUserStateByUid(lockedEntry->uid());
-
-    Blob& blob = std::get<1>(result);
-    KeyStoreServiceReturnCode& error = std::get<0>(result);
-
-    Blob charBlob;
-    ResponseCode rc;
-
-    std::tie(rc, blob, charBlob) =
-        lockedEntry.readBlobs(userState->getEncryptionKey(), userState->getState());
-
-    userState = {};
-
-    if (rc != ResponseCode::NO_ERROR) {
-        return error = rc, result;
-    }
-
-    auto hidlKey = blob2hidlVec(blob);
-    auto& dev = keymasterDevice_;
-
-    auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& upgradedKeyBlob) {
-        dev->logIfKeymasterVendorError(ret);
-        error = ret;
-        if (!error.isOk()) {
-            if (error == ErrorCode::INVALID_KEY_BLOB) {
-                log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
-            }
-            return;
-        }
-
-        Blob newBlob(&upgradedKeyBlob[0], upgradedKeyBlob.size(), nullptr /* info */,
-                     0 /* infoLength */, ::TYPE_KEYMASTER_10);
-        newBlob.setSecurityLevel(blob.getSecurityLevel());
-        newBlob.setEncrypted(blob.isEncrypted());
-        newBlob.setSuperEncrypted(blob.isSuperEncrypted());
-        newBlob.setCriticalToDeviceEncryption(blob.isCriticalToDeviceEncryption());
-
-        error = keyStore_->put(lockedEntry, newBlob, charBlob);
-        if (!error.isOk()) {
-            ALOGI("upgradeKeyBlob keystore->put failed %d", error.getErrorCode());
-            return;
-        }
-
-        deleteOldKeyOnUpgrade(lockedEntry, std::move(blob));
-        blob = std::move(newBlob);
-    };
-
-    KeyStoreServiceReturnCode error2;
-    error2 = KS_HANDLE_HIDL_ERROR(dev, dev->upgradeKey(hidlKey, params.hidl_data(), hidlCb));
-    if (!error2.isOk()) {
-        return error = error2, result;
-    }
-
-    return result;
-}
-
-std::tuple<KeyStoreServiceReturnCode, KeyCharacteristics, Blob, Blob>
-KeymasterWorker::createKeyCharacteristicsCache(const LockedKeyBlobEntry& lockedEntry,
-                                               const hidl_vec<uint8_t>& clientId,
-                                               const hidl_vec<uint8_t>& appData, Blob keyBlob,
-                                               Blob charBlob) {
-    std::tuple<KeyStoreServiceReturnCode, KeyCharacteristics, Blob, Blob> result;
-
-#if __cplusplus == 201703L
-    auto& [rc, resultCharacteristics, outBlob, charOutBlob] = result;
-#else
-    KeyStoreServiceReturnCode& rc = std::get<0>(result);
-    KeyCharacteristics& resultCharacteristics = std::get<1>(result);
-    Blob& outBlob = std::get<2>(result);
-    Blob& charOutBlob = std::get<3>(result);
-#endif
-
-    rc = ResponseCode::SYSTEM_ERROR;
-    if (!keyBlob) return result;
-    auto hidlKeyBlob = blob2hidlVec(keyBlob);
-    auto& dev = keymasterDevice_;
-
-    KeyStoreServiceReturnCode error;
-
-    AuthorizationSet hwEnforced, swEnforced;
-    bool success = true;
-
-    if (charBlob) {
-        std::tie(success, hwEnforced, swEnforced) = charBlob.getKeyCharacteristics();
-    }
-    if (!success) {
-        LOG(ERROR) << "Failed to read cached key characteristics";
-        return rc = ResponseCode::SYSTEM_ERROR, result;
-    }
-
-    auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
-        dev->logIfKeymasterVendorError(ret);
-        error = ret;
-        if (!error.isOk()) {
-            if (error == ErrorCode::INVALID_KEY_BLOB) {
-                log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
-            }
-            return;
-        }
-
-        // Replace the sw_enforced set with those persisted to disk, minus hw_enforced
-        AuthorizationSet softwareEnforced = keyCharacteristics.softwareEnforced;
-        hwEnforced = keyCharacteristics.hardwareEnforced;
-        swEnforced.Union(softwareEnforced);
-        softwareEnforced.Subtract(hwEnforced);
-
-        // We only get the characteristics from keymaster if there was no cache file or the
-        // the chach file was a legacy cache file. So lets write a new cache file for the next time.
-        Blob newCharBlob;
-        success = newCharBlob.putKeyCharacteristics(hwEnforced, swEnforced);
-        if (!success) {
-            error = ResponseCode::SYSTEM_ERROR;
-            LOG(ERROR) << "Failed to serialize cached key characteristics";
-            return;
-        }
-
-        error = keyStore_->put(lockedEntry, {}, newCharBlob);
-        if (!error.isOk()) {
-            ALOGE("Failed to write key characteristics cache");
-            return;
-        }
-        charBlob = std::move(newCharBlob);
-    };
-
-    if (!charBlob || charBlob.getType() == TYPE_KEY_CHARACTERISTICS) {
-        // this updates the key characteristics cache file to the new format or creates one in
-        // in the first place
-        rc = KS_HANDLE_HIDL_ERROR(
-            dev, dev->getKeyCharacteristics(hidlKeyBlob, clientId, appData, hidlCb));
-        if (!rc.isOk()) {
-            return result;
-        }
-
-        if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
-            AuthorizationSet upgradeParams;
-            if (clientId.size()) {
-                upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
-            }
-            if (appData.size()) {
-                upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
-            }
-            std::tie(rc, keyBlob) = upgradeKeyBlob(lockedEntry, upgradeParams);
-            if (!rc.isOk()) {
-                return result;
-            }
-
-            auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
-
-            rc = KS_HANDLE_HIDL_ERROR(
-                dev, dev->getKeyCharacteristics(upgradedHidlKeyBlob, clientId, appData, hidlCb));
-            if (!rc.isOk()) {
-                return result;
-            }
-        }
-    }
-
-    resultCharacteristics.hardwareEnforced = hwEnforced.hidl_data();
-    resultCharacteristics.softwareEnforced = swEnforced.hidl_data();
-
-    outBlob = std::move(keyBlob);
-    charOutBlob = std::move(charBlob);
-    rc = error;
-    return result;
-}
-
-/**
- * Get the auth token for this operation from the auth token table.
- *
- * Returns ResponseCode::NO_ERROR if the auth token was set or none was required.
- *         ::OP_AUTH_NEEDED if it is a per op authorization, no
- *         authorization token exists for that operation and
- *         failOnTokenMissing is false.
- *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
- *         token for the operation
- */
-std::pair<KeyStoreServiceReturnCode, HardwareAuthToken>
-KeymasterWorker::getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle,
-                              KeyPurpose purpose, bool failOnTokenMissing) {
-
-    AuthorizationSet allCharacteristics(characteristics.softwareEnforced);
-    allCharacteristics.append(characteristics.hardwareEnforced.begin(),
-                              characteristics.hardwareEnforced.end());
-
-    HardwareAuthToken authToken;
-    AuthTokenTable::Error err;
-    std::tie(err, authToken) = keyStore_->getAuthTokenTable().FindAuthorization(
-        allCharacteristics, static_cast<KeyPurpose>(purpose), handle);
-
-    KeyStoreServiceReturnCode rc;
-
-    switch (err) {
-    case AuthTokenTable::OK:
-    case AuthTokenTable::AUTH_NOT_REQUIRED:
-        rc = ResponseCode::NO_ERROR;
-        break;
-
-    case AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
-    case AuthTokenTable::AUTH_TOKEN_EXPIRED:
-    case AuthTokenTable::AUTH_TOKEN_WRONG_SID:
-        ALOGE("getAuthToken failed: %d", err);  // STOPSHIP: debug only, to be removed
-        rc = ErrorCode::KEY_USER_NOT_AUTHENTICATED;
-        break;
-
-    case AuthTokenTable::OP_HANDLE_REQUIRED:
-        rc = failOnTokenMissing ? KeyStoreServiceReturnCode(ErrorCode::KEY_USER_NOT_AUTHENTICATED)
-                                : KeyStoreServiceReturnCode(ResponseCode::OP_AUTH_NEEDED);
-        break;
-
-    default:
-        ALOGE("Unexpected FindAuthorization return value %d", err);
-        rc = ErrorCode::INVALID_ARGUMENT;
-    }
-
-    return {rc, std::move(authToken)};
-}
-
-KeyStoreServiceReturnCode KeymasterWorker::abort(const sp<IBinder>& token,
-                                                 ResponseCode reason_for_abort) {
-    auto op = operationMap_.removeOperation(token, false /* wasOpSuccessful */,
-                                            static_cast<int32_t>(reason_for_abort));
-    if (op) {
-        keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
-        return KS_HANDLE_HIDL_ERROR(keymasterDevice_, keymasterDevice_->abort(op->handle));
-    } else {
-        return ErrorCode::INVALID_OPERATION_HANDLE;
-    }
-}
-
-/**
- * Prune the oldest pruneable operation.
- */
-bool KeymasterWorker::pruneOperation() {
-    sp<IBinder> oldest = operationMap_.getOldestPruneableOperation();
-    ALOGD("Trying to prune operation %p", oldest.get());
-    size_t op_count_before_abort = operationMap_.getOperationCount();
-    // We mostly ignore errors from abort() because all we care about is whether at least
-    // one operation has been removed.
-    auto rc = abort(oldest, ResponseCode::PRUNED);
-    keyStore_->removeOperationDevice(oldest);
-    if (operationMap_.getOperationCount() >= op_count_before_abort) {
-        ALOGE("Failed to abort pruneable operation %p, error: %d", oldest.get(), rc.getErrorCode());
-        return false;
-    }
-    return true;
-}
-
-// My IDE defines "CAPTURE_MOVE(x) x" because it does not understand generalized lambda captures.
-// It should never be redefined by a build system though.
-#ifndef CAPTURE_MOVE
-#define CAPTURE_MOVE(x) x = std::move(x)
-#endif
-
-void KeymasterWorker::begin(LockedKeyBlobEntry lockedEntry, sp<IBinder> appToken, Blob keyBlob,
-                            Blob charBlob, bool pruneable, KeyPurpose purpose,
-                            AuthorizationSet opParams, hidl_vec<uint8_t> entropy,
-                            worker_begin_cb worker_cb) {
-
-    Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(appToken),
-                        CAPTURE_MOVE(keyBlob), CAPTURE_MOVE(charBlob), pruneable, purpose,
-                        CAPTURE_MOVE(opParams), CAPTURE_MOVE(entropy),
-                        CAPTURE_MOVE(worker_cb)]() mutable {
-        // Concurrently executed
-
-        auto& dev = keymasterDevice_;
-
-        KeyCharacteristics characteristics;
-
-        {
-            hidl_vec<uint8_t> clientId;
-            hidl_vec<uint8_t> appData;
-            for (const auto& param : opParams) {
-                if (param.tag == Tag::APPLICATION_ID) {
-                    clientId = authorizationValue(TAG_APPLICATION_ID, param).value();
-                } else if (param.tag == Tag::APPLICATION_DATA) {
-                    appData = authorizationValue(TAG_APPLICATION_DATA, param).value();
-                }
-            }
-            KeyStoreServiceReturnCode error;
-            std::tie(error, characteristics, keyBlob, charBlob) = createKeyCharacteristicsCache(
-                lockedEntry, clientId, appData, std::move(keyBlob), std::move(charBlob));
-            if (!error.isOk()) {
-                worker_cb(operationFailed(error));
-                return;
-            }
-        }
-
-        KeyStoreServiceReturnCode rc, authRc;
-        HardwareAuthToken authToken;
-        std::tie(authRc, authToken) = getAuthToken(characteristics, 0 /* no challenge */, purpose,
-                                                   /*failOnTokenMissing*/ false);
-
-        // If per-operation auth is needed we need to begin the operation and
-        // the client will need to authorize that operation before calling
-        // update. Any other auth issues stop here.
-        if (!authRc.isOk() && authRc != ResponseCode::OP_AUTH_NEEDED) {
-            return worker_cb(operationFailed(authRc));
-        }
-
-        // Add entropy to the device first.
-        if (entropy.size()) {
-            rc = KS_HANDLE_HIDL_ERROR(dev, dev->addRngEntropy(entropy));
-            if (!rc.isOk()) {
-                return worker_cb(operationFailed(rc));
-            }
-        }
-
-        // Create a keyid for this key.
-        auto keyid = KeymasterEnforcement::CreateKeyId(blob2hidlVec(keyBlob));
-        if (!keyid) {
-            ALOGE("Failed to create a key ID for authorization checking.");
-            return worker_cb(operationFailed(ErrorCode::UNKNOWN_ERROR));
-        }
-
-        // Check that all key authorization policy requirements are met.
-        AuthorizationSet key_auths = characteristics.hardwareEnforced;
-        key_auths.append(characteristics.softwareEnforced.begin(),
-                         characteristics.softwareEnforced.end());
-
-        rc = keyStore_->getEnforcementPolicy().AuthorizeOperation(
-            purpose, *keyid, key_auths, opParams, authToken, 0 /* op_handle */,
-            true /* is_begin_operation */);
-        if (!rc.isOk()) {
-            return worker_cb(operationFailed(rc));
-        }
-
-        // If there are more than kMaxOperations, abort the oldest operation that was started as
-        // pruneable.
-        while (operationMap_.getOperationCount() >= kMaxOperations) {
-            ALOGD("Reached or exceeded concurrent operations limit");
-            if (!pruneOperation()) {
-                break;
-            }
-        }
-
-        android::security::keymaster::OperationResult result;
-
-        auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
-                          uint64_t operationHandle) {
-            dev->logIfKeymasterVendorError(ret);
-            result.resultCode = ret;
-            if (!result.resultCode.isOk()) {
-                if (result.resultCode == ErrorCode::INVALID_KEY_BLOB) {
-                    log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
-                }
-                return;
-            }
-            result.handle = operationHandle;
-            result.outParams = outParams;
-        };
-
-        do {
-            rc = KS_HANDLE_HIDL_ERROR(dev, dev->begin(purpose, blob2hidlVec(keyBlob),
-                                                      opParams.hidl_data(), authToken, hidlCb));
-            if (!rc.isOk()) {
-                LOG(ERROR) << "Got error " << rc << " from begin()";
-                return worker_cb(operationFailed(ResponseCode::SYSTEM_ERROR));
-            }
-
-            if (result.resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
-                std::tie(rc, keyBlob) = upgradeKeyBlob(lockedEntry, opParams);
-                if (!rc.isOk()) {
-                    return worker_cb(operationFailed(rc));
-                }
-
-                rc = KS_HANDLE_HIDL_ERROR(dev, dev->begin(purpose, blob2hidlVec(keyBlob),
-                                                          opParams.hidl_data(), authToken, hidlCb));
-                if (!rc.isOk()) {
-                    LOG(ERROR) << "Got error " << rc << " from begin()";
-                    return worker_cb(operationFailed(ResponseCode::SYSTEM_ERROR));
-                }
-            }
-            // If there are too many operations abort the oldest operation that was
-            // started as pruneable and try again.
-        } while (result.resultCode == ErrorCode::TOO_MANY_OPERATIONS && pruneOperation());
-
-        rc = result.resultCode;
-        if (!rc.isOk()) {
-            return worker_cb(operationFailed(rc));
-        }
-
-        // Note: The operation map takes possession of the contents of "characteristics".
-        // It is safe to use characteristics after the following line but it will be empty.
-        sp<IBinder> operationToken =
-            operationMap_.addOperation(result.handle, *keyid, purpose, dev, appToken,
-                                       std::move(characteristics), opParams.hidl_data(), pruneable);
-        assert(characteristics.hardwareEnforced.size() == 0);
-        assert(characteristics.softwareEnforced.size() == 0);
-        result.token = operationToken;
-
-        auto operation = operationMap_.getOperation(operationToken);
-        if (!operation) {
-            return worker_cb(operationFailed(ResponseCode::SYSTEM_ERROR));
-        }
-
-        if (authRc.isOk() && authToken.mac.size() &&
-            dev->halVersion().securityLevel == SecurityLevel::STRONGBOX) {
-            operation->authTokenFuture = operation->authTokenPromise.get_future();
-            std::weak_ptr<Operation> weak_operation = operation;
-
-            auto verifyTokenCB = [weak_operation](KeyStoreServiceReturnCode rc,
-                                                  HardwareAuthToken authToken,
-                                                  VerificationToken verificationToken) {
-                auto operation = weak_operation.lock();
-                if (!operation) {
-                    // operation aborted, nothing to do
-                    return;
-                }
-                if (rc.isOk()) {
-                    operation->authToken = std::move(authToken);
-                    operation->verificationToken = std::move(verificationToken);
-                }
-                operation->authTokenPromise.set_value(rc);
-            };
-            auto teeKmDevice = keyStore_->getDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
-            teeKmDevice->verifyAuthorization(result.handle, {}, std::move(authToken),
-                                             std::move(verifyTokenCB));
-        }
-
-        // Return the authentication lookup result. If this is a per operation
-        // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the
-        // application should get an auth token using the handle before the
-        // first call to update, which will fail if keystore hasn't received the
-        // auth token.
-        if (result.resultCode.isOk()) {
-            result.resultCode = authRc;
-        }
-        return worker_cb(result);
-    });
-}
-
-KeyStoreServiceReturnCode
-KeymasterWorker::getOperationAuthTokenIfNeeded(std::shared_ptr<Operation> op) {
-    if (!op) return ErrorCode::INVALID_OPERATION_HANDLE;
-
-    if (op->authTokenFuture.valid()) {
-        LOG(INFO) << "Waiting for verification token";
-        op->authTokenFuture.wait();
-        auto rc = op->authTokenFuture.get();
-        if (!rc.isOk()) {
-            return rc;
-        }
-        op->authTokenFuture = {};
-    } else if (!op->hasAuthToken()) {
-        KeyStoreServiceReturnCode rc;
-        HardwareAuthToken found;
-        std::tie(rc, found) = getAuthToken(op->characteristics, op->handle, op->purpose);
-        if (!rc.isOk()) return rc;
-        op->authToken = std::move(found);
-    }
-
-    return ResponseCode::NO_ERROR;
-}
-
-namespace {
-
-class Finalize {
-  private:
-    std::function<void()> f_;
-
-  public:
-    explicit Finalize(std::function<void()> f) : f_(f) {}
-    ~Finalize() {
-        if (f_) f_();
-    }
-    void release() { f_ = {}; }
-};
-
-}  // namespace
-
-void KeymasterWorker::update(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> data,
-                             update_cb worker_cb) {
-    Worker::addRequest([this, CAPTURE_MOVE(token), CAPTURE_MOVE(params), CAPTURE_MOVE(data),
-                        CAPTURE_MOVE(worker_cb)]() {
-        KeyStoreServiceReturnCode rc;
-        auto op = operationMap_.getOperation(token);
-        if (!op) {
-            return worker_cb(operationFailed(ErrorCode::INVALID_OPERATION_HANDLE));
-        }
-
-        Finalize abort_operation_in_case_of_error([&] {
-            operationMap_.removeOperation(token, false, rc.getErrorCode());
-            keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
-            KS_HANDLE_HIDL_ERROR(keymasterDevice_, keymasterDevice_->abort(op->handle));
-        });
-
-        rc = getOperationAuthTokenIfNeeded(op);
-        if (!rc.isOk()) return worker_cb(operationFailed(rc));
-
-        // Check that all key authorization policy requirements are met.
-        AuthorizationSet key_auths(op->characteristics.hardwareEnforced);
-        key_auths.append(op->characteristics.softwareEnforced.begin(),
-                         op->characteristics.softwareEnforced.end());
-
-        rc = keyStore_->getEnforcementPolicy().AuthorizeOperation(op->purpose, op->keyid, key_auths,
-                                                                  params, op->authToken, op->handle,
-                                                                  false /* is_begin_operation */);
-        if (!rc.isOk()) return worker_cb(operationFailed(rc));
-
-        OperationResult result;
-        auto hidlCb = [&](ErrorCode ret, uint32_t inputConsumed,
-                          const hidl_vec<KeyParameter>& outParams,
-                          const ::std::vector<uint8_t>& output) {
-            op->device->logIfKeymasterVendorError(ret);
-            result.resultCode = ret;
-            if (result.resultCode.isOk()) {
-                result.inputConsumed = inputConsumed;
-                result.outParams = outParams;
-                result.data = output;
-            }
-        };
-
-        rc = KS_HANDLE_HIDL_ERROR(op->device,
-                                  op->device->update(op->handle, params.hidl_data(), data,
-                                                     op->authToken, op->verificationToken, hidlCb));
-
-        // just a reminder: on success result->resultCode was set in the callback. So we only
-        // overwrite it if there was a communication error indicated by the ErrorCode.
-        if (!rc.isOk()) result.resultCode = rc;
-        if (result.resultCode.isOk()) {
-            // if everything went well we don't abort the operation.
-            abort_operation_in_case_of_error.release();
-        }
-        return worker_cb(std::move(result));
-    });
-}
-
-/**
- * Check that all KeyParameters provided by the application are allowed. Any parameter that keystore
- * adds itself should be disallowed here.
- */
-template <typename ParamsIter>
-static bool checkAllowedOperationParams(ParamsIter begin, const ParamsIter end) {
-    while (begin != end) {
-        switch (begin->tag) {
-        case Tag::ATTESTATION_APPLICATION_ID:
-        case Tag::RESET_SINCE_ID_ROTATION:
-            return false;
-        default:
-            break;
-        }
-        ++begin;
-    }
-    return true;
-}
-
-void KeymasterWorker::finish(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> input,
-                             hidl_vec<uint8_t> signature, hidl_vec<uint8_t> entropy,
-                             finish_cb worker_cb) {
-    Worker::addRequest([this, CAPTURE_MOVE(token), CAPTURE_MOVE(params), CAPTURE_MOVE(input),
-                        CAPTURE_MOVE(signature), CAPTURE_MOVE(entropy),
-                        CAPTURE_MOVE(worker_cb)]() mutable {
-        KeyStoreServiceReturnCode rc;
-        auto op = operationMap_.getOperation(token);
-        if (!op) {
-            return worker_cb(operationFailed(ErrorCode::INVALID_OPERATION_HANDLE));
-        }
-
-        bool finished = false;
-        Finalize abort_operation_in_case_of_error([&] {
-            operationMap_.removeOperation(token, finished && rc.isOk(), rc.getErrorCode());
-            keyStore_->getAuthTokenTable().MarkCompleted(op->handle);
-            if (!finished)
-                KS_HANDLE_HIDL_ERROR(keymasterDevice_, keymasterDevice_->abort(op->handle));
-        });
-
-        if (!checkAllowedOperationParams(params.begin(), params.end())) {
-            return worker_cb(operationFailed(ErrorCode::INVALID_ARGUMENT));
-        }
-
-        rc = getOperationAuthTokenIfNeeded(op);
-        if (!rc.isOk()) return worker_cb(operationFailed(rc));
-
-        // Check that all key authorization policy requirements are met.
-        AuthorizationSet key_auths(op->characteristics.hardwareEnforced);
-        key_auths.append(op->characteristics.softwareEnforced.begin(),
-                         op->characteristics.softwareEnforced.end());
-
-        if (key_auths.Contains(Tag::TRUSTED_CONFIRMATION_REQUIRED)) {
-            hidl_vec<uint8_t> confirmationToken =
-                keyStore_->getConfirmationManager().getLatestConfirmationToken();
-            if (confirmationToken.size() == 0) {
-                LOG(ERROR) << "Confirmation token required but none found";
-                return worker_cb(operationFailed(ErrorCode::NO_USER_CONFIRMATION));
-            }
-            params.push_back(keymaster::TAG_CONFIRMATION_TOKEN, std::move(confirmationToken));
-        }
-
-        rc = keyStore_->getEnforcementPolicy().AuthorizeOperation(op->purpose, op->keyid, key_auths,
-                                                                  params, op->authToken, op->handle,
-                                                                  false /* is_begin_operation */);
-        if (!rc.isOk()) return worker_cb(operationFailed(rc));
-
-        if (entropy.size()) {
-            rc = KS_HANDLE_HIDL_ERROR(op->device, op->device->addRngEntropy(entropy));
-            if (!rc.isOk()) {
-                return worker_cb(operationFailed(rc));
-            }
-        }
-
-        OperationResult result;
-        auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
-                          const ::std::vector<uint8_t>& output) {
-            op->device->logIfKeymasterVendorError(ret);
-            result.resultCode = ret;
-            if (result.resultCode.isOk()) {
-                result.outParams = outParams;
-                result.data = output;
-            }
-        };
-
-        rc = KS_HANDLE_HIDL_ERROR(op->device, op->device->finish(op->handle, params.hidl_data(),
-                                                                 input, signature, op->authToken,
-                                                                 op->verificationToken, hidlCb));
-
-        if (rc.isOk()) {
-            // inform the finalizer that the finish call went through
-            finished = true;
-            // and what the result was
-            rc = result.resultCode;
-        } else {
-            return worker_cb(operationFailed(rc));
-        }
-        return worker_cb(std::move(result));
-    });
-}
-
-void KeymasterWorker::abort(sp<IBinder> token, abort_cb worker_cb) {
-    Worker::addRequest([this, CAPTURE_MOVE(token), CAPTURE_MOVE(worker_cb)]() {
-        return worker_cb(abort(token, ResponseCode::ABORT_CALLED));
-    });
-}
-
-void KeymasterWorker::verifyAuthorization(uint64_t challenge, hidl_vec<KeyParameter> params,
-                                          HardwareAuthToken token,
-                                          verifyAuthorization_cb worker_cb) {
-    Worker::addRequest([this, challenge, CAPTURE_MOVE(params), CAPTURE_MOVE(token),
-                        CAPTURE_MOVE(worker_cb)]() {
-        KeyStoreServiceReturnCode error;
-        VerificationToken verificationToken;
-        KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
-            keymasterDevice_,
-            keymasterDevice_->verifyAuthorization(
-                challenge, params, token, [&](ErrorCode ret, const VerificationToken& vToken) {
-                    keymasterDevice_->logIfKeymasterVendorError(ret);
-                    error = ret;
-                    verificationToken = vToken;
-                }));
-        worker_cb(rc.isOk() ? error : rc, std::move(token), std::move(verificationToken));
-    });
-}
-
-void KeymasterWorker::addRngEntropy(hidl_vec<uint8_t> data, addRngEntropy_cb _hidl_cb) {
-    addRequest(&Keymaster::addRngEntropy, std::move(_hidl_cb), std::move(data));
-}
-
-namespace {
-bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
-    return params.end() !=
-           std::find_if(params.begin(), params.end(),
-                        [&](const KeyParameter& param) { return param.tag == tag; });
-}
-
-bool isAuthenticationBound(const hidl_vec<KeyParameter>& params) {
-    return !containsTag(params, Tag::NO_AUTH_REQUIRED);
-}
-}  // namespace
-
-void KeymasterWorker::generateKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyParameter> keyParams,
-                                  hidl_vec<uint8_t> entropy, int flags, generateKey_cb worker_cb) {
-    Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(keyParams),
-                        CAPTURE_MOVE(entropy), CAPTURE_MOVE(worker_cb), flags]() mutable {
-        KeyStoreServiceReturnCode rc =
-            KS_HANDLE_HIDL_ERROR(keymasterDevice_, keymasterDevice_->addRngEntropy(entropy));
-        if (!rc.isOk()) {
-            return worker_cb(rc, {});
-        }
-
-        SecurityLevel securityLevel = keymasterDevice_->halVersion().securityLevel;
-
-        // Fallback cannot be considered for Strongbox. Further versions restrictions are enforced
-        // by KeyStore::getFallbackDevice()
-        bool consider_fallback = securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT;
-
-        Finalize logOnFail([&] {
-            logKeystoreKeyCreationEvent(keyParams, false /*wasCreationSuccessful*/,
-                                        rc.getErrorCode());
-        });
-
-        KeyCharacteristics outCharacteristics;
-        KeyStoreServiceReturnCode error;
-        auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
-                           const KeyCharacteristics& keyCharacteristics) {
-            keymasterDevice_->logIfKeymasterVendorError(ret);
-            error = ret;
-            if (!error.isOk()) {
-                return;
-            }
-            consider_fallback = false;
-            outCharacteristics = keyCharacteristics;
-
-            Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
-            keyBlob.setSecurityLevel(securityLevel);
-            keyBlob.setCriticalToDeviceEncryption(flags &
-                                                  KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
-            if (isAuthenticationBound(keyParams) && !keyBlob.isCriticalToDeviceEncryption()) {
-                keyBlob.setSuperEncrypted(true);
-            }
-            keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-
-            AuthorizationSet sw_enforced = keyParams;
-            sw_enforced.Subtract(outCharacteristics.hardwareEnforced);
-            sw_enforced.Union(outCharacteristics.softwareEnforced);
-            sw_enforced.Filter([](const KeyParameter& param) -> bool {
-                return !(param.tag == Tag::APPLICATION_DATA || param.tag == Tag::APPLICATION_ID);
-            });
-            if (!sw_enforced.Contains(Tag::USER_ID)) {
-                // Most Java processes don't have access to this tag
-                sw_enforced.push_back(keymaster::TAG_USER_ID, get_user_id(lockedEntry->uid()));
-            }
-            Blob keyCharBlob;
-            keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
-            error = keyStore_->put(lockedEntry, std::move(keyBlob), std::move(keyCharBlob));
-        };
-
-        rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_,
-                                  keymasterDevice_->generateKey(keyParams, hidl_cb));
-        if (!rc.isOk()) {
-            return worker_cb(rc, {});
-        }
-
-        if (consider_fallback && !error.isOk()) {
-            auto fallback = keyStore_->getFallbackDevice();
-            if (!fallback) {
-                return worker_cb(error, {});
-            }
-            // No fallback for 3DES
-            for (auto& param : keyParams) {
-                auto algorithm = authorizationValue(TAG_ALGORITHM, param);
-                if (algorithm.isOk() && algorithm.value() == Algorithm::TRIPLE_DES) {
-                    return worker_cb(ErrorCode::UNSUPPORTED_ALGORITHM, {});
-                }
-            }
-
-            // delegate to fallback worker
-            fallback->generateKey(std::move(lockedEntry), std::move(keyParams), std::move(entropy),
-                                  flags, std::move(worker_cb));
-            // let fallback do the logging
-            logOnFail.release();
-            return;
-        }
-
-        if (!error.isOk()) return worker_cb(error, {});
-
-        // log on success
-        logOnFail.release();
-        logKeystoreKeyCreationEvent(keyParams, true /*wasCreationSuccessful*/,
-                                    error.getErrorCode());
-
-        return worker_cb(error, std::move(outCharacteristics));
-    });
-}
-
-void KeymasterWorker::generateKey(hidl_vec<KeyParameter> keyParams, generateKey2_cb worker_cb) {
-    addRequest(&Keymaster::generateKey, std::move(worker_cb), std::move(keyParams));
-}
-
-void KeymasterWorker::getKeyCharacteristics(LockedKeyBlobEntry lockedEntry,
-                                            hidl_vec<uint8_t> clientId, hidl_vec<uint8_t> appData,
-                                            Blob keyBlob, Blob charBlob,
-                                            getKeyCharacteristics_cb worker_cb) {
-    Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(clientId),
-                        CAPTURE_MOVE(appData), CAPTURE_MOVE(keyBlob), CAPTURE_MOVE(charBlob),
-                        CAPTURE_MOVE(worker_cb)]() {
-        auto result = createKeyCharacteristicsCache(lockedEntry, clientId, appData,
-                                                    std::move(keyBlob), std::move(charBlob));
-        return worker_cb(std::get<0>(result), std::move(std::get<1>(result)));
-    });
-}
-
-void KeymasterWorker::importKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyParameter> keyParams,
-                                KeyFormat keyFormat, hidl_vec<uint8_t> keyData, int flags,
-                                importKey_cb worker_cb) {
-    Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), CAPTURE_MOVE(keyParams), keyFormat,
-                        CAPTURE_MOVE(keyData), flags, CAPTURE_MOVE(worker_cb)]() mutable {
-        SecurityLevel securityLevel = keymasterDevice_->halVersion().securityLevel;
-
-        // Fallback cannot be considered for Strongbox. Further versions restrictions are enforced
-        // by KeyStore::getFallbackDevice()
-        bool consider_fallback = securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT;
-
-        KeyStoreServiceReturnCode error;
-        Finalize logOnFail([&] {
-            logKeystoreKeyCreationEvent(keyParams, false /*wasCreationSuccessful*/,
-                                        error.getErrorCode());
-        });
-
-        KeyCharacteristics outCharacteristics;
-        auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
-                           const KeyCharacteristics& keyCharacteristics) {
-            keymasterDevice_->logIfKeymasterVendorError(ret);
-            error = ret;
-            if (!error.isOk()) {
-                LOG(INFO) << "importKey failed";
-                return;
-            }
-            consider_fallback = false;
-            outCharacteristics = keyCharacteristics;
-
-            Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
-            keyBlob.setSecurityLevel(securityLevel);
-            keyBlob.setCriticalToDeviceEncryption(flags &
-                                                  KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
-            if (isAuthenticationBound(keyParams) && !keyBlob.isCriticalToDeviceEncryption()) {
-                keyBlob.setSuperEncrypted(true);
-            }
-            keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-
-            AuthorizationSet sw_enforced = keyParams;
-            sw_enforced.Subtract(outCharacteristics.hardwareEnforced);
-            sw_enforced.Union(outCharacteristics.softwareEnforced);
-            sw_enforced.Filter([](const KeyParameter& param) -> bool {
-                return !(param.tag == Tag::APPLICATION_DATA || param.tag == Tag::APPLICATION_ID);
-            });
-            if (!sw_enforced.Contains(Tag::USER_ID)) {
-                // Most Java processes don't have access to this tag
-                sw_enforced.push_back(keymaster::TAG_USER_ID, get_user_id(lockedEntry->uid()));
-            }
-            Blob keyCharBlob;
-            keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
-            error = keyStore_->put(lockedEntry, std::move(keyBlob), std::move(keyCharBlob));
-        };
-
-        KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
-            keymasterDevice_, keymasterDevice_->importKey(keyParams, keyFormat, keyData, hidl_cb));
-        if (!rc.isOk()) {
-            return worker_cb(rc, {});
-        }
-
-        if (consider_fallback && !error.isOk()) {
-            auto fallback = keyStore_->getFallbackDevice();
-            if (!fallback) {
-                return worker_cb(error, {});
-            }
-            // No fallback for 3DES
-            for (auto& param : keyParams) {
-                auto algorithm = authorizationValue(TAG_ALGORITHM, param);
-                if (algorithm.isOk() && algorithm.value() == Algorithm::TRIPLE_DES) {
-                    return worker_cb(ErrorCode::UNSUPPORTED_ALGORITHM, {});
-                }
-            }
-
-            // delegate to fallback worker
-            fallback->importKey(std::move(lockedEntry), std::move(keyParams), keyFormat,
-                                std::move(keyData), flags, std::move(worker_cb));
-            // let fallback to the logging
-            logOnFail.release();
-            return;
-        }
-
-        if (!error.isOk()) return worker_cb(error, {});
-
-        // log on success
-        logOnFail.release();
-        logKeystoreKeyCreationEvent(keyParams, true /*wasCreationSuccessful*/,
-                                    error.getErrorCode());
-
-        return worker_cb(error, std::move(outCharacteristics));
-    });
-}
-
-void KeymasterWorker::importWrappedKey(LockedKeyBlobEntry wrappingLockedEntry,
-                                       LockedKeyBlobEntry wrapppedLockedEntry,
-                                       hidl_vec<uint8_t> wrappedKeyData,
-                                       hidl_vec<uint8_t> maskingKey,
-                                       hidl_vec<KeyParameter> unwrappingParams, Blob wrappingBlob,
-                                       Blob wrappingCharBlob, uint64_t passwordSid,
-                                       uint64_t biometricSid, importWrappedKey_cb worker_cb) {
-    Worker::addRequest([this, CAPTURE_MOVE(wrappingLockedEntry), CAPTURE_MOVE(wrapppedLockedEntry),
-                        CAPTURE_MOVE(wrappedKeyData), CAPTURE_MOVE(maskingKey),
-                        CAPTURE_MOVE(unwrappingParams), CAPTURE_MOVE(wrappingBlob),
-                        CAPTURE_MOVE(wrappingCharBlob), passwordSid, biometricSid,
-                        CAPTURE_MOVE(worker_cb)]() mutable {
-        auto hidlWrappingKey = blob2hidlVec(wrappingBlob);
-
-        SecurityLevel securityLevel = keymasterDevice_->halVersion().securityLevel;
-
-        KeyCharacteristics outCharacteristics;
-        KeyStoreServiceReturnCode error;
-
-        auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
-                          const KeyCharacteristics& keyCharacteristics) {
-            keymasterDevice_->logIfKeymasterVendorError(ret);
-            error = ret;
-            if (!error.isOk()) {
-                return;
-            }
-            outCharacteristics = keyCharacteristics;
-
-            Blob keyBlob(hidlKeyBlob.data(), hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
-            keyBlob.setSecurityLevel(securityLevel);
-            if (isAuthenticationBound(keyCharacteristics.hardwareEnforced)) {
-                keyBlob.setSuperEncrypted(true);
-            }
-
-            AuthorizationSet sw_enforced = outCharacteristics.softwareEnforced;
-            if (!sw_enforced.Contains(Tag::USER_ID)) {
-                // Most Java processes don't have access to this tag
-                sw_enforced.push_back(keymaster::TAG_USER_ID,
-                                      get_user_id(wrapppedLockedEntry->uid()));
-            }
-            Blob keyCharBlob;
-            keyCharBlob.putKeyCharacteristics(outCharacteristics.hardwareEnforced, sw_enforced);
-            error = keyStore_->put(wrapppedLockedEntry, std::move(keyBlob), std::move(keyCharBlob));
-        };
-
-        KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
-            keymasterDevice_, keymasterDevice_->importWrappedKey(
-                                  wrappedKeyData, hidlWrappingKey, maskingKey, unwrappingParams,
-                                  passwordSid, biometricSid, hidlCb));
-
-        // possible hidl error
-        if (!rc.isOk()) {
-            return worker_cb(rc, {});
-        }
-
-        if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
-            std::tie(rc, wrappingBlob) = upgradeKeyBlob(wrappingLockedEntry, {});
-            if (!rc.isOk()) {
-                return worker_cb(rc, {});
-            }
-
-            auto upgradedHidlKeyBlob = blob2hidlVec(wrappingBlob);
-
-            rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_,
-                                      keymasterDevice_->importWrappedKey(
-                                          wrappedKeyData, upgradedHidlKeyBlob, maskingKey,
-                                          unwrappingParams, passwordSid, biometricSid, hidlCb));
-            if (!rc.isOk()) {
-                error = rc;
-            }
-        }
-        return worker_cb(error, std::move(outCharacteristics));
-    });
-}
-
-void KeymasterWorker::exportKey(LockedKeyBlobEntry lockedEntry, KeyFormat exportFormat,
-                                hidl_vec<uint8_t> clientId, hidl_vec<uint8_t> appData, Blob keyBlob,
-                                Blob charBlob, exportKey_cb worker_cb) {
-    Worker::addRequest([this, CAPTURE_MOVE(lockedEntry), exportFormat, CAPTURE_MOVE(clientId),
-                        CAPTURE_MOVE(appData), CAPTURE_MOVE(keyBlob), CAPTURE_MOVE(charBlob),
-                        CAPTURE_MOVE(worker_cb)]() mutable {
-        auto key = blob2hidlVec(keyBlob);
-
-        ExportResult result;
-        auto hidlCb = [&](ErrorCode ret,
-                          const ::android::hardware::hidl_vec<uint8_t>& keyMaterial) {
-            keymasterDevice_->logIfKeymasterVendorError(ret);
-            result.resultCode = ret;
-            if (!result.resultCode.isOk()) {
-                if (result.resultCode == ErrorCode::INVALID_KEY_BLOB) {
-                    log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
-                }
-                return;
-            }
-            result.exportData = keyMaterial;
-        };
-        KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
-            keymasterDevice_,
-            keymasterDevice_->exportKey(exportFormat, key, clientId, appData, hidlCb));
-
-        // Overwrite result->resultCode only on HIDL error. Otherwise we want the result set in the
-        // callback hidlCb.
-        if (!rc.isOk()) {
-            result.resultCode = rc;
-        }
-
-        if (result.resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
-            AuthorizationSet upgradeParams;
-            if (clientId.size()) {
-                upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
-            }
-            if (appData.size()) {
-                upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
-            }
-            std::tie(rc, keyBlob) = upgradeKeyBlob(lockedEntry, upgradeParams);
-            if (!rc.isOk()) {
-                return worker_cb(std::move(result));
-            }
-
-            auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
-
-            rc = KS_HANDLE_HIDL_ERROR(keymasterDevice_,
-                                      keymasterDevice_->exportKey(exportFormat, upgradedHidlKeyBlob,
-                                                                  clientId, appData, hidlCb));
-            if (!rc.isOk()) {
-                result.resultCode = rc;
-            }
-        }
-        return worker_cb(std::move(result));
-    });
-}
-void KeymasterWorker::attestKey(hidl_vec<uint8_t> keyToAttest, hidl_vec<KeyParameter> attestParams,
-                                attestKey_cb worker_cb) {
-    addRequest(&Keymaster::attestKey, std::move(worker_cb), std::move(keyToAttest),
-               std::move(attestParams));
-}
-
-void KeymasterWorker::deleteKey(hidl_vec<uint8_t> keyBlob, deleteKey_cb _hidl_cb) {
-    addRequest(&Keymaster::deleteKey, std::move(_hidl_cb), std::move(keyBlob));
-}
-
-void KeymasterWorker::binderDied(android::wp<IBinder> who) {
-    Worker::addRequest([this, who]() {
-        auto operations = operationMap_.getOperationsForToken(who.unsafe_get());
-        for (const auto& token : operations) {
-            abort(token, ResponseCode::BINDER_DIED);
-            keyStore_->removeOperationDevice(token);
-        }
-    });
-}
-
-}  // namespace keystore
diff --git a/keystore/keymaster_worker.h b/keystore/keymaster_worker.h
deleted file mode 100644
index f11af29..0000000
--- a/keystore/keymaster_worker.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
-**
-** Copyright 2018, 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_KEYMASTER_WORKER_H_
-#define KEYSTORE_KEYMASTER_WORKER_H_
-
-#include <condition_variable>
-#include <functional>
-#include <keymasterV4_1/Keymaster.h>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <queue>
-#include <thread>
-#include <tuple>
-
-#include <keystore/ExportResult.h>
-#include <keystore/KeyCharacteristics.h>
-#include <keystore/KeymasterBlob.h>
-#include <keystore/OperationResult.h>
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_return_types.h>
-
-#include "blob.h"
-#include "operation.h"
-
-namespace keystore {
-
-using android::sp;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using android::hardware::keymaster::V4_1::support::Keymaster;
-using ::android::security::keymaster::KeymasterBlob;
-
-class KeyStore;
-
-class Worker {
-
-    /*
-     * NonCopyableFunction works similar to std::function in that it wraps callable objects and
-     * erases their type. The rationale for using a custom class instead of
-     * std::function is that std::function requires the wrapped object to be copy contructible.
-     * NonCopyableFunction is itself not copyable and never attempts to copy the wrapped object.
-     * TODO use similar optimization as std::function to remove the extra make_unique allocation.
-     */
-    template <typename Fn> class NonCopyableFunction;
-
-    template <typename Ret, typename... Args> class NonCopyableFunction<Ret(Args...)> {
-
-        class NonCopyableFunctionBase {
-          public:
-            NonCopyableFunctionBase() = default;
-            virtual ~NonCopyableFunctionBase() {}
-            virtual Ret operator()(Args... args) = 0;
-            NonCopyableFunctionBase(const NonCopyableFunctionBase&) = delete;
-            NonCopyableFunctionBase& operator=(const NonCopyableFunctionBase&) = delete;
-        };
-
-        template <typename Fn>
-        class NonCopyableFunctionTypeEraser : public NonCopyableFunctionBase {
-          private:
-            Fn f_;
-
-          public:
-            NonCopyableFunctionTypeEraser() = default;
-            explicit NonCopyableFunctionTypeEraser(Fn f) : f_(std::move(f)) {}
-            Ret operator()(Args... args) override { return f_(std::move(args)...); }
-        };
-
-      private:
-        std::unique_ptr<NonCopyableFunctionBase> f_;
-
-      public:
-        NonCopyableFunction() = default;
-        // NOLINTNEXTLINE(google-explicit-constructor)
-        template <typename F> NonCopyableFunction(F f) {
-            f_ = std::make_unique<NonCopyableFunctionTypeEraser<F>>(std::move(f));
-        }
-        NonCopyableFunction(NonCopyableFunction&& other) = default;
-        NonCopyableFunction& operator=(NonCopyableFunction&& other) = default;
-        NonCopyableFunction(const NonCopyableFunction& other) = delete;
-        NonCopyableFunction& operator=(const NonCopyableFunction& other) = delete;
-
-        Ret operator()(Args... args) {
-            if (f_) return (*f_)(std::move(args)...);
-        }
-    };
-
-    using WorkerTask = NonCopyableFunction<void()>;
-
-    std::queue<WorkerTask> pending_requests_;
-    std::mutex pending_requests_mutex_;
-    std::condition_variable pending_requests_cond_var_;
-    bool running_ = false;
-    bool terminate_ = false;
-
-  public:
-    Worker();
-    ~Worker();
-    void addRequest(WorkerTask request);
-};
-
-template <typename... Args> struct MakeKeymasterWorkerCB;
-
-template <typename ErrorType, typename... Args>
-struct MakeKeymasterWorkerCB<ErrorType, std::function<void(Args...)>> {
-    using type = std::function<void(ErrorType, std::tuple<std::decay_t<Args>...>&&)>;
-};
-
-template <typename ErrorType> struct MakeKeymasterWorkerCB<ErrorType> {
-    using type = std::function<void(ErrorType)>;
-};
-
-template <typename... Args>
-using MakeKeymasterWorkerCB_t = typename MakeKeymasterWorkerCB<Args...>::type;
-
-class KeymasterWorker : protected Worker {
-  private:
-    sp<Keymaster> keymasterDevice_;
-    OperationMap operationMap_;
-    KeyStore* keyStore_;
-
-    template <typename KMFn, typename ErrorType, typename... Args, size_t... I>
-    void unwrap_tuple(KMFn kmfn, std::function<void(ErrorType)> cb,
-                      const std::tuple<Args...>& tuple, std::index_sequence<I...>) {
-        cb(((*keymasterDevice_).*kmfn)(std::get<I>(tuple)...));
-    }
-
-    template <typename KMFn, typename ErrorType, typename... ReturnTypes, typename... Args,
-              size_t... I>
-    void unwrap_tuple(KMFn kmfn, std::function<void(ErrorType, std::tuple<ReturnTypes...>&&)> cb,
-                      const std::tuple<Args...>& tuple, std::index_sequence<I...>) {
-        std::tuple<ReturnTypes...> returnValue;
-        auto result = ((*keymasterDevice_).*kmfn)(
-            std::get<I>(tuple)...,
-            [&returnValue](const ReturnTypes&... args) { returnValue = std::make_tuple(args...); });
-        cb(std::move(result), std::move(returnValue));
-    }
-
-    template <typename KMFn, typename ErrorType, typename... Args>
-    void addRequest(KMFn kmfn, std::function<void(ErrorType)> cb, Args&&... args) {
-        Worker::addRequest([this, kmfn, cb = std::move(cb),
-                            tuple = std::make_tuple(std::forward<Args>(args)...)]() {
-            unwrap_tuple(kmfn, std::move(cb), tuple, std::index_sequence_for<Args...>{});
-        });
-    }
-
-    template <typename KMFn, typename ErrorType, typename... ReturnTypes, typename... Args>
-    void addRequest(KMFn kmfn, std::function<void(ErrorType, std::tuple<ReturnTypes...>&&)> cb,
-                    Args&&... args) {
-        Worker::addRequest([this, kmfn, cb = std::move(cb),
-                            tuple = std::make_tuple(std::forward<Args>(args)...)]() {
-            unwrap_tuple(kmfn, std::move(cb), tuple, std::index_sequence_for<Args...>{});
-        });
-    }
-
-    void deleteOldKeyOnUpgrade(const LockedKeyBlobEntry& blobfile, Blob keyBlob);
-    std::tuple<KeyStoreServiceReturnCode, Blob>
-    upgradeKeyBlob(const LockedKeyBlobEntry& lockedEntry, const AuthorizationSet& params);
-    std::tuple<KeyStoreServiceReturnCode, KeyCharacteristics, Blob, Blob>
-    createKeyCharacteristicsCache(const LockedKeyBlobEntry& lockedEntry,
-                                  const hidl_vec<uint8_t>& clientId,
-                                  const hidl_vec<uint8_t>& appData, Blob keyBlob, Blob charBlob);
-
-    /**
-     * Get the auth token for this operation from the auth token table.
-     *
-     * Returns NO_ERROR if the auth token was found or none was required.  If not needed, the
-     *             token will be empty (which keymaster interprets as no auth token).
-     *         OP_AUTH_NEEDED if it is a per op authorization, no authorization token exists for
-     *             that operation and  failOnTokenMissing is false.
-     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth token for the operation
-     */
-    std::pair<KeyStoreServiceReturnCode, HardwareAuthToken>
-    getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle, KeyPurpose purpose,
-                 bool failOnTokenMissing = true);
-
-    KeyStoreServiceReturnCode abort(const sp<IBinder>& token, ResponseCode reason_for_abort);
-
-    bool pruneOperation();
-
-    KeyStoreServiceReturnCode getOperationAuthTokenIfNeeded(std::shared_ptr<Operation> op);
-
-    void appendConfirmationTokenIfNeeded(const KeyCharacteristics& keyCharacteristics,
-                                         hidl_vec<KeyParameter>* params);
-
-  public:
-    KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore);
-
-    void logIfKeymasterVendorError(ErrorCode ec) const;
-
-    using worker_begin_cb = std::function<void(::android::security::keymaster::OperationResult)>;
-    void begin(LockedKeyBlobEntry, sp<IBinder> appToken, Blob keyBlob, Blob charBlob,
-               bool pruneable, KeyPurpose purpose, AuthorizationSet opParams,
-               hidl_vec<uint8_t> entropy, worker_begin_cb worker_cb);
-
-    using update_cb = std::function<void(::android::security::keymaster::OperationResult)>;
-    void update(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> data,
-                update_cb _hidl_cb);
-
-    using finish_cb = std::function<void(::android::security::keymaster::OperationResult)>;
-    void finish(sp<IBinder> token, AuthorizationSet params, hidl_vec<uint8_t> input,
-                hidl_vec<uint8_t> signature, hidl_vec<uint8_t> entorpy, finish_cb worker_cb);
-
-    using abort_cb = std::function<void(KeyStoreServiceReturnCode)>;
-    void abort(sp<IBinder> token, abort_cb _hidl_cb);
-
-    using getHardwareInfo_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::getHardwareInfo_cb>;
-    void getHardwareInfo(getHardwareInfo_cb _hidl_cb);
-
-    using getHmacSharingParameters_cb =
-        MakeKeymasterWorkerCB_t<Return<void>, Keymaster::getHmacSharingParameters_cb>;
-    void getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb);
-
-    using computeSharedHmac_cb =
-        MakeKeymasterWorkerCB_t<Return<void>, Keymaster::computeSharedHmac_cb>;
-    void computeSharedHmac(hidl_vec<HmacSharingParameters> params, computeSharedHmac_cb _hidl_cb);
-
-    using verifyAuthorization_cb =
-        std::function<void(KeyStoreServiceReturnCode ec, HardwareAuthToken, VerificationToken)>;
-    void verifyAuthorization(uint64_t challenge, hidl_vec<KeyParameter> params,
-                             HardwareAuthToken token, verifyAuthorization_cb _hidl_cb);
-
-    using addRngEntropy_cb = MakeKeymasterWorkerCB_t<Return<ErrorCode>>;
-    void addRngEntropy(hidl_vec<uint8_t> data, addRngEntropy_cb _hidl_cb);
-
-    using generateKey_cb = std::function<void(
-        KeyStoreServiceReturnCode, ::android::hardware::keymaster::V4_0::KeyCharacteristics)>;
-    void generateKey(LockedKeyBlobEntry, hidl_vec<KeyParameter> keyParams,
-                     hidl_vec<uint8_t> entropy, int flags, generateKey_cb _hidl_cb);
-
-    using generateKey2_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::generateKey_cb>;
-    void generateKey(hidl_vec<KeyParameter> keyParams, generateKey2_cb _hidl_cb);
-
-    using getKeyCharacteristics_cb = std::function<void(
-        KeyStoreServiceReturnCode, ::android::hardware::keymaster::V4_0::KeyCharacteristics)>;
-    void getKeyCharacteristics(LockedKeyBlobEntry lockedEntry, hidl_vec<uint8_t> clientId,
-                               hidl_vec<uint8_t> appData, Blob keyBlob, Blob charBlob,
-                               getKeyCharacteristics_cb _hidl_cb);
-
-    using importKey_cb = std::function<void(
-        KeyStoreServiceReturnCode, ::android::hardware::keymaster::V4_0::KeyCharacteristics)>;
-    void importKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyParameter> params,
-                   KeyFormat keyFormat, hidl_vec<uint8_t> keyData, int flags,
-                   importKey_cb _hidl_cb);
-
-    using importWrappedKey_cb = std::function<void(
-        KeyStoreServiceReturnCode, ::android::hardware::keymaster::V4_0::KeyCharacteristics)>;
-    void importWrappedKey(LockedKeyBlobEntry wrappingLockedEntry,
-                          LockedKeyBlobEntry wrapppedLockedEntry, hidl_vec<uint8_t> wrappedKeyData,
-                          hidl_vec<uint8_t> maskingKey, hidl_vec<KeyParameter> unwrappingParams,
-                          Blob wrappingBlob, Blob wrappingCharBlob, uint64_t passwordSid,
-                          uint64_t biometricSid, importWrappedKey_cb worker_cb);
-
-    using exportKey_cb = std::function<void(::android::security::keymaster::ExportResult)>;
-    void exportKey(LockedKeyBlobEntry lockedEntry, KeyFormat exportFormat,
-                   hidl_vec<uint8_t> clientId, hidl_vec<uint8_t> appData, Blob keyBlob,
-                   Blob charBlob, exportKey_cb _hidl_cb);
-
-    using attestKey_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::attestKey_cb>;
-    void attestKey(hidl_vec<uint8_t> keyToAttest, hidl_vec<KeyParameter> attestParams,
-                   attestKey_cb _hidl_cb);
-
-    using deleteKey_cb = MakeKeymasterWorkerCB_t<Return<ErrorCode>>;
-    void deleteKey(hidl_vec<uint8_t> keyBlob, deleteKey_cb _hidl_cb);
-
-    using begin_cb = MakeKeymasterWorkerCB_t<Return<void>, Keymaster::begin_cb>;
-    void begin(KeyPurpose purpose, hidl_vec<uint8_t> key, hidl_vec<KeyParameter> inParams,
-               HardwareAuthToken authToken, begin_cb _hidl_cb);
-
-    void binderDied(android::wp<IBinder> who);
-
-    const Keymaster::VersionResult& halVersion() { return keymasterDevice_->halVersion(); }
-};
-
-}  // namespace keystore
-
-#endif  // KEYSTORE_KEYMASTER_WORKER_H_
diff --git a/keystore/keystore.rc b/keystore/keystore.rc
deleted file mode 100644
index 132039a..0000000
--- a/keystore/keystore.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service keystore /system/bin/keystore /data/misc/keystore
-    class main
-    user keystore
-    group keystore drmrpc readproc log
-    writepid /dev/cpuset/foreground/tasks
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.cpp b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
deleted file mode 100644
index 823ca58..0000000
--- a/keystore/keystore_aidl_hidl_marshalling_utils.cpp
+++ /dev/null
@@ -1,257 +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 "keystore_aidl_hidl_marshalling_utils.h"
-
-#include <keystore/ExportResult.h>
-#include <keystore/KeyCharacteristics.h>
-#include <keystore/KeymasterBlob.h>
-#include <keystore/KeymasterCertificateChain.h>
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_hidl_support.h>
-
-namespace keystore {
-
-// reads byte[]
-hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in) {
-
-    ssize_t length = in.readInt32();
-    if (length <= 0) {
-        return {};
-    }
-
-    const void* buf = in.readInplace(length);
-    if (!buf) return {};
-
-    return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length));
-}
-
-android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out) {
-    int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
-
-    auto rc = out->writeInt32(size);
-    if (rc != ::android::OK) return rc;
-
-    if (!size) return ::android::OK;
-
-    return out->write(blob.data(), size);
-}
-
-android::status_t writeKeymasterBlob(const ::std::vector<int32_t>& blob, android::Parcel* out) {
-
-    int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
-
-    auto rc = out->writeInt32(size);
-    if (rc != ::android::OK) return rc;
-
-    if (!size) return ::android::OK;
-
-    return out->write(blob.data(), size);
-}
-
-NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in) {
-    // Method must be in sync with KeymasterArgument.java
-    if (in.readInt32() == 0) {
-        return {};
-    }
-    KeyParameter result;
-
-    Tag tag = static_cast<Tag>(in.readInt32());
-    result.tag = tag;
-    switch (typeFromTag(tag)) {
-    case TagType::ENUM:
-    case TagType::ENUM_REP:
-    case TagType::UINT:
-    case TagType::UINT_REP:
-        result.f.integer = in.readInt32();
-        break;
-    case TagType::ULONG:
-    case TagType::ULONG_REP:
-    case TagType::DATE:
-        result.f.longInteger = in.readInt64();
-        break;
-    case TagType::BOOL:
-        result.f.boolValue = true;
-        break;
-    case TagType::BIGNUM:
-    case TagType::BYTES:
-        result.blob = readKeymasterBlob(in);  // byte array
-        break;
-    default:
-        ALOGE("Unsupported KeyParameter tag %d", tag);
-        return {};
-    }
-    return result;
-}
-
-android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out) {
-    // Method must be in sync with with KeymasterArgument.java
-    // Presence flag must be written by caller.
-
-    auto tag = param.tag;
-    auto rc = out->writeInt32(uint32_t(tag));
-    if (rc != ::android::OK) return rc;
-    switch (typeFromTag(param.tag)) {
-    case TagType::ENUM:
-    case TagType::ENUM_REP:
-    case TagType::UINT:
-    case TagType::UINT_REP:
-        rc = out->writeInt32(param.f.integer);
-        break;
-    case TagType::ULONG:
-    case TagType::ULONG_REP:
-    case TagType::DATE:
-        rc = out->writeInt64(param.f.longInteger);
-        break;
-    case TagType::BOOL:
-        // nothing to do here presence indicates true
-        break;
-    case TagType::BIGNUM:
-    case TagType::BYTES:
-        rc = writeKeymasterBlob(param.blob, out);
-        break;
-    default:
-        ALOGE("Failed to write KeyParameter: Unsupported tag %d", param.tag);
-        rc = android::BAD_VALUE;
-        break;
-    }
-    return rc;
-}
-
-hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in) {
-
-    ssize_t length = in.readInt32();  // -1 for null
-    size_t ulength = (size_t)length;
-    if (length < 0) {
-        ulength = 0;
-    }
-    hidl_vec<KeyParameter> result;
-    result.resize(ulength);
-    for (size_t i = 0; i < ulength; ++i) {
-        auto param = readKeyParameterFromParcel(in);
-        if (!param.isOk()) {
-            ALOGE("Error reading KeyParameter from parcel");
-            return {};
-        }
-        result[i] = param.value();
-    }
-    return result;
-}
-
-android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params,
-                                        android::Parcel* out) {
-    int32_t size = int32_t(std::min<size_t>(params.size(), std::numeric_limits<int32_t>::max()));
-
-    auto rc = out->writeInt32(size);
-    if (rc != ::android::OK) return rc;
-    for (int32_t i = 0; i < size; ++i) {
-        rc = out->writeInt32(1);  // writeTypedObject presence flag.
-        if (rc != ::android::OK) return rc;
-        rc = writeKeyParameterToParcel(params[i], out);
-        if (rc != ::android::OK) return rc;
-    }
-    return rc;
-}
-
-hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in) {
-    hidl_vec<hidl_vec<uint8_t>> result;
-
-    ssize_t count = in.readInt32();
-    size_t ucount = count;
-    if (count <= 0) {
-        return result;
-    }
-
-    result.resize(ucount);
-
-    for (size_t i = 0; i < ucount; ++i) {
-        result[i] = readKeymasterBlob(in);
-    }
-    return result;
-};
-
-android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs,
-                                                android::Parcel* out) {
-    int32_t count = int32_t(std::min<size_t>(certs.size(), std::numeric_limits<int32_t>::max()));
-    auto rc = out->writeInt32(count);
-
-    for (int32_t i = 0; i < count; ++i) {
-        rc = writeKeymasterBlob(certs[i], out);
-        if (rc != ::android::OK) return rc;
-    }
-    return rc;
-}
-
-};  // namespace keystore
-
-// Implementation for  keystore parcelables.
-// TODO: split implementation into separate classes
-namespace android {
-namespace security {
-namespace keymaster {
-
-using ::android::status_t;
-using ::keystore::ErrorCode;
-
-ExportResult::ExportResult() : resultCode() {}
-
-ExportResult::~ExportResult() {}
-
-status_t ExportResult::readFromParcel(const Parcel* inn) {
-    const Parcel& in = *inn;
-    resultCode = ErrorCode(in.readInt32());
-    exportData = keystore::readKeymasterBlob(in);
-    return OK;
-}
-
-status_t ExportResult::writeToParcel(Parcel* out) const {
-    out->writeInt32(resultCode.getErrorCode());
-    return keystore::writeKeymasterBlob(exportData, out);
-}
-
-status_t KeyCharacteristics::readFromParcel(const Parcel* in) {
-    softwareEnforced.readFromParcel(in);
-    return hardwareEnforced.readFromParcel(in);
-}
-
-status_t KeyCharacteristics::writeToParcel(Parcel* out) const {
-    softwareEnforced.writeToParcel(out);
-    return hardwareEnforced.writeToParcel(out);
-}
-
-status_t KeymasterBlob::readFromParcel(const Parcel* in) {
-    data_ = keystore::readKeymasterBlob(*in);
-    return OK;
-}
-
-status_t KeymasterBlob::writeToParcel(Parcel* out) const {
-    return keystore::writeKeymasterBlob(data_, out);
-}
-
-status_t KeymasterCertificateChain::readFromParcel(const Parcel* in) {
-    chain = keystore::readCertificateChainFromParcel(*in);
-    return OK;
-}
-
-status_t KeymasterCertificateChain::writeToParcel(Parcel* out) const {
-    return keystore::writeCertificateChainToParcel(chain, out);
-}
-
-}  // namespace keymaster
-}  // namespace security
-
-}  // namespace android
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.h b/keystore/keystore_aidl_hidl_marshalling_utils.h
deleted file mode 100644
index ea72197..0000000
--- a/keystore/keystore_aidl_hidl_marshalling_utils.h
+++ /dev/null
@@ -1,79 +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_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
-#define KEYSTORE_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
-
-#include <utility>
-
-#include <binder/Parcel.h>
-
-#include <keystore/keymaster_types.h>
-
-namespace keystore {
-
-template <typename Fn, typename... Args>
-inline auto nullable(Fn fn, const android::Parcel& in, Args&&... args)
-    -> NullOr<decltype(fn(in, std::forward<Args>(args)...))> {
-    if (in.readInt32() != 1) {
-        return {};
-    }
-
-    return fn(in, std::forward<Args>(args)...);
-}
-template <typename Fn, typename Arg>
-inline android::status_t nullable(Fn fn, const NullOr<Arg>& arg, android::Parcel* out) {
-    if (!arg.isOk()) {
-        return out->writeInt32(0);
-    }
-    auto rc = out->writeInt32(1);
-    if (rc != ::android::OK) return rc;
-
-    return fn(arg.value(), out);
-}
-template <typename Fn, typename Arg>
-inline android::status_t nullable(Fn fn, Arg&& arg, android::Parcel* out) {
-    auto rc = out->writeInt32(1);
-    if (rc != ::android::OK) return rc;
-
-    return fn(std::forward<Arg>(arg), out);
-}
-
-inline android::status_t nullable(android::Parcel* out) {
-    return out->writeInt32(0);
-}
-
-/**
- * makes a copy only if inPlace is false
- */
-hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in);
-android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out);
-
-NullOr<hidl_vec<uint8_t>> readBlobAsByteArray(const android::Parcel& in, bool inPlace = true);
-android::status_t writeBlobAsByteArray(const NullOr<const hidl_vec<uint8_t>&>& blob,
-                                       android::Parcel* out);
-
-NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in);
-android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out);
-
-hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in);
-android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params, android::Parcel* out);
-
-hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in);
-}
-
-#endif  // KEYSTORE_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
index 3d9e87e..ccd3808 100644
--- a/keystore/keystore_attestation_id.cpp
+++ b/keystore/keystore_attestation_id.cpp
@@ -271,7 +271,7 @@
 
     if (uid == AID_SYSTEM) {
         /* Use a fixed ID for system callers */
-        auto pinfo = std::make_unique<KeyAttestationPackageInfo>(
+        auto pinfo = std::make_optional<KeyAttestationPackageInfo>(
             String16(kAttestationSystemPackageName), 1 /* version code */,
             std::make_shared<KeyAttestationPackageInfo::SignaturesVector>());
         key_attestation_id = KeyAttestationApplicationId(std::move(pinfo));
@@ -284,7 +284,7 @@
         if (!status.isOk()) {
             ALOGW("package manager request for key attestation ID failed with: %s %d",
                   status.exceptionMessage().string(), status.exceptionCode());
-            auto pinfo = std::make_unique<KeyAttestationPackageInfo>(
+            auto pinfo = std::make_optional<KeyAttestationPackageInfo>(
                 String16(kUnknownPackageName), 1 /* version code */,
                 std::make_shared<KeyAttestationPackageInfo::SignaturesVector>());
             key_attestation_id = KeyAttestationApplicationId(std::move(pinfo));
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
deleted file mode 100644
index 428a9bc..0000000
--- a/keystore/keystore_cli.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2009 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 <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#include <vector>
-
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <keystore/keystore.h>
-
-using namespace android;
-using namespace keystore;
-using android::security::keystore::IKeystoreService;
-
-static const char* responses[] = {
-    nullptr,
-    /* [NO_ERROR]           = */ "No error",
-    /* [LOCKED]             = */ "Locked",
-    /* [UNINITIALIZED]      = */ "Uninitialized",
-    /* [SYSTEM_ERROR]       = */ "System error",
-    /* [PROTOCOL_ERROR]     = */ "Protocol error",
-    /* [PERMISSION_DENIED]  = */ "Permission denied",
-    /* [KEY_NOT_FOUND]      = */ "Key not found",
-    /* [VALUE_CORRUPTED]    = */ "Value corrupted",
-    /* [UNDEFINED_ACTION]   = */ "Undefined action",
-    /* [WRONG_PASSWORD]     = */ "Wrong password (last chance)",
-    /* [WRONG_PASSWORD + 1] = */ "Wrong password (2 tries left)",
-    /* [WRONG_PASSWORD + 2] = */ "Wrong password (3 tries left)",
-    /* [WRONG_PASSWORD + 3] = */ "Wrong password (4 tries left)",
-};
-
-#define SINGLE_ARG_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
-                return 1; \
-            } \
-            int32_t ret = -1; \
-            service->cmd(String16(argv[2]), &ret); \
-            if (ret < 0) { \
-                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
-                return 1; \
-            } else { \
-                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define SINGLE_INT_ARG_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
-                return 1; \
-            } \
-            int32_t ret = -1; \
-            service->cmd(atoi(argv[2]), &ret); \
-            if (ret < 0) { \
-                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
-                return 1; \
-            } else { \
-                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define SINGLE_ARG_PLUS_UID_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name> <uid>\n", argv[0]); \
-                return 1; \
-            } \
-            int uid = -1; \
-            if (argc > 3) { \
-                uid = atoi(argv[3]); \
-                fprintf(stderr, "Running as uid %d\n", uid); \
-            } \
-            int32_t ret = -1; \
-            service->cmd(String16(argv[2]), uid, &ret); \
-            if (ret < 0) { \
-                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
-                return 1; \
-            } else { \
-                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define SINGLE_ARG_PLUS_UID_DATA_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name> <uid>\n", argv[0]); \
-                return 1; \
-            } \
-            std::vector<uint8_t> data; \
-            int uid = -1; \
-            if (argc > 3) { \
-                uid = atoi(argv[3]); \
-                fprintf(stderr, "Running as uid %d\n", uid); \
-            } \
-            ::android::binder::Status ret = service->cmd(String16(argv[2]), uid, &data); \
-            if (!ret.isOk()) { \
-                fprintf(stderr, "Exception code: %d\n", ret.exceptionCode()); \
-                return 1; \
-            } else { \
-                fwrite(&data[0], data.size(), 1, stdout); \
-                fflush(stdout); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define STRING_ARG_DATA_STDIN_INT_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
-                return 1; \
-            } \
-            uint8_t* data; \
-            size_t dataSize; \
-            read_input(&data, &dataSize); \
-            int32_t ret = -1; \
-            service->cmd(String16(argv[2]), data, dataSize, &ret); \
-            if (ret < 0) { \
-                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
-                return 1; \
-            } else { \
-                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-#define SINGLE_ARG_DATA_RETURN(cmd) \
-    do { \
-        if (strcmp(argv[1], #cmd) == 0) { \
-            if (argc < 3) { \
-                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
-                return 1; \
-            } \
-            std::vector<uint8_t> data; \
-            ::android::binder::Status ret = service->cmd(String16(argv[2]), &data); \
-            if (!ret.isOk()) { \
-                fprintf(stderr, "Exception code: %d\n", ret.exceptionCode()); \
-                return 1; \
-            } else { \
-                fwrite(&data[0], data.size(), 1, stdout); \
-                fflush(stdout); \
-                return 0; \
-            } \
-        } \
-    } while (0)
-
-static int list(const sp<IKeystoreService>& service, const String16& name, int uid) {
-    std::vector<String16> matches;
-    ::android::binder::Status ret = service->list(name, uid, &matches);
-
-    if (!ret.isOk()) {
-        fprintf(stderr, "list: exception (%d)\n", ret.exceptionCode());
-        return 1;
-    } else {
-        std::vector<String16>::const_iterator it = matches.begin();
-        for (; it != matches.end(); ++it) {
-            printf("%s\n", String8(*it).string());
-        }
-        return 0;
-    }
-}
-
-int main(int argc, char* argv[])
-{
-    if (argc < 2) {
-        fprintf(stderr, "Usage: %s action [parameter ...]\n", argv[0]);
-        return 1;
-    }
-
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == nullptr) {
-        fprintf(stderr, "%s: error: could not connect to keystore service\n", argv[0]);
-        return 1;
-    }
-
-    /*
-     * All the commands should return a value
-     */
-
-    SINGLE_INT_ARG_INT_RETURN(getState);
-
-    SINGLE_ARG_PLUS_UID_DATA_RETURN(get);
-
-    // TODO: insert
-
-    SINGLE_ARG_PLUS_UID_INT_RETURN(del);
-
-    SINGLE_ARG_PLUS_UID_INT_RETURN(exist);
-
-    if (strcmp(argv[1], "list") == 0) {
-        return list(service, argc < 3 ? String16("") : String16(argv[2]),
-                argc < 4 ? -1 : atoi(argv[3]));
-    }
-
-    // TODO: notifyUserPasswordChanged
-
-    SINGLE_INT_ARG_INT_RETURN(lock);
-
-    // TODO: unlock
-
-    SINGLE_INT_ARG_INT_RETURN(isEmpty);
-
-    // TODO: generate
-
-    // TODO: grant
-
-    // TODO: ungrant
-
-    // TODO: getmtime
-
-    fprintf(stderr, "%s: unknown command: %s\n", argv[0], argv[1]);
-    return 1;
-}
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 4f69eb0..6e45ee2 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -15,6 +15,8 @@
 #include <chrono>
 #include <cstdio>
 #include <future>
+#include <iomanip>
+#include <iostream>
 #include <memory>
 #include <string>
 #include <vector>
@@ -24,38 +26,56 @@
 #include <base/strings/string_number_conversions.h>
 #include <base/strings/string_split.h>
 #include <base/strings/string_util.h>
-#include <base/strings/utf_string_conversions.h>
-#include <base/threading/platform_thread.h>
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_client_impl.h>
 
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <android/security/BnConfirmationPromptCallback.h>
-#include <android/security/keystore/IKeystoreService.h>
+#include <aidl/android/security/apc/BnConfirmationCallback.h>
+#include <aidl/android/security/apc/IProtectedConfirmation.h>
+#include <aidl/android/system/keystore2/IKeystoreService.h>
+#include <aidl/android/system/keystore2/ResponseCode.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <keymint_support/authorization_set.h>
 
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+#include <openssl/x509.h>
 
-//#include <keystore/keystore.h>
+#include "keystore_client.pb.h"
+
+namespace apc = ::aidl::android::security::apc;
+namespace keymint = ::aidl::android::hardware::security::keymint;
+namespace ks2 = ::aidl::android::system::keystore2;
 
 using base::CommandLine;
-using keystore::KeystoreClient;
-
-using android::sp;
-using android::String16;
-using android::security::keystore::IKeystoreService;
-using base::CommandLine;
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
+using keystore::EncryptedData;
 
 namespace {
-using namespace keystore;
 
 struct TestCase {
     std::string name;
     bool required_for_brillo_pts;
-    AuthorizationSet parameters;
+    keymint::AuthorizationSet parameters;
 };
 
+constexpr const char keystore2_service_name[] = "android.system.keystore2";
+
+int unwrapError(const ndk::ScopedAStatus& status) {
+    if (status.isOk()) return 0;
+    if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+        return status.getServiceSpecificError();
+    } else {
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+}
+
+ks2::KeyDescriptor keyDescriptor(const std::string& alias) {
+    return {
+        .domain = ks2::Domain::APP,
+        .nspace = -1,  // ignored - should be -1.
+        .alias = alias,
+        .blob = {},
+    };
+}
+
 void PrintUsageAndExit() {
     printf("Usage: keystore_client_v2 <command> [options]\n");
     printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>] [--test_for_0_3]\n"
@@ -78,52 +98,487 @@
     exit(1);
 }
 
-std::unique_ptr<KeystoreClient> CreateKeystoreInstance() {
-    return std::unique_ptr<KeystoreClient>(
-        static_cast<KeystoreClient*>(new keystore::KeystoreClientImpl));
+std::shared_ptr<ks2::IKeystoreService> CreateKeystoreInstance() {
+    ::ndk::SpAIBinder keystoreBinder(AServiceManager_checkService(keystore2_service_name));
+    auto result = ks2::IKeystoreService::fromBinder(keystoreBinder);
+    if (result) return result;
+    std::cerr << "Unable to connect to Keystore.";
+    exit(-1);
 }
 
-void PrintTags(const AuthorizationSet& parameters) {
-    for (auto iter = parameters.begin(); iter != parameters.end(); ++iter) {
-        auto tag_str = toString(iter->tag);
-        printf("  %s\n", tag_str.c_str());
+std::shared_ptr<ks2::IKeystoreSecurityLevel>
+GetSecurityLevelInterface(std::shared_ptr<ks2::IKeystoreService> keystore,
+                          keymint::SecurityLevel securitylevel) {
+    std::shared_ptr<ks2::IKeystoreSecurityLevel> sec_level;
+    auto rc = keystore->getSecurityLevel(securitylevel, &sec_level);
+    if (rc.isOk()) return sec_level;
+    std::cerr << "Unable to get security level interface from Keystore: " << rc.getDescription();
+    exit(-1);
+}
+
+bool isHardwareEnforced(const ks2::Authorization& a) {
+    return !(a.securityLevel == keymint::SecurityLevel::SOFTWARE ||
+             a.securityLevel == keymint::SecurityLevel::KEYSTORE);
+}
+
+void PrintTags(const std::vector<ks2::Authorization>& characteristics, bool printHardwareEnforced) {
+    for (const auto& a : characteristics) {
+        if (isHardwareEnforced(a) == printHardwareEnforced) {
+            std::cout << toString(a.keyParameter.tag) << "\n";
+        }
     }
 }
 
-void PrintKeyCharacteristics(const AuthorizationSet& hardware_enforced_characteristics,
-                             const AuthorizationSet& software_enforced_characteristics) {
+void PrintKeyCharacteristics(const std::vector<ks2::Authorization>& characteristics) {
     printf("Hardware:\n");
-    PrintTags(hardware_enforced_characteristics);
+    PrintTags(characteristics, true /* printHardwareEnforced */);
     printf("Software:\n");
-    PrintTags(software_enforced_characteristics);
+    PrintTags(characteristics, false /* printHardwareEnforced */);
 }
 
-bool TestKey(const std::string& name, bool required, const AuthorizationSet& parameters) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result =
-        keystore->generateKey("tmp", parameters, 0 /*flags*/, &hardware_enforced_characteristics,
-                              &software_enforced_characteristics);
+const char kEncryptSuffix[] = "_ENC";
+const char kAuthenticateSuffix[] = "_AUTH";
+constexpr uint32_t kAESKeySize = 256;      // bits
+constexpr uint32_t kHMACKeySize = 256;     // bits
+constexpr uint32_t kHMACOutputSize = 256;  // bits
+
+bool verifyEncryptionKeyAttributes(const std::vector<ks2::Authorization> authorizations) {
+    bool verified = true;
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::ALGORITHM &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::algorithm>(
+                           keymint::Algorithm::AES);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::KEY_SIZE &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
+                           kAESKeySize);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::BLOCK_MODE &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::blockMode>(
+                           keymint::BlockMode::CBC);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::PADDING &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::paddingMode>(
+                           keymint::PaddingMode::PKCS7);
+        });
+
+    return verified;
+}
+
+bool verifyAuthenticationKeyAttributes(const std::vector<ks2::Authorization> authorizations) {
+    bool verified = true;
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::ALGORITHM &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::algorithm>(
+                           keymint::Algorithm::HMAC);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::KEY_SIZE &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
+                           kHMACKeySize);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::MIN_MAC_LENGTH &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
+                           kHMACOutputSize);
+        });
+
+    verified =
+        verified &&
+        std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
+            return a.keyParameter.tag == keymint::Tag::DIGEST &&
+                   a.keyParameter.value ==
+                       keymint::KeyParameterValue::make<keymint::KeyParameterValue::digest>(
+                           keymint::Digest::SHA_2_256);
+        });
+    return verified;
+}
+
+std::variant<int, ks2::KeyEntryResponse>
+loadOrCreateAndVerifyEncryptionKey(const std::string& name, keymint::SecurityLevel securityLevel,
+                                   bool create) {
+    auto keystore = CreateKeystoreInstance();
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    bool foundKey = true;
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        auto error = unwrapError(rc);
+        if (ks2::ResponseCode(error) == ks2::ResponseCode::KEY_NOT_FOUND && create) {
+            foundKey = false;
+        } else {
+            std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+            return error;
+        }
+    }
+
+    if (!foundKey) {
+        auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
+        auto params = keymint::AuthorizationSetBuilder()
+                          .AesEncryptionKey(kAESKeySize)
+                          .Padding(keymint::PaddingMode::PKCS7)
+                          .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC)
+                          .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
+
+        ks2::KeyMetadata keyMetadata;
+
+        rc = sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */,
+                                    params.vector_data(), 0 /* flags */, {} /* entropy */,
+                                    &keyMetadata);
+        if (!rc.isOk()) {
+            std::cerr << "Failed to generate key: " << rc.getDescription() << std::endl;
+            return unwrapError(rc);
+        }
+
+        rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+        if (!rc.isOk()) {
+            std::cerr << "Failed to get key entry (second try): " << rc.getDescription()
+                      << std::endl;
+            return unwrapError(rc);
+        }
+    }
+
+    if (!verifyEncryptionKeyAttributes(keyEntryResponse.metadata.authorizations)) {
+        std::cerr << "Key has wrong set of parameters." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::INVALID_ARGUMENT);
+    }
+
+    return keyEntryResponse;
+}
+
+std::variant<int, ks2::KeyEntryResponse>
+loadOrCreateAndVerifyAuthenticationKey(const std::string& name,
+                                       keymint::SecurityLevel securityLevel, bool create) {
+    auto keystore = CreateKeystoreInstance();
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    bool foundKey = true;
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        auto error = unwrapError(rc);
+        if (ks2::ResponseCode(error) == ks2::ResponseCode::KEY_NOT_FOUND && create) {
+            foundKey = false;
+        } else {
+            std::cerr << "Failed to get HMAC key entry: " << rc.getDescription() << std::endl;
+            return error;
+        }
+    }
+
+    if (!foundKey) {
+        auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
+        auto params = keymint::AuthorizationSetBuilder()
+                          .HmacKey(kHMACKeySize)
+                          .Digest(keymint::Digest::SHA_2_256)
+                          .Authorization(keymint::TAG_MIN_MAC_LENGTH, kHMACOutputSize)
+                          .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
+
+        ks2::KeyMetadata keyMetadata;
+
+        rc = sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */,
+                                    params.vector_data(), 0 /* flags */, {} /* entropy */,
+                                    &keyMetadata);
+        if (!rc.isOk()) {
+            std::cerr << "Failed to generate HMAC key: " << rc.getDescription() << std::endl;
+            return unwrapError(rc);
+        }
+
+        rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+        if (!rc.isOk()) {
+            std::cerr << "Failed to get HMAC key entry (second try): " << rc.getDescription()
+                      << std::endl;
+            return unwrapError(rc);
+        }
+    }
+
+    if (!verifyAuthenticationKeyAttributes(keyEntryResponse.metadata.authorizations)) {
+        std::cerr << "Key has wrong set of parameters." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::INVALID_ARGUMENT);
+    }
+
+    return keyEntryResponse;
+}
+
+std::variant<int, std::vector<uint8_t>>
+encryptWithAuthentication(const std::string& name, const std::vector<uint8_t>& data,
+                          keymint::SecurityLevel securityLevel) {
+    // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
+    // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
+    // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
+    // because hardware support for GCM is not mandatory for all Brillo devices.
+    std::string encryption_key_name = name + kEncryptSuffix;
+    auto encryption_key_result =
+        loadOrCreateAndVerifyEncryptionKey(encryption_key_name, securityLevel, true /* create */);
+    if (auto error = std::get_if<int>(&encryption_key_result)) {
+        return *error;
+    }
+    auto encryption_key = std::get<ks2::KeyEntryResponse>(encryption_key_result);
+
+    std::string authentication_key_name = name + kAuthenticateSuffix;
+    auto authentication_key_result = loadOrCreateAndVerifyAuthenticationKey(
+        authentication_key_name, securityLevel, true /* create */);
+    if (auto error = std::get_if<int>(&authentication_key_result)) {
+        return *error;
+    }
+    auto authentication_key = std::get<ks2::KeyEntryResponse>(authentication_key_result);
+
+    ks2::CreateOperationResponse encOperationResponse;
+    auto encrypt_params = keymint::AuthorizationSetBuilder()
+                              .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::ENCRYPT)
+                              .Padding(keymint::PaddingMode::PKCS7)
+                              .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
+
+    auto rc = encryption_key.iSecurityLevel->createOperation(
+        encryption_key.metadata.key, encrypt_params.vector_data(), false /* forced */,
+        &encOperationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to begin encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    std::optional<std::vector<uint8_t>> optCiphertext;
+
+    rc = encOperationResponse.iOperation->finish(data, {}, &optCiphertext);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    std::vector<uint8_t> initVector;
+    if (auto params = encOperationResponse.parameters) {
+        for (auto& p : params->keyParameter) {
+            if (auto iv = keymint::authorizationValue(keymint::TAG_NONCE, p)) {
+                initVector = std::move(iv->get());
+                break;
+            }
+        }
+        if (initVector.empty()) {
+            std::cerr << "Encryption operation did not return an IV." << std::endl;
+            return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+        }
+    }
+
+    if (!optCiphertext) {
+        std::cerr << "Encryption succeeded but no ciphertext returned." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    auto ciphertext = std::move(*optCiphertext);
+    auto toBeSigned = initVector;
+    toBeSigned.insert(toBeSigned.end(), ciphertext.begin(), ciphertext.end());
+
+    ks2::CreateOperationResponse signOperationResponse;
+    auto sign_params = keymint::AuthorizationSetBuilder()
+                           .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::SIGN)
+                           .Digest(keymint::Digest::SHA_2_256)
+                           .Authorization(keymint::TAG_MAC_LENGTH, kHMACOutputSize);
+
+    rc = authentication_key.iSecurityLevel->createOperation(
+        authentication_key.metadata.key, sign_params.vector_data(), false /* forced */,
+        &signOperationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to begin signing operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    std::optional<std::vector<uint8_t>> optMac;
+
+    rc = signOperationResponse.iOperation->finish(toBeSigned, {}, &optMac);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    if (!optMac) {
+        std::cerr << "Signing succeeded but no MAC returned." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    auto mac = std::move(*optMac);
+
+    EncryptedData protobuf;
+    protobuf.set_init_vector(initVector.data(), initVector.size());
+    protobuf.set_authentication_data(mac.data(), mac.size());
+    protobuf.set_encrypted_data(ciphertext.data(), ciphertext.size());
+    std::string resultString;
+    if (!protobuf.SerializeToString(&resultString)) {
+        std::cerr << "Encrypt: Failed to serialize EncryptedData protobuf.";
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    std::vector<uint8_t> result(reinterpret_cast<const uint8_t*>(resultString.data()),
+                                reinterpret_cast<const uint8_t*>(resultString.data()) +
+                                    resultString.size());
+    return result;
+}
+
+std::variant<int, std::vector<uint8_t>>
+decryptWithAuthentication(const std::string& name, const std::vector<uint8_t>& data) {
+
+    // Decode encrypted data
+    EncryptedData protobuf;
+    if (!protobuf.ParseFromArray(data.data(), data.size())) {
+        std::cerr << "Decrypt: Failed to parse EncryptedData protobuf." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    // Load encryption and authentication keys.
+    std::string encryption_key_name = name + kEncryptSuffix;
+    auto encryption_key_result = loadOrCreateAndVerifyEncryptionKey(
+        encryption_key_name, keymint::SecurityLevel::KEYSTORE /* ignored */, false /* create */);
+    if (auto error = std::get_if<int>(&encryption_key_result)) {
+        return *error;
+    }
+    auto encryption_key = std::get<ks2::KeyEntryResponse>(encryption_key_result);
+
+    std::string authentication_key_name = name + kAuthenticateSuffix;
+    auto authentication_key_result = loadOrCreateAndVerifyAuthenticationKey(
+        authentication_key_name, keymint::SecurityLevel::KEYSTORE /* ignored */,
+        false /* create */);
+    if (auto error = std::get_if<int>(&authentication_key_result)) {
+        return *error;
+    }
+    auto authentication_key = std::get<ks2::KeyEntryResponse>(authentication_key_result);
+
+    // Begin authentication operation
+    ks2::CreateOperationResponse signOperationResponse;
+    auto sign_params = keymint::AuthorizationSetBuilder()
+                           .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::VERIFY)
+                           .Digest(keymint::Digest::SHA_2_256)
+                           .Authorization(keymint::TAG_MAC_LENGTH, kHMACOutputSize);
+
+    auto rc = authentication_key.iSecurityLevel->createOperation(
+        authentication_key.metadata.key, sign_params.vector_data(), false /* forced */,
+        &signOperationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to begin verify operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    const uint8_t* p = reinterpret_cast<const uint8_t*>(protobuf.init_vector().data());
+    std::vector<uint8_t> toBeVerified(p, p + protobuf.init_vector().size());
+
+    p = reinterpret_cast<const uint8_t*>(protobuf.encrypted_data().data());
+    toBeVerified.insert(toBeVerified.end(), p, p + protobuf.encrypted_data().size());
+
+    p = reinterpret_cast<const uint8_t*>(protobuf.authentication_data().data());
+    std::vector<uint8_t> signature(p, p + protobuf.authentication_data().size());
+
+    std::optional<std::vector<uint8_t>> optOut;
+    rc = signOperationResponse.iOperation->finish(toBeVerified, signature, &optOut);
+    if (!rc.isOk()) {
+        std::cerr << "Decrypt: HMAC verification failed: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    // Begin decryption operation
+    ks2::CreateOperationResponse encOperationResponse;
+    auto encrypt_params = keymint::AuthorizationSetBuilder()
+                              .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::DECRYPT)
+                              .Authorization(keymint::TAG_NONCE, protobuf.init_vector().data(),
+                                             protobuf.init_vector().size())
+                              .Padding(keymint::PaddingMode::PKCS7)
+                              .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
+
+    rc = encryption_key.iSecurityLevel->createOperation(encryption_key.metadata.key,
+                                                        encrypt_params.vector_data(),
+                                                        false /* forced */, &encOperationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to begin encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    std::optional<std::vector<uint8_t>> optPlaintext;
+
+    p = reinterpret_cast<const uint8_t*>(protobuf.encrypted_data().data());
+    std::vector<uint8_t> cyphertext(p, p + protobuf.encrypted_data().size());
+
+    rc = encOperationResponse.iOperation->finish(cyphertext, {}, &optPlaintext);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    if (!optPlaintext) {
+        std::cerr << "Decryption succeeded but no plaintext returned." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    return *optPlaintext;
+}
+
+bool TestKey(const std::string& name, bool required,
+             const std::vector<keymint::KeyParameter>& parameters) {
+    auto keystore = CreateKeystoreInstance();
+    auto sec_level =
+        GetSecurityLevelInterface(keystore, keymint::SecurityLevel::TRUSTED_ENVIRONMENT);
+
+    ks2::KeyDescriptor keyDescriptor = {
+        .domain = ks2::Domain::APP,
+        .nspace = -1,
+        .alias = "tmp",
+        .blob = {},
+    };
+
+    ks2::KeyMetadata keyMetadata;
+
+    auto rc = sec_level->generateKey(keyDescriptor, {} /* attestationKey */, parameters,
+                                     0 /* flags */, {} /* entropy */, &keyMetadata);
     const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
-    if (!result.isOk()) {
-        LOG(ERROR) << "Failed to generate key: " << result;
+    if (!rc.isOk()) {
+        LOG(ERROR) << "Failed to generate key: " << rc.getDescription();
         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
     }
-    result = keystore->deleteKey("tmp");
-    if (!result.isOk()) {
-        LOG(ERROR) << "Failed to delete key: " << result;
+
+    rc = keystore->deleteKey(keyDescriptor);
+    if (!rc.isOk()) {
+        LOG(ERROR) << "Failed to delete key: " << rc.getDescription();
         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
     }
     printf("===============================================================\n");
     printf("%s Key Characteristics:\n", name.c_str());
-    PrintKeyCharacteristics(hardware_enforced_characteristics, software_enforced_characteristics);
-    bool hardware_backed = (hardware_enforced_characteristics.size() > 0);
-    if (software_enforced_characteristics.GetTagCount(TAG_ALGORITHM) > 0 ||
-        software_enforced_characteristics.GetTagCount(TAG_KEY_SIZE) > 0 ||
-        software_enforced_characteristics.GetTagCount(TAG_RSA_PUBLIC_EXPONENT) > 0) {
+    PrintKeyCharacteristics(keyMetadata.authorizations);
+    bool hardware_backed = std::any_of(keyMetadata.authorizations.begin(),
+                                       keyMetadata.authorizations.end(), isHardwareEnforced);
+    if (std::any_of(keyMetadata.authorizations.begin(), keyMetadata.authorizations.end(),
+                    [&](const auto& a) {
+                        return !isHardwareEnforced(a) &&
+                               (a.keyParameter.tag == keymint::Tag::ALGORITHM ||
+                                a.keyParameter.tag == keymint::Tag::KEY_SIZE ||
+                                a.keyParameter.tag == keymint::Tag::RSA_PUBLIC_EXPONENT);
+                    })) {
         VLOG(1) << "Hardware-backed key but required characteristics enforced in software.";
         hardware_backed = false;
     }
@@ -137,60 +592,64 @@
     return (hardware_backed || !required);
 }
 
-AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
-    AuthorizationSetBuilder parameters;
+keymint::AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
+    keymint::AuthorizationSetBuilder parameters;
     parameters.RsaSigningKey(key_size, 65537)
-        .Digest(Digest::SHA_2_256)
-        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
-        .Padding(PaddingMode::RSA_PSS)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Digest(keymint::Digest::SHA_2_256)
+        .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
+        .Padding(keymint::PaddingMode::RSA_PSS)
+        .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     if (!sha256_only) {
-        parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
+        parameters.Digest(keymint::Digest::SHA_2_224)
+            .Digest(keymint::Digest::SHA_2_384)
+            .Digest(keymint::Digest::SHA_2_512);
     }
     return std::move(parameters);
 }
 
-AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
-    AuthorizationSetBuilder parameters;
+keymint::AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
+    keymint::AuthorizationSetBuilder parameters;
     parameters.RsaEncryptionKey(key_size, 65537)
-        .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
-        .Padding(PaddingMode::RSA_OAEP)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
+        .Padding(keymint::PaddingMode::RSA_OAEP)
+        .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     return std::move(parameters);
 }
 
-AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
-    AuthorizationSetBuilder parameters;
+keymint::AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
+    keymint::AuthorizationSetBuilder parameters;
     parameters.EcdsaSigningKey(key_size)
-        .Digest(Digest::SHA_2_256)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Digest(keymint::Digest::SHA_2_256)
+        .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     if (!sha256_only) {
-        parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
+        parameters.Digest(keymint::Digest::SHA_2_224)
+            .Digest(keymint::Digest::SHA_2_384)
+            .Digest(keymint::Digest::SHA_2_512);
     }
     return std::move(parameters);
 }
 
-AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
-    AuthorizationSetBuilder parameters;
-    parameters.AesEncryptionKey(key_size).Authorization(TAG_NO_AUTH_REQUIRED);
+keymint::AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
+    keymint::AuthorizationSetBuilder parameters;
+    parameters.AesEncryptionKey(key_size).Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     if (with_gcm_mode) {
-        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
-            .Authorization(TAG_MIN_MAC_LENGTH, 128);
+        parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::GCM)
+            .Authorization(keymint::TAG_MIN_MAC_LENGTH, 128);
     } else {
-        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
-        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
-        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CTR);
-        parameters.Padding(PaddingMode::NONE);
+        parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::ECB);
+        parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
+        parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CTR);
+        parameters.Padding(keymint::PaddingMode::NONE);
     }
     return std::move(parameters);
 }
 
-AuthorizationSet GetHMACParameters(uint32_t key_size, Digest digest) {
-    AuthorizationSetBuilder parameters;
+keymint::AuthorizationSet GetHMACParameters(uint32_t key_size, keymint::Digest digest) {
+    keymint::AuthorizationSetBuilder parameters;
     parameters.HmacKey(key_size)
         .Digest(digest)
-        .Authorization(TAG_MIN_MAC_LENGTH, 224)
-        .Authorization(TAG_NO_AUTH_REQUIRED);
+        .Authorization(keymint::TAG_MIN_MAC_LENGTH, 224)
+        .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     return std::move(parameters);
 }
 
@@ -212,12 +671,12 @@
         {"AES-256", true, GetAESParameters(256, false)},
         {"AES-128-GCM", false, GetAESParameters(128, true)},
         {"AES-256-GCM", false, GetAESParameters(256, true)},
-        {"HMAC-SHA256-16", true, GetHMACParameters(16, Digest::SHA_2_256)},
-        {"HMAC-SHA256-32", true, GetHMACParameters(32, Digest::SHA_2_256)},
-        {"HMAC-SHA256-64", false, GetHMACParameters(64, Digest::SHA_2_256)},
-        {"HMAC-SHA224-32", false, GetHMACParameters(32, Digest::SHA_2_224)},
-        {"HMAC-SHA384-32", false, GetHMACParameters(32, Digest::SHA_2_384)},
-        {"HMAC-SHA512-32", false, GetHMACParameters(32, Digest::SHA_2_512)},
+        {"HMAC-SHA256-16", true, GetHMACParameters(16, keymint::Digest::SHA_2_256)},
+        {"HMAC-SHA256-32", true, GetHMACParameters(32, keymint::Digest::SHA_2_256)},
+        {"HMAC-SHA256-64", false, GetHMACParameters(64, keymint::Digest::SHA_2_256)},
+        {"HMAC-SHA224-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_224)},
+        {"HMAC-SHA384-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_384)},
+        {"HMAC-SHA512-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_512)},
     };
     return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]);
 }
@@ -243,7 +702,8 @@
             continue;
         }
         ++test_count;
-        if (!TestKey(test_case.name, test_case.required_for_brillo_pts, test_case.parameters)) {
+        if (!TestKey(test_case.name, test_case.required_for_brillo_pts,
+                     test_case.parameters.vector_data())) {
             VLOG(1) << "Test failed: " << test_case.name;
             ++fail_count;
         }
@@ -262,248 +722,274 @@
     return 0;
 }
 
-std::string ReadFile(const std::string& filename) {
+std::vector<uint8_t> ReadFile(const std::string& filename) {
     std::string content;
     base::FilePath path(filename);
     if (!base::ReadFileToString(path, &content)) {
         printf("Failed to read file: %s\n", filename.c_str());
         exit(1);
     }
-    return content;
+    std::vector<uint8_t> buffer(reinterpret_cast<const uint8_t*>(content.data()),
+                                reinterpret_cast<const uint8_t*>(content.data()) + content.size());
+    return buffer;
 }
 
-void WriteFile(const std::string& filename, const std::string& content) {
+void WriteFile(const std::string& filename, const std::vector<uint8_t>& content) {
     base::FilePath path(filename);
     int size = content.size();
-    if (base::WriteFile(path, content.data(), size) != size) {
+    if (base::WriteFile(path, reinterpret_cast<const char*>(content.data()), size) != size) {
         printf("Failed to write file: %s\n", filename.c_str());
         exit(1);
     }
 }
 
-int AddEntropy(const std::string& input, int32_t flags) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->addRandomNumberGeneratorEntropy(input, flags).getErrorCode();
-    printf("AddEntropy: %d\n", result);
-    return result;
-}
-
 // Note: auth_bound keys created with this tool will not be usable.
-int GenerateKey(const std::string& name, int32_t flags, bool auth_bound) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    AuthorizationSetBuilder params;
+int GenerateKey(const std::string& name, keymint::SecurityLevel securityLevel, bool auth_bound) {
+    auto keystore = CreateKeystoreInstance();
+    auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
+    keymint::AuthorizationSetBuilder params;
     params.RsaSigningKey(2048, 65537)
-        .Digest(Digest::SHA_2_224)
-        .Digest(Digest::SHA_2_256)
-        .Digest(Digest::SHA_2_384)
-        .Digest(Digest::SHA_2_512)
-        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
-        .Padding(PaddingMode::RSA_PSS);
+        .Digest(keymint::Digest::SHA_2_224)
+        .Digest(keymint::Digest::SHA_2_256)
+        .Digest(keymint::Digest::SHA_2_384)
+        .Digest(keymint::Digest::SHA_2_512)
+        .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
+        .Padding(keymint::PaddingMode::RSA_PSS);
     if (auth_bound) {
         // Gatekeeper normally generates the secure user id.
         // Using zero allows the key to be created, but it will not be usuable.
-        params.Authorization(TAG_USER_SECURE_ID, 0);
+        params.Authorization(keymint::TAG_USER_SECURE_ID, 0);
     } else {
-        params.Authorization(TAG_NO_AUTH_REQUIRED);
+        params.Authorization(keymint::TAG_NO_AUTH_REQUIRED);
     }
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result = keystore->generateKey(name, params, flags, &hardware_enforced_characteristics,
-                                        &software_enforced_characteristics);
-    printf("GenerateKey: %d\n", result.getErrorCode());
-    if (result.isOk()) {
-        PrintKeyCharacteristics(hardware_enforced_characteristics,
-                                software_enforced_characteristics);
+
+    ks2::KeyMetadata keyMetadata;
+
+    auto rc =
+        sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */, params.vector_data(),
+                               0 /* flags */, {} /* entropy */, &keyMetadata);
+
+    if (rc.isOk()) {
+        std::cerr << "GenerateKey failed: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    return result.getErrorCode();
+    std::cout << "GenerateKey: success" << std::endl;
+    PrintKeyCharacteristics(keyMetadata.authorizations);
+    return 0;
 }
 
 int GetCharacteristics(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
-                                                  &software_enforced_characteristics);
-    printf("GetCharacteristics: %d\n", result.getErrorCode());
-    if (result.isOk()) {
-        PrintKeyCharacteristics(hardware_enforced_characteristics,
-                                software_enforced_characteristics);
+    auto keystore = CreateKeystoreInstance();
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    return result.getErrorCode();
+
+    std::cout << "GetCharacteristics: success" << std::endl;
+    PrintKeyCharacteristics(keyEntryResponse.metadata.authorizations);
+    return 0;
 }
 
 int ExportKey(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    std::string data;
-    int32_t result = keystore->exportKey(KeyFormat::X509, name, &data).getErrorCode();
-    printf("ExportKey: %d (%zu)\n", result, data.size());
-    return result;
+    auto keystore = CreateKeystoreInstance();
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
+    }
+
+    if (auto cert = keyEntryResponse.metadata.certificate) {
+        std::cout << "ExportKey: Got certificate of length (" << cert->size() << ")" << std::endl;
+    } else {
+        std::cout << "ExportKey: Key entry does not have a public component.\n";
+        std::cout << "Possibly a symmetric key?" << std::endl;
+    }
+    return 0;
 }
 
 int DeleteKey(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->deleteKey(name).getErrorCode();
-    printf("DeleteKey: %d\n", result);
-    return result;
-}
+    auto keystore = CreateKeystoreInstance();
 
-int DeleteAllKeys() {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->deleteAllKeys().getErrorCode();
-    printf("DeleteAllKeys: %d\n", result);
-    return result;
+    auto rc = keystore->deleteKey(keyDescriptor(name));
+    if (!rc.isOk()) {
+        std::cerr << "Failed to delete key: " << rc.getDescription();
+        return unwrapError(rc);
+    }
+    std::cout << "Successfully deleted key." << std::endl;
+    return 0;
 }
 
 int DoesKeyExist(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    printf("DoesKeyExist: %s\n", keystore->doesKeyExist(name) ? "yes" : "no");
+    auto keystore = CreateKeystoreInstance();
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    bool keyExists = true;
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        auto responseCode = unwrapError(rc);
+        if (ks2::ResponseCode(responseCode) == ks2::ResponseCode::KEY_NOT_FOUND) {
+            keyExists = false;
+        } else {
+            std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+            return unwrapError(rc);
+        }
+    }
+    std::cout << "DoesKeyExists: " << (keyExists ? "yes" : "no") << std::endl;
     return 0;
 }
 
-int List(const std::string& prefix) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    std::vector<std::string> key_list;
-    if (!keystore->listKeys(prefix, &key_list)) {
-        printf("ListKeys failed.\n");
-        return 1;
+int List() {
+    auto keystore = CreateKeystoreInstance();
+    std::vector<ks2::KeyDescriptor> key_list;
+    auto rc = keystore->listEntries(ks2::Domain::APP, -1 /* nspace ignored */, &key_list);
+    if (!rc.isOk()) {
+        std::cerr << "ListKeys failed: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    printf("Keys:\n");
-    for (const auto& key_name : key_list) {
-        printf("  %s\n", key_name.c_str());
-    }
-    return 0;
-}
-
-int ListAppsWithKeys() {
-
-    sp<android::IServiceManager> sm = android::defaultServiceManager();
-    sp<android::IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = android::interface_cast<IKeystoreService>(binder);
-    if (service == nullptr) {
-        fprintf(stderr, "Error connecting to keystore service.\n");
-        return 1;
-    }
-    int32_t aidl_return;
-    ::std::vector<::std::string> uids;
-    android::binder::Status status = service->listUidsOfAuthBoundKeys(&uids, &aidl_return);
-    if (!status.isOk()) {
-        fprintf(stderr, "Requesting uids of auth bound keys failed with error %s.\n",
-                status.toString8().c_str());
-        return 1;
-    }
-    if (!KeyStoreNativeReturnCode(aidl_return).isOk()) {
-        fprintf(stderr, "Requesting uids of auth bound keys failed with code %d.\n", aidl_return);
-        return 1;
-    }
-    printf("Apps with auth bound keys:\n");
-    for (auto i = uids.begin(); i != uids.end(); ++i) {
-        printf("%s\n", i->c_str());
+    std::cout << "Keys:\n";
+    for (const auto& key : key_list) {
+        std::cout << "  "
+                  << (key.alias ? *key.alias : "Whoopsi - no alias, this should not happen.")
+                  << std::endl;
     }
     return 0;
 }
 
 int SignAndVerify(const std::string& name) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    AuthorizationSetBuilder sign_params;
-    sign_params.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
-    sign_params.Digest(Digest::SHA_2_256);
-    AuthorizationSet output_params;
-    uint64_t handle;
-    auto result =
-        keystore->beginOperation(KeyPurpose::SIGN, name, sign_params, &output_params, &handle);
-    if (!result.isOk()) {
-        printf("Sign: BeginOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
+    auto keystore = CreateKeystoreInstance();
+    auto sign_params = keymint::AuthorizationSetBuilder()
+                           .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::SIGN)
+                           .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
+                           .Digest(keymint::Digest::SHA_2_256);
+
+    keymint::AuthorizationSet output_params;
+
+    ks2::KeyEntryResponse keyEntryResponse;
+
+    auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    AuthorizationSet empty_params;
-    std::string output_data;
-    result = keystore->finishOperation(handle, empty_params, "data_to_sign",
-                                       std::string() /*signature_to_verify*/, &output_params,
-                                       &output_data);
-    if (!result.isOk()) {
-        printf("Sign: FinishOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
+
+    ks2::CreateOperationResponse operationResponse;
+
+    rc = keyEntryResponse.iSecurityLevel->createOperation(keyEntryResponse.metadata.key,
+                                                          sign_params.vector_data(),
+                                                          false /* forced */, &operationResponse);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to create operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    printf("Sign: %zu bytes.\n", output_data.size());
-    // We have a signature, now verify it.
-    std::string signature_to_verify = output_data;
-    output_data.clear();
-    result =
-        keystore->beginOperation(KeyPurpose::VERIFY, name, sign_params, &output_params, &handle);
-    result = keystore->finishOperation(handle, empty_params, "data_to_sign", signature_to_verify,
-                                       &output_params, &output_data);
-    if (result == ErrorCode::VERIFICATION_FAILED) {
-        printf("Verify: Failed to verify signature.\n");
-        return result.getErrorCode();
+
+    const std::vector<uint8_t> data_to_sign{0x64, 0x61, 0x74, 0x61, 0x5f, 0x74,
+                                            0x6f, 0x5f, 0x73, 0x69, 0x67, 0x6e};
+    std::optional<std::vector<uint8_t>> output_data;
+    rc = operationResponse.iOperation->finish(data_to_sign, {}, &output_data);
+    if (!rc.isOk()) {
+        std::cerr << "Failed to finalize operation: " << rc.getDescription() << std::endl;
+        return unwrapError(rc);
     }
-    if (!result.isOk()) {
-        printf("Verify: FinishOperation failed: %d\n", result.getErrorCode());
-        return result.getErrorCode();
+
+    if (!output_data) {
+        std::cerr << "Odd signing succeeded but no signature was returned." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
     }
-    printf("Verify: OK\n");
+    auto signature = std::move(*output_data);
+
+    std::cout << "Sign: " << signature.size() << " bytes." << std::endl;
+
+    if (auto cert = keyEntryResponse.metadata.certificate) {
+        const uint8_t* p = cert->data();
+        bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &p, (long)cert->size()));
+        bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
+        bssl::UniquePtr<EVP_MD_CTX> ctx(EVP_MD_CTX_new());
+        if (!ctx) {
+            std::cerr << "Failed to created EVP_MD context. << std::endl";
+            return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+        }
+
+        if (!EVP_DigestVerifyInit(ctx.get(), nullptr, EVP_sha256(), nullptr, decoded_pkey.get()) ||
+            !EVP_DigestVerifyUpdate(ctx.get(), data_to_sign.data(), data_to_sign.size()) ||
+            EVP_DigestVerifyFinal(ctx.get(), signature.data(), signature.size()) != 1) {
+            std::cerr << "Failed to verify signature." << std::endl;
+            return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+        }
+    } else {
+        std::cerr << "No public key to check signature against." << std::endl;
+        return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
+    }
+
+    std::cout << "Verify: OK" << std::endl;
     return 0;
 }
 
 int Encrypt(const std::string& key_name, const std::string& input_filename,
-            const std::string& output_filename, int32_t flags) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    std::string input = ReadFile(input_filename);
-    std::string output;
-    if (!keystore->encryptWithAuthentication(key_name, input, flags, &output)) {
-        printf("EncryptWithAuthentication failed.\n");
-        return 1;
+            const std::string& output_filename, keymint::SecurityLevel securityLevel) {
+    auto input = ReadFile(input_filename);
+    auto result = encryptWithAuthentication(key_name, input, securityLevel);
+    if (auto error = std::get_if<int>(&result)) {
+        std::cerr << "EncryptWithAuthentication failed." << std::endl;
+        return *error;
     }
-    WriteFile(output_filename, output);
+    WriteFile(output_filename, std::get<std::vector<uint8_t>>(result));
     return 0;
 }
 
 int Decrypt(const std::string& key_name, const std::string& input_filename,
             const std::string& output_filename) {
-    std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    std::string input = ReadFile(input_filename);
-    std::string output;
-    if (!keystore->decryptWithAuthentication(key_name, input, &output)) {
-        printf("DecryptWithAuthentication failed.\n");
-        return 1;
+    auto input = ReadFile(input_filename);
+    auto result = decryptWithAuthentication(key_name, input);
+    if (auto error = std::get_if<int>(&result)) {
+        std::cerr << "DecryptWithAuthentication failed." << std::endl;
+        return *error;
     }
-    WriteFile(output_filename, output);
+    WriteFile(output_filename, std::get<std::vector<uint8_t>>(result));
     return 0;
 }
 
-uint32_t securityLevelOption2Flags(const CommandLine& cmd) {
+keymint::SecurityLevel securityLevelOption2SecurlityLevel(const CommandLine& cmd) {
     if (cmd.HasSwitch("seclevel")) {
         auto str = cmd.GetSwitchValueASCII("seclevel");
         if (str == "strongbox") {
-            return KEYSTORE_FLAG_STRONGBOX;
-        } else if (str == "software") {
-            return KEYSTORE_FLAG_FALLBACK;
+            return keymint::SecurityLevel::STRONGBOX;
+        } else if (str == "tee") {
+            return keymint::SecurityLevel::TRUSTED_ENVIRONMENT;
         }
+        std::cerr << "Unknown Security level: " << str << std::endl;
+        std::cerr << "Supported security levels: \"strongbox\" or \"tee\" (default)" << std::endl;
     }
-    return KEYSTORE_FLAG_NONE;
+    return keymint::SecurityLevel::TRUSTED_ENVIRONMENT;
 }
 
 class ConfirmationListener
-    : public android::security::BnConfirmationPromptCallback,
-      public std::promise<std::tuple<ConfirmationResponseCode, std::vector<uint8_t>>> {
+    : public apc::BnConfirmationCallback,
+      public std::promise<std::tuple<apc::ResponseCode, std::optional<std::vector<uint8_t>>>> {
   public:
     ConfirmationListener() {}
 
-    virtual ::android::binder::Status
-    onConfirmationPromptCompleted(int32_t result,
-                                  const ::std::vector<uint8_t>& dataThatWasConfirmed) override {
-        this->set_value({static_cast<ConfirmationResponseCode>(result), dataThatWasConfirmed});
-        return ::android::binder::Status::ok();
-    }
+    virtual ::ndk::ScopedAStatus
+    onCompleted(::aidl::android::security::apc::ResponseCode result,
+                const std::optional<std::vector<uint8_t>>& dataConfirmed) override {
+        this->set_value({result, dataConfirmed});
+        return ::ndk::ScopedAStatus::ok();
+    };
 };
 
 int Confirmation(const std::string& promptText, const std::string& extraDataHex,
                  const std::string& locale, const std::string& uiOptionsStr,
                  const std::string& cancelAfter) {
-    sp<android::IServiceManager> sm = android::defaultServiceManager();
-    sp<android::IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = android::interface_cast<IKeystoreService>(binder);
-    if (service == nullptr) {
-        printf("error: could not connect to keystore service.\n");
+    ::ndk::SpAIBinder apcBinder(AServiceManager_getService("android.security.apc"));
+    auto apcService = apc::IProtectedConfirmation::fromBinder(apcBinder);
+    if (!apcService) {
+        std::cerr << "Error: could not connect to apc service." << std::endl;
         return 1;
     }
 
@@ -537,44 +1023,28 @@
         return 1;
     }
 
-    String16 promptText16(promptText.data(), promptText.size());
-    String16 locale16(locale.data(), locale.size());
-
-    sp<ConfirmationListener> listener = new ConfirmationListener();
+    auto listener = std::make_shared<ConfirmationListener>();
 
     auto future = listener->get_future();
-    int32_t aidl_return;
-    android::binder::Status status = service->presentConfirmationPrompt(
-        listener, promptText16, extraData, locale16, uiOptionsAsFlags, &aidl_return);
-    if (!status.isOk()) {
-        printf("Presenting confirmation prompt failed with binder status '%s'.\n",
-               status.toString8().c_str());
+    auto rc = apcService->presentPrompt(listener, promptText, extraData, locale, uiOptionsAsFlags);
+
+    if (!rc.isOk()) {
+        std::cerr << "Presenting confirmation prompt failed: " << rc.getDescription() << std::endl;
         return 1;
     }
-    ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
-    if (responseCode != ConfirmationResponseCode::OK) {
-        printf("Presenting confirmation prompt failed with response code %d.\n", responseCode);
-        return 1;
-    }
-    printf("Waiting for prompt to complete - use Ctrl+C to abort...\n");
+
+    std::cerr << "Waiting for prompt to complete - use Ctrl+C to abort..." << std::endl;
 
     if (cancelAfterValue > 0.0) {
-        printf("Sleeping %.1f seconds before canceling prompt...\n", cancelAfterValue);
+        std::cerr << "Sleeping " << cancelAfterValue << " seconds before canceling prompt..."
+                  << std::endl;
         auto fstatus =
             future.wait_for(std::chrono::milliseconds(uint64_t(cancelAfterValue * 1000)));
         if (fstatus == std::future_status::timeout) {
-            status = service->cancelConfirmationPrompt(listener, &aidl_return);
-            if (!status.isOk()) {
-                printf("Canceling confirmation prompt failed with binder status '%s'.\n",
-                       status.toString8().c_str());
-                return 1;
-            }
-            responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
-            if (responseCode == ConfirmationResponseCode::Ignored) {
-                // The confirmation was completed by the user so take the response
-            } else if (responseCode != ConfirmationResponseCode::OK) {
-                printf("Canceling confirmation prompt failed with response code %d.\n",
-                       responseCode);
+            rc = apcService->cancelPrompt(listener);
+            if (!rc.isOk()) {
+                std::cerr << "Canceling confirmation prompt failed: " << rc.getDescription()
+                          << std::endl;
                 return 1;
             }
         }
@@ -582,27 +1052,28 @@
 
     future.wait();
 
-    auto [rc, dataThatWasConfirmed] = future.get();
+    auto [responseCode, dataThatWasConfirmed] = future.get();
 
-    printf("Confirmation prompt completed\n"
-           "responseCode = %d\n",
-           rc);
-    printf("dataThatWasConfirmed[%zd] = {", dataThatWasConfirmed.size());
+    std::cerr << "Confirmation prompt completed\n"
+              << "responseCode = " << toString(responseCode);
     size_t newLineCountDown = 16;
     bool hasPrinted = false;
-    for (uint8_t element : dataThatWasConfirmed) {
-        if (hasPrinted) {
-            printf(", ");
-        }
-        if (newLineCountDown == 0) {
-            printf("\n  ");
-            newLineCountDown = 32;
-        }
-        printf("0x%02x", element);
-        hasPrinted = true;
-    }
-    printf("}\n");
+    if (dataThatWasConfirmed) {
+        std::cerr << "dataThatWasConfirmed[" << dataThatWasConfirmed->size() << "] = {";
+        for (uint8_t element : *dataThatWasConfirmed) {
+            if (hasPrinted) {
+                std::cerr << ", ";
+            }
+            if (newLineCountDown == 0) {
+                std::cerr << "\n  ";
+                newLineCountDown = 32;
+            }
+            std::cerr << "0x" << std::hex << std::setw(2) << std::setfill('0') << (unsigned)element;
 
+            hasPrinted = true;
+        }
+    }
+    std::cerr << std::endl;
     return 0;
 }
 
@@ -613,7 +1084,7 @@
     CommandLine* command_line = CommandLine::ForCurrentProcess();
     CommandLine::StringVector args = command_line->GetArgs();
 
-    android::ProcessState::self()->startThreadPool();
+    ABinderProcess_startThreadPool();
 
     if (args.empty()) {
         PrintUsageAndExit();
@@ -623,12 +1094,9 @@
                                   command_line->HasSwitch("test_for_0_3"));
     } else if (args[0] == "list-brillo-tests") {
         return ListTestCases();
-    } else if (args[0] == "add-entropy") {
-        return AddEntropy(command_line->GetSwitchValueASCII("input"),
-                          securityLevelOption2Flags(*command_line));
     } else if (args[0] == "generate") {
         return GenerateKey(command_line->GetSwitchValueASCII("name"),
-                           securityLevelOption2Flags(*command_line),
+                           securityLevelOption2SecurlityLevel(*command_line),
                            command_line->HasSwitch("auth_bound"));
     } else if (args[0] == "get-chars") {
         return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
@@ -636,20 +1104,17 @@
         return ExportKey(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "delete") {
         return DeleteKey(command_line->GetSwitchValueASCII("name"));
-    } else if (args[0] == "delete-all") {
-        return DeleteAllKeys();
     } else if (args[0] == "exists") {
         return DoesKeyExist(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "list") {
-        return List(command_line->GetSwitchValueASCII("prefix"));
-    } else if (args[0] == "list-apps-with-keys") {
-        return ListAppsWithKeys();
+        return List();
     } else if (args[0] == "sign-verify") {
         return SignAndVerify(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "encrypt") {
-        return Encrypt(
-            command_line->GetSwitchValueASCII("name"), command_line->GetSwitchValueASCII("in"),
-            command_line->GetSwitchValueASCII("out"), securityLevelOption2Flags(*command_line));
+        return Encrypt(command_line->GetSwitchValueASCII("name"),
+                       command_line->GetSwitchValueASCII("in"),
+                       command_line->GetSwitchValueASCII("out"),
+                       securityLevelOption2SecurlityLevel(*command_line));
     } else if (args[0] == "decrypt") {
         return Decrypt(command_line->GetSwitchValueASCII("name"),
                        command_line->GetSwitchValueASCII("in"),
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
deleted file mode 100644
index f888683..0000000
--- a/keystore/keystore_client_impl.cpp
+++ /dev/null
@@ -1,629 +0,0 @@
-// Copyright 2015 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.
-
-#define LOG_TAG "keystore_client"
-
-#include "keystore/keystore_client_impl.h"
-
-#include <future>
-#include <optional>
-#include <string>
-#include <vector>
-
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IBinder.h>
-#include <binder/IInterface.h>
-#include <binder/IServiceManager.h>
-#include <keystore/keystore.h>
-#include <log/log.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_promises.h>
-
-#include "keystore_client.pb.h"
-
-namespace {
-
-// Use the UID of the current process.
-const int kDefaultUID = -1;
-const char kEncryptSuffix[] = "_ENC";
-const char kAuthenticateSuffix[] = "_AUTH";
-constexpr uint32_t kAESKeySize = 256;      // bits
-constexpr uint32_t kHMACKeySize = 256;     // bits
-constexpr uint32_t kHMACOutputSize = 256;  // bits
-
-using android::String16;
-using android::security::keymaster::ExportResult;
-using android::security::keymaster::OperationResult;
-using android::security::keystore::KeystoreResponse;
-using keystore::AuthorizationSet;
-using keystore::AuthorizationSetBuilder;
-using keystore::KeyCharacteristics;
-using keystore::KeyStoreServiceReturnCode;
-}  // namespace
-
-namespace keystore {
-
-KeystoreClientImpl::KeystoreClientImpl() {
-    service_manager_ = android::defaultServiceManager();
-    keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
-    keystore_ =
-        android::interface_cast<android::security::keystore::IKeystoreService>(keystore_binder_);
-}
-
-bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
-                                                   const std::string& data, int32_t flags,
-                                                   std::string* encrypted_data) {
-    // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
-    // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
-    // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
-    // because hardware support for GCM is not mandatory for all Brillo devices.
-    std::string encryption_key_name = key_name + kEncryptSuffix;
-    if (!createOrVerifyEncryptionKey(encryption_key_name, flags)) {
-        return false;
-    }
-    std::string authentication_key_name = key_name + kAuthenticateSuffix;
-    if (!createOrVerifyAuthenticationKey(authentication_key_name, flags)) {
-        return false;
-    }
-    AuthorizationSetBuilder encrypt_params;
-    encrypt_params.Padding(PaddingMode::PKCS7);
-    encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
-    AuthorizationSet output_params;
-    std::string raw_encrypted_data;
-    if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
-                          std::string(), /* signature_to_verify */
-                          &output_params, &raw_encrypted_data)) {
-        ALOGE("Encrypt: AES operation failed.");
-        return false;
-    }
-    auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
-    if (!init_vector_blob.isOk()) {
-        ALOGE("Encrypt: Missing initialization vector.");
-        return false;
-    }
-    std::string init_vector = hidlVec2String(init_vector_blob.value());
-
-    AuthorizationSetBuilder authenticate_params;
-    authenticate_params.Digest(Digest::SHA_2_256);
-    authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
-    std::string raw_authentication_data;
-    if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
-                          init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */
-                          &output_params, &raw_authentication_data)) {
-        ALOGE("Encrypt: HMAC operation failed.");
-        return false;
-    }
-    EncryptedData protobuf;
-    protobuf.set_init_vector(init_vector);
-    protobuf.set_authentication_data(raw_authentication_data);
-    protobuf.set_encrypted_data(raw_encrypted_data);
-    if (!protobuf.SerializeToString(encrypted_data)) {
-        ALOGE("Encrypt: Failed to serialize EncryptedData protobuf.");
-        return false;
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::decryptWithAuthentication(const std::string& key_name,
-                                                   const std::string& encrypted_data,
-                                                   std::string* data) {
-    EncryptedData protobuf;
-    if (!protobuf.ParseFromString(encrypted_data)) {
-        ALOGE("Decrypt: Failed to parse EncryptedData protobuf.");
-    }
-    // Verify authentication before attempting decryption.
-    std::string authentication_key_name = key_name + kAuthenticateSuffix;
-    AuthorizationSetBuilder authenticate_params;
-    authenticate_params.Digest(Digest::SHA_2_256);
-    AuthorizationSet output_params;
-    std::string output_data;
-    if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
-                          protobuf.init_vector() + protobuf.encrypted_data(),
-                          protobuf.authentication_data(), &output_params, &output_data)) {
-        ALOGE("Decrypt: HMAC operation failed.");
-        return false;
-    }
-    std::string encryption_key_name = key_name + kEncryptSuffix;
-    AuthorizationSetBuilder encrypt_params;
-    encrypt_params.Padding(PaddingMode::PKCS7);
-    encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
-    encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
-                                 protobuf.init_vector().size());
-    if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
-                          protobuf.encrypted_data(), std::string(), /* signature_to_verify */
-                          &output_params, data)) {
-        ALOGE("Decrypt: AES operation failed.");
-        return false;
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
-                                          const AuthorizationSet& input_parameters,
-                                          const std::string& input_data,
-                                          const std::string& signature_to_verify,
-                                          AuthorizationSet* output_parameters,
-                                          std::string* output_data) {
-    uint64_t handle;
-    auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
-    if (!result.isOk()) {
-        ALOGE("BeginOperation failed: %d", result.getErrorCode());
-        return false;
-    }
-    AuthorizationSet empty_params;
-    AuthorizationSet ignored_params;
-    result = finishOperation(handle, empty_params, input_data, signature_to_verify, &ignored_params,
-                             output_data);
-    if (!result.isOk()) {
-        ALOGE("FinishOperation failed: %d", result.getErrorCode());
-        return false;
-    }
-    return true;
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy, int32_t flags) {
-    int32_t error_code;
-
-    android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise());
-    auto future = promise->get_future();
-
-    auto binder_result =
-        keystore_->addRngEntropy(promise, blob2hidlVec(entropy), flags, &error_code);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    auto result = future.get();
-
-    return KeyStoreNativeReturnCode(result.response_code());
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::generateKey(const std::string& key_name, const AuthorizationSet& key_parameters,
-                                int32_t flags, AuthorizationSet* hardware_enforced_characteristics,
-                                AuthorizationSet* software_enforced_characteristics) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code;
-    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
-    auto future = promise->get_future();
-    auto binder_result = keystore_->generateKey(
-        promise, key_name16,
-        ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
-        hidl_vec<uint8_t>() /* entropy */, kDefaultUID, flags, &error_code);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    auto [km_response, characteristics] = future.get();
-
-    /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
-     * There are no references to Parcel memory after that, and ownership of the newly acquired
-     * memory is with the AuthorizationSet objects. */
-    *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
-    *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
-    return KeyStoreNativeReturnCode(km_response.response_code());
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
-                                          AuthorizationSet* hardware_enforced_characteristics,
-                                          AuthorizationSet* software_enforced_characteristics) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code;
-    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
-    auto future = promise->get_future();
-    auto binder_result = keystore_->getKeyCharacteristics(
-        promise, key_name16, android::security::keymaster::KeymasterBlob(),
-        android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    auto [km_response, characteristics] = future.get();
-
-    /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
-     * There are no references to Parcel memory after that, and ownership of the newly acquired
-     * memory is with the AuthorizationSet objects. */
-    *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
-    *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
-    return KeyStoreNativeReturnCode(km_response.response_code());
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::importKey(const std::string& key_name, const AuthorizationSet& key_parameters,
-                              KeyFormat key_format, const std::string& key_data,
-                              AuthorizationSet* hardware_enforced_characteristics,
-                              AuthorizationSet* software_enforced_characteristics) {
-    String16 key_name16(key_name.data(), key_name.size());
-    auto hidlKeyData = blob2hidlVec(key_data);
-    int32_t error_code;
-    android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
-    auto future = promise->get_future();
-    auto binder_result = keystore_->importKey(
-        promise, key_name16,
-        ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
-        (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &error_code);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    auto [km_response, characteristics] = future.get();
-
-    /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
-     * There are no references to Parcel memory after that, and ownership of the newly acquired
-     * memory is with the AuthorizationSet objects. */
-    *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
-    *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
-    return KeyStoreNativeReturnCode(km_response.response_code());
-}
-
-KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
-                                                       const std::string& key_name,
-                                                       std::string* export_data) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code;
-    android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
-    auto future = promise->get_future();
-    auto binder_result = keystore_->exportKey(
-        promise, key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
-        android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    auto export_result = future.get();
-    if (!export_result.resultCode.isOk()) return export_result.resultCode;
-
-    *export_data = hidlVec2String(export_result.exportData);
-
-    return export_result.resultCode;
-}
-
-KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t result;
-    auto binder_result = keystore_->del(key_name16, kDefaultUID, &result);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    return KeyStoreNativeReturnCode(result);
-}
-
-KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
-    int32_t result;
-    auto binder_result = keystore_->clear_uid(kDefaultUID, &result);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    return KeyStoreNativeReturnCode(result);
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
-                                   const AuthorizationSet& input_parameters,
-                                   AuthorizationSet* output_parameters, uint64_t* handle) {
-    android::sp<android::IBinder> token(new android::BBinder);
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code;
-    android::sp<OperationResultPromise> promise(new OperationResultPromise{});
-    auto future = promise->get_future();
-    auto binder_result = keystore_->begin(
-        promise, token, key_name16, (int)purpose, true /*pruneable*/,
-        android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &error_code);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    OperationResult result = future.get();
-    if (result.resultCode.isOk()) {
-        *handle = getNextVirtualHandle();
-        active_operations_[*handle] = result.token;
-        if (result.outParams.size()) {
-            *output_parameters = result.outParams;
-        }
-    }
-    return result.resultCode;
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::updateOperation(uint64_t handle, const AuthorizationSet& input_parameters,
-                                    const std::string& input_data, size_t* num_input_bytes_consumed,
-                                    AuthorizationSet* output_parameters, std::string* output_data) {
-    if (active_operations_.count(handle) == 0) {
-        return ErrorCode::INVALID_OPERATION_HANDLE;
-    }
-    auto hidlInputData = blob2hidlVec(input_data);
-    int32_t error_code;
-    android::sp<OperationResultPromise> promise(new OperationResultPromise{});
-    auto future = promise->get_future();
-    auto binder_result = keystore_->update(
-        promise, active_operations_[handle],
-        android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        hidlInputData, &error_code);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    OperationResult result = future.get();
-
-    if (result.resultCode.isOk()) {
-        *num_input_bytes_consumed = result.inputConsumed;
-        if (result.outParams.size()) {
-            *output_parameters = result.outParams;
-        }
-        // TODO verify that append should not be assign
-        output_data->append(hidlVec2String(result.data));
-    }
-    return result.resultCode;
-}
-
-KeyStoreNativeReturnCode
-KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& input_parameters,
-                                    const std::string& input_data,
-                                    const std::string& signature_to_verify,
-                                    AuthorizationSet* output_parameters, std::string* output_data) {
-    if (active_operations_.count(handle) == 0) {
-        return ErrorCode::INVALID_OPERATION_HANDLE;
-    }
-    int32_t error_code;
-    auto hidlSignature = blob2hidlVec(signature_to_verify);
-    auto hidlInput = blob2hidlVec(input_data);
-    android::sp<OperationResultPromise> promise(new OperationResultPromise{});
-    auto future = promise->get_future();
-    auto binder_result = keystore_->finish(
-        promise, active_operations_[handle],
-        android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
-        (std::vector<uint8_t>)hidlInput, (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(),
-        &error_code);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    KeyStoreNativeReturnCode rc(error_code);
-    if (!rc.isOk()) return rc;
-
-    OperationResult result = future.get();
-    if (result.resultCode.isOk()) {
-        if (result.outParams.size()) {
-            *output_parameters = result.outParams;
-        }
-        // TODO verify that append should not be assign
-        output_data->append(hidlVec2String(result.data));
-        active_operations_.erase(handle);
-    }
-    return result.resultCode;
-}
-
-KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
-    if (active_operations_.count(handle) == 0) {
-        return ErrorCode::INVALID_OPERATION_HANDLE;
-    }
-    int32_t result;
-    android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise{});
-    auto future = promise->get_future();
-    // Current implementation does not return exceptions in android::binder::Status
-    auto binder_result = keystore_->abort(promise, active_operations_[handle], &result);
-    if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
-    KeyStoreNativeReturnCode rc(result);
-    if (!rc.isOk()) return rc;
-    rc = KeyStoreNativeReturnCode(future.get().response_code());
-    if (rc.isOk()) {
-        active_operations_.erase(handle);
-    }
-    return rc;
-}
-
-bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
-    String16 key_name16(key_name.data(), key_name.size());
-    int32_t result;
-    auto binder_result = keystore_->exist(key_name16, kDefaultUID, &result);
-    if (!binder_result.isOk()) return false;  // binder error
-    return result == static_cast<int32_t>(ResponseCode::NO_ERROR);
-}
-
-bool KeystoreClientImpl::listKeys(const std::string& prefix,
-                                  std::vector<std::string>* key_name_list) {
-    return listKeysOfUid(prefix, kDefaultUID, key_name_list);
-}
-
-bool KeystoreClientImpl::listKeysOfUid(const std::string& prefix, int uid,
-                                       std::vector<std::string>* key_name_list) {
-    String16 prefix16(prefix.data(), prefix.size());
-    std::vector<::android::String16> matches;
-    auto binder_result = keystore_->list(prefix16, uid, &matches);
-    if (!binder_result.isOk()) return false;
-
-    for (const auto& match : matches) {
-        android::String8 key_name(match);
-        key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
-    }
-    return true;
-}
-
-std::optional<std::vector<uint8_t>> KeystoreClientImpl::getKey(const std::string& alias, int uid) {
-    String16 alias16(alias.data(), alias.size());
-    std::vector<uint8_t> output;
-    auto binder_result = keystore_->get(alias16, uid, &output);
-    if (!binder_result.isOk()) return std::nullopt;
-    return output;
-}
-
-uint64_t KeystoreClientImpl::getNextVirtualHandle() {
-    return next_virtual_handle_++;
-}
-
-bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name, int32_t flags) {
-    bool key_exists = doesKeyExist(key_name);
-    if (key_exists) {
-        bool verified = false;
-        if (!verifyEncryptionKeyAttributes(key_name, &verified)) {
-            return false;
-        }
-        if (!verified) {
-            auto result = deleteKey(key_name);
-            if (!result.isOk()) {
-                ALOGE("Failed to delete invalid encryption key: %d", result.getErrorCode());
-                return false;
-            }
-            key_exists = false;
-        }
-    }
-    if (!key_exists) {
-        AuthorizationSetBuilder key_parameters;
-        key_parameters.AesEncryptionKey(kAESKeySize)
-            .Padding(PaddingMode::PKCS7)
-            .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
-            .Authorization(TAG_NO_AUTH_REQUIRED);
-        AuthorizationSet hardware_enforced_characteristics;
-        AuthorizationSet software_enforced_characteristics;
-        auto result =
-            generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
-                        &software_enforced_characteristics);
-        if (!result.isOk()) {
-            ALOGE("Failed to generate encryption key: %d", result.getErrorCode());
-            return false;
-        }
-        if (hardware_enforced_characteristics.size() == 0) {
-            ALOGW("WARNING: Encryption key is not hardware-backed.");
-        }
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name,
-                                                         int32_t flags) {
-    bool key_exists = doesKeyExist(key_name);
-    if (key_exists) {
-        bool verified = false;
-        if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
-            return false;
-        }
-        if (!verified) {
-            auto result = deleteKey(key_name);
-            if (!result.isOk()) {
-                ALOGE("Failed to delete invalid authentication key: %d", result.getErrorCode());
-                return false;
-            }
-            key_exists = false;
-        }
-    }
-    if (!key_exists) {
-        AuthorizationSetBuilder key_parameters;
-        key_parameters.HmacKey(kHMACKeySize)
-            .Digest(Digest::SHA_2_256)
-            .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
-            .Authorization(TAG_NO_AUTH_REQUIRED);
-        AuthorizationSet hardware_enforced_characteristics;
-        AuthorizationSet software_enforced_characteristics;
-        auto result =
-            generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
-                        &software_enforced_characteristics);
-        if (!result.isOk()) {
-            ALOGE("Failed to generate authentication key: %d", result.getErrorCode());
-            return false;
-        }
-        if (hardware_enforced_characteristics.size() == 0) {
-            ALOGW("WARNING: Authentication key is not hardware-backed.");
-        }
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
-                                                       bool* verified) {
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
-                                        &software_enforced_characteristics);
-    if (!result.isOk()) {
-        ALOGE("Failed to query encryption key: %d", result.getErrorCode());
-        return false;
-    }
-    *verified = true;
-    auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
-                              software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
-    if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
-        ALOGW("Found encryption key with invalid algorithm.");
-        *verified = false;
-    }
-    auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
-                             software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
-    if (!key_size.isOk() || key_size.value() != kAESKeySize) {
-        ALOGW("Found encryption key with invalid size.");
-        *verified = false;
-    }
-    auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
-                               software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
-    if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
-        ALOGW("Found encryption key with invalid block mode.");
-        *verified = false;
-    }
-    auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
-                                 software_enforced_characteristics.GetTagValue(TAG_PADDING));
-    if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
-        ALOGW("Found encryption key with invalid padding mode.");
-        *verified = false;
-    }
-    if (hardware_enforced_characteristics.size() == 0) {
-        ALOGW("WARNING: Encryption key is not hardware-backed.");
-    }
-    return true;
-}
-
-bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
-                                                           bool* verified) {
-    AuthorizationSet hardware_enforced_characteristics;
-    AuthorizationSet software_enforced_characteristics;
-    auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
-                                        &software_enforced_characteristics);
-    if (!result.isOk()) {
-        ALOGE("Failed to query authentication key: %d", result.getErrorCode());
-        return false;
-    }
-    *verified = true;
-    auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
-                              software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
-    if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
-        ALOGW("Found authentication key with invalid algorithm.");
-        *verified = false;
-    }
-    auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
-                             software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
-    if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
-        ALOGW("Found authentication key with invalid size.");
-        *verified = false;
-    }
-    auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
-                             software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
-    if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
-        ALOGW("Found authentication key with invalid minimum mac size.");
-        *verified = false;
-    }
-    auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
-                           software_enforced_characteristics.GetTagValue(TAG_DIGEST));
-    if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
-        ALOGW("Found authentication key with invalid digest list.");
-        *verified = false;
-    }
-    if (hardware_enforced_characteristics.size() == 0) {
-        ALOGW("WARNING: Authentication key is not hardware-backed.");
-    }
-    return true;
-}
-
-}  // namespace keystore
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
deleted file mode 100644
index 02c2139..0000000
--- a/keystore/keystore_main.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#define LOG_TAG "keystore"
-
-#include <android-base/logging.h>
-#include <android/hidl/manager/1.2/IServiceManager.h>
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <keymasterV4_1/Keymaster3.h>
-#include <keymasterV4_1/Keymaster4.h>
-#include <utils/StrongPointer.h>
-
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_return_types.h>
-
-#include "KeyStore.h"
-#include "key_store_service.h"
-#include "legacy_keymaster_device_wrapper.h"
-#include "permissions.h"
-
-/* KeyStore is a secured storage for key-value pairs. In this implementation,
- * each file stores one key-value pair. Keys are encoded in file names, and
- * values are encrypted with checksums. The encryption key is protected by a
- * user-defined password. To keep things simple, buffers are always larger than
- * the maximum space we needed, so boundary checks on buffers are omitted. */
-
-using ::android::sp;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::keymaster::V4_0::ErrorCode;
-using ::android::hardware::keymaster::V4_0::HmacSharingParameters;
-using ::android::hardware::keymaster::V4_0::SecurityLevel;
-using ::android::hidl::manager::V1_2::IServiceManager;
-
-using ::keystore::keymaster::support::Keymaster;
-using ::keystore::keymaster::support::Keymaster3;
-using ::keystore::keymaster::support::Keymaster4;
-
-using keystore::KeymasterDevices;
-
-template <typename Wrapper>
-KeymasterDevices enumerateKeymasterDevices(IServiceManager* serviceManager) {
-    KeymasterDevices result;
-    serviceManager->listManifestByInterface(
-        Wrapper::WrappedIKeymasterDevice::descriptor, [&](const hidl_vec<hidl_string>& names) {
-            auto try_get_device = [&](const auto& name, bool fail_silent) {
-                auto device = Wrapper::WrappedIKeymasterDevice::getService(name);
-                if (fail_silent && !device) return;
-                CHECK(device) << "Failed to get service for \""
-                              << Wrapper::WrappedIKeymasterDevice::descriptor
-                              << "\" with interface name \"" << name << "\"";
-
-                sp<Keymaster> kmDevice(new Wrapper(device, name));
-                auto halVersion = kmDevice->halVersion();
-                SecurityLevel securityLevel = halVersion.securityLevel;
-                LOG(INFO) << "found " << Wrapper::WrappedIKeymasterDevice::descriptor
-                          << " with interface name " << name << " and seclevel "
-                          << toString(securityLevel);
-                CHECK(static_cast<uint32_t>(securityLevel) < result.size())
-                    << "Security level of \"" << Wrapper::WrappedIKeymasterDevice::descriptor
-                    << "\" with interface name \"" << name << "\" out of range";
-                auto& deviceSlot = result[securityLevel];
-                if (deviceSlot) {
-                    if (!fail_silent) {
-                        LOG(WARNING) << "Implementation of \""
-                                     << Wrapper::WrappedIKeymasterDevice::descriptor
-                                     << "\" with interface name \"" << name
-                                     << "\" and security level: " << toString(securityLevel)
-                                     << " Masked by other implementation of Keymaster";
-                    }
-                } else {
-                    deviceSlot = kmDevice;
-                }
-            };
-            bool has_default = false;
-            for (auto& n : names) {
-                try_get_device(n, false);
-                if (n == "default") has_default = true;
-            }
-            // Make sure that we always check the default device. If we enumerate only what is
-            // known to hwservicemanager, we miss a possible passthrough HAL.
-            if (!has_default) {
-                try_get_device("default", true /* fail_silent */);
-            }
-        });
-    return result;
-}
-
-KeymasterDevices initializeKeymasters() {
-    auto serviceManager = IServiceManager::getService();
-    CHECK(serviceManager.get()) << "Failed to get ServiceManager";
-    auto result = enumerateKeymasterDevices<Keymaster4>(serviceManager.get());
-    auto softKeymaster = result[SecurityLevel::SOFTWARE];
-    if (!result[SecurityLevel::TRUSTED_ENVIRONMENT]) {
-        result = enumerateKeymasterDevices<Keymaster3>(serviceManager.get());
-    }
-    if (softKeymaster) result[SecurityLevel::SOFTWARE] = softKeymaster;
-    if (result[SecurityLevel::SOFTWARE] && !result[SecurityLevel::TRUSTED_ENVIRONMENT]) {
-        LOG(WARNING) << "No secure Keymaster implementation found, but device offers insecure"
-                        " Keymaster HAL. Using as default.";
-        result[SecurityLevel::TRUSTED_ENVIRONMENT] = result[SecurityLevel::SOFTWARE];
-        result[SecurityLevel::SOFTWARE] = nullptr;
-    }
-    if (!result[SecurityLevel::SOFTWARE]) {
-        auto fbdev = android::keystore::makeSoftwareKeymasterDevice();
-        CHECK(fbdev.get()) << "Unable to create Software Keymaster Device";
-        result[SecurityLevel::SOFTWARE] = new Keymaster3(fbdev, "Software");
-    }
-    return result;
-}
-
-int main(int argc, char* argv[]) {
-    using android::hardware::hidl_string;
-    CHECK(argc >= 2) << "A directory must be specified!";
-    CHECK(chdir(argv[1]) != -1) << "chdir: " << argv[1] << ": " << strerror(errno);
-
-    auto kmDevices = initializeKeymasters();
-
-    CHECK(kmDevices[SecurityLevel::SOFTWARE]) << "Missing software Keymaster device";
-    CHECK(kmDevices[SecurityLevel::TRUSTED_ENVIRONMENT])
-        << "Error no viable keymaster device found";
-
-    CHECK(configure_selinux() != -1) << "Failed to configure SELinux.";
-
-    auto halVersion = kmDevices[SecurityLevel::TRUSTED_ENVIRONMENT]->halVersion();
-
-    // If the hardware is keymaster 2.0 or higher we will not allow the fallback device for import
-    // or generation of keys. The fallback device is only used for legacy keys present on the
-    // device.
-    SecurityLevel minimalAllowedSecurityLevelForNewKeys =
-        halVersion.majorVersion >= 2 ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
-
-    android::sp<keystore::KeyStore> keyStore(
-        new keystore::KeyStore(kmDevices, minimalAllowedSecurityLevelForNewKeys));
-    keyStore->initialize();
-    android::sp<android::IServiceManager> sm = android::defaultServiceManager();
-    android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(keyStore);
-    service->setRequestingSid(true);
-    android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
-    CHECK(ret == android::OK) << "Couldn't register binder service!";
-
-    /*
-     * This thread is just going to process Binder transactions.
-     */
-    android::IPCThreadState::self()->joinThreadPool();
-    return 1;
-}
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
deleted file mode 100644
index 86d286e..0000000
--- a/keystore/legacy_keymaster_device_wrapper.cpp
+++ /dev/null
@@ -1,547 +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.
- */
-
-#define LOG_TAG "android.hardware.keymaster@3.0-impl"
-
-#include "legacy_keymaster_device_wrapper.h"
-
-#include <log/log.h>
-
-#include <hardware/keymaster2.h>
-#include <hardware/keymaster_defs.h>
-#include <keymaster/keymaster_configuration.h>
-#include <keymaster/soft_keymaster_device.h>
-
-namespace android {
-namespace keystore {
-
-using ::keymaster::SoftKeymasterDevice;
-
-LegacyKeymasterDeviceWrapper::LegacyKeymasterDeviceWrapper(keymaster2_device_t* dev)
-    : keymaster_device_(dev) {}
-
-LegacyKeymasterDeviceWrapper::~LegacyKeymasterDeviceWrapper() {
-    if (keymaster_device_) keymaster_device_->common.close(&keymaster_device_->common);
-}
-
-static inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) {
-    return keymaster_tag_get_type(tag);
-}
-
-/**
- * legacy_enum_conversion converts enums from hidl to keymaster and back. Currently, this is just a
- * cast to make the compiler happy. One of two thigs should happen though:
- * TODO The keymaster enums should become aliases for the hidl generated enums so that we have a
- *      single point of truth. Then this cast function can go away.
- */
-inline static keymaster_tag_t legacy_enum_conversion(const Tag value) {
-    return keymaster_tag_t(value);
-}
-inline static Tag legacy_enum_conversion(const keymaster_tag_t value) {
-    return Tag(value);
-}
-inline static keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) {
-    return keymaster_purpose_t(value);
-}
-inline static keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) {
-    return keymaster_key_format_t(value);
-}
-inline static ErrorCode legacy_enum_conversion(const keymaster_error_t value) {
-    return ErrorCode(value);
-}
-
-class KmParamSet : public keymaster_key_param_set_t {
-  public:
-    explicit KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
-        params = new keymaster_key_param_t[keyParams.size()];
-        length = keyParams.size();
-        for (size_t i = 0; i < keyParams.size(); ++i) {
-            auto tag = legacy_enum_conversion(keyParams[i].tag);
-            switch (typeFromTag(tag)) {
-            case KM_ENUM:
-            case KM_ENUM_REP:
-                params[i] = keymaster_param_enum(tag, keyParams[i].f.integer);
-                break;
-            case KM_UINT:
-            case KM_UINT_REP:
-                params[i] = keymaster_param_int(tag, keyParams[i].f.integer);
-                break;
-            case KM_ULONG:
-            case KM_ULONG_REP:
-                params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger);
-                break;
-            case KM_DATE:
-                params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime);
-                break;
-            case KM_BOOL:
-                if (keyParams[i].f.boolValue)
-                    params[i] = keymaster_param_bool(tag);
-                else
-                    params[i].tag = KM_TAG_INVALID;
-                break;
-            case KM_BIGNUM:
-            case KM_BYTES:
-                params[i] =
-                    keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size());
-                break;
-            case KM_INVALID:
-            default:
-                params[i].tag = KM_TAG_INVALID;
-                /* just skip */
-                break;
-            }
-        }
-    }
-    KmParamSet(KmParamSet&& other) noexcept
-        : keymaster_key_param_set_t{other.params, other.length} {
-        other.length = 0;
-        other.params = nullptr;
-    }
-    KmParamSet(const KmParamSet&) = delete;
-    ~KmParamSet() { delete[] params; }
-};
-
-inline static KmParamSet hidlParams2KmParamSet(const hidl_vec<KeyParameter>& params) {
-    return KmParamSet(params);
-}
-
-inline static keymaster_blob_t hidlVec2KmBlob(const hidl_vec<uint8_t>& blob) {
-    /* hidl unmarshals funny pointers if the the blob is empty */
-    if (blob.size()) return {&blob[0], blob.size()};
-    return {};
-}
-
-inline static keymaster_key_blob_t hidlVec2KmKeyBlob(const hidl_vec<uint8_t>& blob) {
-    /* hidl unmarshals funny pointers if the the blob is empty */
-    if (blob.size()) return {&blob[0], blob.size()};
-    return {};
-}
-
-inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_key_blob_t& blob) {
-    if (blob.key_material == nullptr || blob.key_material_size == 0) {
-        return {};
-    } else {
-        return hidl_vec<uint8_t>(blob.key_material, blob.key_material + blob.key_material_size);
-    }
-}
-inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_blob_t& blob) {
-    if (blob.data == nullptr || blob.data_length == 0) {
-        return {};
-    } else {
-        return hidl_vec<uint8_t>(blob.data, blob.data + blob.data_length);
-    }
-}
-
-inline static hidl_vec<hidl_vec<uint8_t>>
-kmCertChain2Hidl(const keymaster_cert_chain_t* cert_chain) {
-    hidl_vec<hidl_vec<uint8_t>> result;
-    if (!cert_chain || cert_chain->entry_count == 0 || !cert_chain->entries) return result;
-
-    result.resize(cert_chain->entry_count);
-    for (size_t i = 0; i < cert_chain->entry_count; ++i) {
-        auto& entry = cert_chain->entries[i];
-        result[i] = kmBlob2hidlVec(entry);
-    }
-
-    return result;
-}
-
-static inline hidl_vec<KeyParameter> kmParamSet2Hidl(const keymaster_key_param_set_t& set) {
-    hidl_vec<KeyParameter> result;
-    if (set.length == 0 || set.params == nullptr) return result;
-
-    result.resize(set.length);
-    keymaster_key_param_t* params = set.params;
-    for (size_t i = 0; i < set.length; ++i) {
-        auto tag = params[i].tag;
-        result[i].tag = legacy_enum_conversion(tag);
-        switch (typeFromTag(tag)) {
-        case KM_ENUM:
-        case KM_ENUM_REP:
-            result[i].f.integer = params[i].enumerated;
-            break;
-        case KM_UINT:
-        case KM_UINT_REP:
-            result[i].f.integer = params[i].integer;
-            break;
-        case KM_ULONG:
-        case KM_ULONG_REP:
-            result[i].f.longInteger = params[i].long_integer;
-            break;
-        case KM_DATE:
-            result[i].f.dateTime = params[i].date_time;
-            break;
-        case KM_BOOL:
-            result[i].f.boolValue = params[i].boolean;
-            break;
-        case KM_BIGNUM:
-        case KM_BYTES:
-            result[i].blob = kmBlob2hidlVec(params[i].blob);
-            break;
-        case KM_INVALID:
-        default:
-            params[i].tag = KM_TAG_INVALID;
-            /* just skip */
-            break;
-        }
-    }
-    return result;
-}
-
-// Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
-Return<void> LegacyKeymasterDeviceWrapper::getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) {
-    _hidl_cb(false, false, false, false, false, "Fallback Device", "Google Android Security");
-    return Void();
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::addRngEntropy(const hidl_vec<uint8_t>& data) {
-    return legacy_enum_conversion(
-        keymaster_device_->add_rng_entropy(keymaster_device_, &data[0], data.size()));
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::generateKey(const hidl_vec<KeyParameter>& keyParams,
-                                                       generateKey_cb _hidl_cb) {
-    // result variables for the wire
-    KeyCharacteristics resultCharacteristics;
-    hidl_vec<uint8_t> resultKeyBlob;
-
-    // result variables the backend understands
-    keymaster_key_blob_t key_blob{nullptr, 0};
-    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
-
-    // convert the parameter set to something our backend understands
-    auto kmParams = hidlParams2KmParamSet(keyParams);
-
-    auto rc = keymaster_device_->generate_key(keymaster_device_, &kmParams, &key_blob,
-                                              &key_characteristics);
-
-    if (rc == KM_ERROR_OK) {
-        // on success convert the result to wire format
-        resultKeyBlob = kmBlob2hidlVec(key_blob);
-        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
-        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
-    }
-
-    // send results off to the client
-    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
-
-    // free buffers that we are responsible for
-    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
-    keymaster_free_characteristics(&key_characteristics);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::getKeyCharacteristics(
-    const hidl_vec<uint8_t>& keyBlob, const hidl_vec<uint8_t>& clientId,
-    const hidl_vec<uint8_t>& appData, getKeyCharacteristics_cb _hidl_cb) {
-    // result variables for the wire
-    KeyCharacteristics resultCharacteristics;
-
-    // result variables the backend understands
-    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
-
-    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
-    auto kmClientId = hidlVec2KmBlob(clientId);
-    auto kmAppData = hidlVec2KmBlob(appData);
-
-    auto rc = keymaster_device_->get_key_characteristics(
-        keymaster_device_, keyBlob.size() ? &kmKeyBlob : nullptr,
-        clientId.size() ? &kmClientId : nullptr, appData.size() ? &kmAppData : nullptr,
-        &key_characteristics);
-
-    if (rc == KM_ERROR_OK) {
-        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
-        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultCharacteristics);
-
-    keymaster_free_characteristics(&key_characteristics);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::importKey(const hidl_vec<KeyParameter>& params,
-                                                     KeyFormat keyFormat,
-                                                     const hidl_vec<uint8_t>& keyData,
-                                                     importKey_cb _hidl_cb) {
-    // result variables for the wire
-    KeyCharacteristics resultCharacteristics;
-    hidl_vec<uint8_t> resultKeyBlob;
-
-    // result variables the backend understands
-    keymaster_key_blob_t key_blob{nullptr, 0};
-    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
-
-    auto kmParams = hidlParams2KmParamSet(params);
-    auto kmKeyData = hidlVec2KmBlob(keyData);
-
-    auto rc = keymaster_device_->import_key(keymaster_device_, &kmParams,
-                                            legacy_enum_conversion(keyFormat), &kmKeyData,
-                                            &key_blob, &key_characteristics);
-
-    if (rc == KM_ERROR_OK) {
-        // on success convert the result to wire format
-        resultKeyBlob = kmBlob2hidlVec(key_blob);
-        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
-        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
-
-    // free buffers that we are responsible for
-    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
-    keymaster_free_characteristics(&key_characteristics);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::exportKey(KeyFormat exportFormat,
-                                                     const hidl_vec<uint8_t>& keyBlob,
-                                                     const hidl_vec<uint8_t>& clientId,
-                                                     const hidl_vec<uint8_t>& appData,
-                                                     exportKey_cb _hidl_cb) {
-
-    // result variables for the wire
-    hidl_vec<uint8_t> resultKeyBlob;
-
-    // result variables the backend understands
-    keymaster_blob_t out_blob = {};
-
-    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
-    auto kmClientId = hidlVec2KmBlob(clientId);
-    auto kmAppData = hidlVec2KmBlob(appData);
-
-    auto rc = keymaster_device_->export_key(keymaster_device_, legacy_enum_conversion(exportFormat),
-                                            keyBlob.size() ? &kmKeyBlob : nullptr,
-                                            clientId.size() ? &kmClientId : nullptr,
-                                            appData.size() ? &kmAppData : nullptr, &out_blob);
-
-    if (rc == KM_ERROR_OK) {
-        // on success convert the result to wire format
-        // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?)
-        resultKeyBlob = kmBlob2hidlVec(out_blob);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
-
-    // free buffers that we are responsible for
-    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::attestKey(const hidl_vec<uint8_t>& keyToAttest,
-                                                     const hidl_vec<KeyParameter>& attestParams,
-                                                     attestKey_cb _hidl_cb) {
-
-    hidl_vec<hidl_vec<uint8_t>> resultCertChain;
-
-    for (size_t i = 0; i < attestParams.size(); ++i) {
-        switch (attestParams[i].tag) {
-            case Tag::ATTESTATION_ID_BRAND:
-            case Tag::ATTESTATION_ID_DEVICE:
-            case Tag::ATTESTATION_ID_PRODUCT:
-            case Tag::ATTESTATION_ID_SERIAL:
-            case Tag::ATTESTATION_ID_IMEI:
-            case Tag::ATTESTATION_ID_MEID:
-            case Tag::ATTESTATION_ID_MANUFACTURER:
-            case Tag::ATTESTATION_ID_MODEL:
-                // Device id attestation may only be supported if the device is able to permanently
-                // destroy its knowledge of the ids. This device is unable to do this, so it must
-                // never perform any device id attestation.
-                _hidl_cb(ErrorCode::CANNOT_ATTEST_IDS, resultCertChain);
-                return Void();
-            default:
-                break;
-        }
-    }
-
-    keymaster_cert_chain_t cert_chain = {};
-
-    auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
-    auto kmAttestParams = hidlParams2KmParamSet(attestParams);
-
-    auto rc = keymaster_device_->attest_key(keymaster_device_, &kmKeyToAttest, &kmAttestParams,
-                                            &cert_chain);
-
-    if (rc == KM_ERROR_OK) {
-        resultCertChain = kmCertChain2Hidl(&cert_chain);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultCertChain);
-
-    keymaster_free_cert_chain(&cert_chain);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
-                                                      const hidl_vec<KeyParameter>& upgradeParams,
-                                                      upgradeKey_cb _hidl_cb) {
-
-    // result variables for the wire
-    hidl_vec<uint8_t> resultKeyBlob;
-
-    // result variables the backend understands
-    keymaster_key_blob_t key_blob = {};
-
-    auto kmKeyBlobToUpgrade = hidlVec2KmKeyBlob(keyBlobToUpgrade);
-    auto kmUpgradeParams = hidlParams2KmParamSet(upgradeParams);
-
-    auto rc = keymaster_device_->upgrade_key(keymaster_device_, &kmKeyBlobToUpgrade,
-                                             &kmUpgradeParams, &key_blob);
-
-    if (rc == KM_ERROR_OK) {
-        // on success convert the result to wire format
-        resultKeyBlob = kmBlob2hidlVec(key_blob);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
-
-    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
-
-    return Void();
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
-    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
-    return legacy_enum_conversion(keymaster_device_->delete_key(keymaster_device_, &kmKeyBlob));
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::deleteAllKeys() {
-    return legacy_enum_conversion(keymaster_device_->delete_all_keys(keymaster_device_));
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::destroyAttestationIds() {
-    return ErrorCode::UNIMPLEMENTED;
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
-                                                 const hidl_vec<KeyParameter>& inParams,
-                                                 begin_cb _hidl_cb) {
-
-    // result variables for the wire
-    hidl_vec<KeyParameter> resultParams;
-    uint64_t resultOpHandle = 0;
-
-    // result variables the backend understands
-    keymaster_key_param_set_t out_params{nullptr, 0};
-    keymaster_operation_handle_t& operation_handle = resultOpHandle;
-
-    auto kmKey = hidlVec2KmKeyBlob(key);
-    auto kmInParams = hidlParams2KmParamSet(inParams);
-
-    auto rc = keymaster_device_->begin(keymaster_device_, legacy_enum_conversion(purpose), &kmKey,
-                                       &kmInParams, &out_params, &operation_handle);
-
-    if (rc == KM_ERROR_OK) resultParams = kmParamSet2Hidl(out_params);
-
-    _hidl_cb(legacy_enum_conversion(rc), resultParams, resultOpHandle);
-
-    keymaster_free_param_set(&out_params);
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::update(uint64_t operationHandle,
-                                                  const hidl_vec<KeyParameter>& inParams,
-                                                  const hidl_vec<uint8_t>& input,
-                                                  update_cb _hidl_cb) {
-    // result variables for the wire
-    uint32_t resultConsumed = 0;
-    hidl_vec<KeyParameter> resultParams;
-    hidl_vec<uint8_t> resultBlob;
-
-    // result variables the backend understands
-    size_t consumed = 0;
-    keymaster_key_param_set_t out_params = {};
-    keymaster_blob_t out_blob = {};
-
-    auto kmInParams = hidlParams2KmParamSet(inParams);
-    auto kmInput = hidlVec2KmBlob(input);
-
-    auto rc = keymaster_device_->update(keymaster_device_, operationHandle, &kmInParams, &kmInput,
-                                        &consumed, &out_params, &out_blob);
-
-    if (rc == KM_ERROR_OK) {
-        resultConsumed = consumed;
-        resultParams = kmParamSet2Hidl(out_params);
-        resultBlob = kmBlob2hidlVec(out_blob);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultConsumed, resultParams, resultBlob);
-
-    keymaster_free_param_set(&out_params);
-    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
-
-    return Void();
-}
-
-Return<void> LegacyKeymasterDeviceWrapper::finish(uint64_t operationHandle,
-                                                  const hidl_vec<KeyParameter>& inParams,
-                                                  const hidl_vec<uint8_t>& input,
-                                                  const hidl_vec<uint8_t>& signature,
-                                                  finish_cb _hidl_cb) {
-    // result variables for the wire
-    hidl_vec<KeyParameter> resultParams;
-    hidl_vec<uint8_t> resultBlob;
-
-    // result variables the backend understands
-    keymaster_key_param_set_t out_params = {};
-    keymaster_blob_t out_blob = {};
-
-    auto kmInParams = hidlParams2KmParamSet(inParams);
-    auto kmInput = hidlVec2KmBlob(input);
-    auto kmSignature = hidlVec2KmBlob(signature);
-
-    auto rc = keymaster_device_->finish(keymaster_device_, operationHandle, &kmInParams, &kmInput,
-                                        &kmSignature, &out_params, &out_blob);
-
-    if (rc == KM_ERROR_OK) {
-        resultParams = kmParamSet2Hidl(out_params);
-        resultBlob = kmBlob2hidlVec(out_blob);
-    }
-
-    _hidl_cb(legacy_enum_conversion(rc), resultParams, resultBlob);
-
-    keymaster_free_param_set(&out_params);
-    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
-
-    return Void();
-}
-
-Return<ErrorCode> LegacyKeymasterDeviceWrapper::abort(uint64_t operationHandle) {
-    return legacy_enum_conversion(keymaster_device_->abort(keymaster_device_, operationHandle));
-}
-
-sp<IKeymasterDevice> makeSoftwareKeymasterDevice() {
-    keymaster2_device_t* dev = nullptr;
-    dev = (new SoftKeymasterDevice)->keymaster2_device();
-
-    auto kmrc = ::keymaster::ConfigureDevice(dev);
-    if (kmrc != KM_ERROR_OK) {
-        dev->common.close(&dev->common);
-        return nullptr;
-    }
-
-    return new LegacyKeymasterDeviceWrapper(dev);
-}
-
-}  // namespace keystore
-}  // namespace android
diff --git a/keystore/legacy_keymaster_device_wrapper.h b/keystore/legacy_keymaster_device_wrapper.h
deleted file mode 100644
index cd2e5a7..0000000
--- a/keystore/legacy_keymaster_device_wrapper.h
+++ /dev/null
@@ -1,90 +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 LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
-#define LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
-
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <hidl/Status.h>
-#include <hidl/MQDescriptor.h>
-
-struct keymaster2_device;
-typedef struct keymaster2_device keymaster2_device_t;
-
-namespace android {
-namespace keystore {
-
-using ::android::hardware::keymaster::V3_0::ErrorCode;
-using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
-using ::android::hardware::keymaster::V3_0::KeyCharacteristics;
-using ::android::hardware::keymaster::V3_0::KeyFormat;
-using ::android::hardware::keymaster::V3_0::KeyParameter;
-using ::android::hardware::keymaster::V3_0::KeyPurpose;
-using ::android::hardware::keymaster::V3_0::Tag;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-class LegacyKeymasterDeviceWrapper : public IKeymasterDevice {
-  public:
-    explicit LegacyKeymasterDeviceWrapper(keymaster2_device_t* dev);
-    virtual ~LegacyKeymasterDeviceWrapper();
-
-    // Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
-    Return<void> getHardwareFeatures(getHardwareFeatures_cb _hidl_cb);
-    Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
-    Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
-                             generateKey_cb _hidl_cb) override;
-    Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
-                                       const hidl_vec<uint8_t>& clientId,
-                                       const hidl_vec<uint8_t>& appData,
-                                       getKeyCharacteristics_cb _hidl_cb) override;
-    Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
-                           const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override;
-    Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
-                           const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
-                           exportKey_cb _hidl_cb) override;
-    Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
-                           const hidl_vec<KeyParameter>& attestParams,
-                           attestKey_cb _hidl_cb) override;
-    Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
-                            const hidl_vec<KeyParameter>& upgradeParams,
-                            upgradeKey_cb _hidl_cb) override;
-    Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
-    Return<ErrorCode> deleteAllKeys() override;
-    Return<ErrorCode> destroyAttestationIds() override;
-    Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
-                       const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) override;
-    Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
-                        const hidl_vec<uint8_t>& input, update_cb _hidl_cb) override;
-    Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
-                        const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
-                        finish_cb _hidl_cb) override;
-    Return<ErrorCode> abort(uint64_t operationHandle) override;
-
-  private:
-    keymaster2_device_t* keymaster_device_;
-};
-
-sp<IKeymasterDevice> makeSoftwareKeymasterDevice();
-
-}  // namespace keystore
-}  // namespace android
-
-#endif  // LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
deleted file mode 100644
index bd4bd5e..0000000
--- a/keystore/operation.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-#define LOG_TAG "KeystoreOperation"
-
-#include "operation.h"
-#include "key_operation_log_handler.h"
-
-#include <algorithm>
-#include <android-base/logging.h>
-#include <mutex>
-
-namespace keystore {
-
-OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
-    : mDeathRecipient(deathRecipient) {}
-
-sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
-                                       const sp<Keymaster>& dev, const sp<IBinder>& appToken,
-                                       KeyCharacteristics&& characteristics,
-                                       const hidl_vec<KeyParameter>& params, bool pruneable) {
-    sp<IBinder> token = new ::android::BBinder();
-    mMap.emplace(token, std::make_shared<Operation>(handle, keyid, purpose, dev,
-                                                    std::move(characteristics), appToken, params));
-    if (pruneable) mLru.push_back(token);
-    if (mAppTokenMap.find(appToken) == mAppTokenMap.end()) appToken->linkToDeath(mDeathRecipient);
-    mAppTokenMap[appToken].push_back(token);
-    return token;
-}
-
-std::shared_ptr<Operation> OperationMap::getOperation(const sp<IBinder>& token) {
-    auto entry = mMap.find(token);
-    if (entry == mMap.end()) return {};
-
-    auto op = entry->second;
-
-    updateLru(token);
-    return op;
-}
-
-void OperationMap::updateLru(const sp<IBinder>& token) {
-    auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
-    if (lruEntry != mLru.end()) {
-        mLru.erase(lruEntry);
-        mLru.push_back(token);
-    }
-}
-
-std::shared_ptr<Operation> OperationMap::removeOperation(const sp<IBinder>& token,
-                                                         bool wasSuccessful, int32_t responseCode) {
-    auto entry = mMap.find(token);
-    if (entry == mMap.end()) return {};
-
-    auto op = entry->second;
-    logKeystoreKeyOperationEvent(*op, wasSuccessful, responseCode);
-    mMap.erase(entry);
-
-    auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
-    if (lruEntry != mLru.end()) mLru.erase(lruEntry);
-    removeOperationTracking(token, op->appToken);
-    return op;
-}
-
-void OperationMap::removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken) {
-    auto appEntry = mAppTokenMap.find(appToken);
-    if (appEntry == mAppTokenMap.end()) {
-        ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
-        return;
-    }
-    auto tokenEntry = std::find(appEntry->second.begin(), appEntry->second.end(), token);
-    appEntry->second.erase(tokenEntry);
-    // Stop listening for death if all operations tied to the token have finished.
-    if (appEntry->second.size() == 0) {
-        appToken->unlinkToDeath(mDeathRecipient);
-        mAppTokenMap.erase(appEntry);
-    }
-}
-
-sp<IBinder> OperationMap::getOldestPruneableOperation() {
-    if (mLru.size() == 0) return {};
-
-    return {mLru.front()};
-}
-
-std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
-    auto appEntry = mAppTokenMap.find(appToken);
-    if (appEntry == mAppTokenMap.end()) return {};
-    return appEntry->second;
-}
-
-}  // namespace keystore
diff --git a/keystore/operation.h b/keystore/operation.h
deleted file mode 100644
index 8423db5..0000000
--- a/keystore/operation.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2015 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_OPERATION_H_
-#define KEYSTORE_OPERATION_H_
-
-#include <list>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <vector>
-
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <keymasterV4_1/Keymaster.h>
-#include <utils/StrongPointer.h>
-
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_concurrency.h>
-#include <keystore/keystore_hidl_support.h>
-
-#include "operation_struct.h"
-
-namespace keystore {
-
-using ::android::IBinder;
-using ::android::sp;
-using keymaster::support::Keymaster;
-
-/**
- * OperationMap handles the translation of uint64_t's and keymaster2_device_t's to opaque binder
- * tokens that can be used to reference that operation at a later time by applications. It also does
- * LRU tracking for operation pruning and keeps a mapping of clients to operations to allow for
- * graceful handling of application death.
- */
-
-class OperationMap {
-  public:
-    explicit OperationMap(IBinder::DeathRecipient* deathRecipient);
-    sp<IBinder> addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
-                             const sp<Keymaster>& dev, const sp<IBinder>& appToken,
-                             KeyCharacteristics&& characteristics,
-                             const hidl_vec<KeyParameter>& params, bool pruneable);
-    std::shared_ptr<Operation> getOperation(const sp<IBinder>& token);
-    std::shared_ptr<Operation> removeOperation(const sp<IBinder>& token, bool wasSuccessful,
-                                               int32_t responseCode);
-    size_t getOperationCount() const { return mMap.size(); }
-    sp<IBinder> getOldestPruneableOperation();
-    std::vector<sp<IBinder>> getOperationsForToken(const sp<IBinder>& appToken);
-
-  private:
-    void updateLru(const sp<IBinder>& token);
-    void removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken);
-
-    std::map<sp<IBinder>, std::shared_ptr<Operation>> mMap;
-    std::list<sp<IBinder>> mLru;
-    std::map<sp<IBinder>, std::vector<sp<IBinder>>> mAppTokenMap;
-    IBinder::DeathRecipient* mDeathRecipient;
-};
-
-}  // namespace keystore
-
-#endif
diff --git a/keystore/operation_struct.h b/keystore/operation_struct.h
deleted file mode 100644
index 23e79fc..0000000
--- a/keystore/operation_struct.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2018 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_OPERATION_STRUCT_H_
-#define KEYSTORE_OPERATION_STRUCT_H_
-
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <keymasterV4_1/Keymaster.h>
-#include <utils/StrongPointer.h>
-
-#include <keystore/keymaster_types.h>
-#include <keystore/keystore_hidl_support.h>
-#include <keystore/keystore_return_types.h>
-
-#include <future>
-
-namespace keystore {
-
-using ::android::IBinder;
-using ::android::sp;
-using keymaster::support::Keymaster;
-
-struct Operation {
-    Operation() = default;
-    Operation(uint64_t handle_, uint64_t keyid_, KeyPurpose purpose_, const sp<Keymaster>& device_,
-              KeyCharacteristics&& characteristics_, sp<IBinder> appToken_,
-              const hidl_vec<KeyParameter> params_)
-        : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_),
-          characteristics(characteristics_), appToken(appToken_), authToken(), verificationToken(),
-          params(params_) {}
-    Operation(Operation&&) = default;
-    Operation(const Operation&) = delete;
-
-    bool hasAuthToken() const { return authToken.mac.size() != 0; }
-
-    uint64_t handle;
-    uint64_t keyid;
-    KeyPurpose purpose;
-    sp<Keymaster> device;
-    KeyCharacteristics characteristics;
-    sp<IBinder> appToken;
-    std::promise<KeyStoreServiceReturnCode> authTokenPromise;
-    std::future<KeyStoreServiceReturnCode> authTokenFuture;
-    HardwareAuthToken authToken;
-    VerificationToken verificationToken;
-    const hidl_vec<KeyParameter> params;
-};
-
-}  // namespace keystore
-
-#endif
diff --git a/keystore/permissions.cpp b/keystore/permissions.cpp
deleted file mode 100644
index 2cd42cf..0000000
--- a/keystore/permissions.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define LOG_TAG "keystore"
-
-#include "permissions.h"
-
-#include <cutils/sockets.h>
-#include <log/log.h>
-#include <private/android_filesystem_config.h>
-
-#include <selinux/android.h>
-
-#include "keystore_utils.h"
-
-/* perm_labels associcated with keystore_key SELinux class verbs. */
-const char* perm_labels[] = {
-    "get_state",
-    "get",
-    "insert",
-    "delete",
-    "exist",
-    "list",
-    "reset",
-    "password",
-    "lock",
-    "unlock",
-    "is_empty",
-    "sign",
-    "verify",
-    "grant",
-    "duplicate",
-    "clear_uid",
-    "add_auth",
-    "user_changed",
-    "gen_unique_id",
-};
-
-struct user_euid {
-    uid_t uid;
-    uid_t euid;
-};
-
-user_euid user_euids[] = {{AID_VPN, AID_SYSTEM},
-                          {AID_WIFI, AID_SYSTEM},
-                          {AID_ROOT, AID_SYSTEM},
-
-#ifdef GRANT_ROOT_ALL_PERMISSIONS
-                          // Allow VTS tests to act on behalf of the wifi user
-                          {AID_WIFI, AID_ROOT}
-#endif
-};
-
-struct user_perm {
-    uid_t uid;
-    perm_t perms;
-};
-
-static user_perm user_perms[] = {
-    {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0))},
-    {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY)},
-    {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY)},
-    {AID_BLUETOOTH, static_cast<perm_t>(P_GET | P_INSERT | P_DELETE | P_EXIST | P_SIGN | P_VERIFY)},
-
-#ifdef GRANT_ROOT_ALL_PERMISSIONS
-    // Allow VTS tests running as root to perform all operations
-    {AID_ROOT, static_cast<perm_t>((uint32_t)(~0))},
-#else
-    {AID_ROOT, static_cast<perm_t>(P_GET)},
-#endif
-};
-
-static const perm_t DEFAULT_PERMS = static_cast<perm_t>(
-    P_GET_STATE | P_GET | P_INSERT | P_DELETE | P_EXIST | P_LIST | P_SIGN | P_VERIFY |
-    P_GEN_UNIQUE_ID /* Only privileged apps can do this, but enforcement is done by SELinux */);
-
-struct audit_data {
-    pid_t pid;
-    uid_t uid;
-    const char* sid;
-};
-
-const char* get_perm_label(perm_t perm) {
-    unsigned int index = ffs(perm);
-    if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) {
-        return perm_labels[index - 1];
-    } else {
-        ALOGE("Keystore: Failed to retrieve permission label.\n");
-        abort();
-    }
-}
-
-static int audit_callback(void* data, security_class_t /* cls */, char* buf, size_t len) {
-    struct audit_data* ad = reinterpret_cast<struct audit_data*>(data);
-    if (!ad) {
-        ALOGE("No keystore audit data");
-        return 0;
-    }
-
-    const char* sid = ad->sid ? ad->sid : "N/A";
-    snprintf(buf, len, "pid=%d uid=%d sid=%s", ad->pid, ad->uid, sid);
-    return 0;
-}
-
-static char* tctx;
-
-int configure_selinux() {
-    union selinux_callback cb;
-    cb.func_audit = audit_callback;
-    selinux_set_callback(SELINUX_CB_AUDIT, cb);
-    cb.func_log = selinux_log_callback;
-    selinux_set_callback(SELINUX_CB_LOG, cb);
-    if (getcon(&tctx) != 0) {
-        ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-static bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid, const char* ssid) {
-    audit_data ad;
-    char* sctx = nullptr;
-    const char* selinux_class = "keystore_key";
-    const char* str_perm = get_perm_label(perm);
-
-    if (!str_perm) {
-        return false;
-    }
-
-    if (ssid == nullptr && getpidcon(spid, &sctx) != 0) {
-        ALOGE("SELinux: Failed to get source pid context.\n");
-        return false;
-    }
-
-    const char* use_sid = ssid ? ssid : sctx;
-
-    ad.pid = spid;
-    ad.uid = uid;
-    ad.sid = use_sid;
-
-    bool allowed = selinux_check_access(use_sid, tctx, selinux_class, str_perm,
-                                        reinterpret_cast<void*>(&ad)) == 0;
-    freecon(sctx);
-    return allowed;
-}
-
-/**
- * Returns the UID that the callingUid should act as. This is here for
- * legacy support of the WiFi and VPN systems and should be removed
- * when WiFi can operate in its own namespace.
- */
-uid_t get_keystore_euid(uid_t uid) {
-    for (size_t i = 0; i < sizeof(user_euids) / sizeof(user_euids[0]); i++) {
-        struct user_euid user = user_euids[i];
-        if (user.uid == uid) {
-            return user.euid;
-        }
-    }
-
-    return uid;
-}
-
-bool has_permission(uid_t uid, perm_t perm, pid_t spid, const char* sid) {
-    // All system users are equivalent for multi-user support.
-    if (get_app_id(uid) == AID_SYSTEM) {
-        uid = AID_SYSTEM;
-    }
-
-    if (sid == nullptr) {
-        android_errorWriteLog(0x534e4554, "121035042");
-    }
-
-    for (size_t i = 0; i < sizeof(user_perms) / sizeof(user_perms[0]); i++) {
-        struct user_perm user = user_perms[i];
-        if (user.uid == uid) {
-            return (user.perms & perm) && keystore_selinux_check_access(uid, perm, spid, sid);
-        }
-    }
-
-    return (DEFAULT_PERMS & perm) && keystore_selinux_check_access(uid, perm, spid, sid);
-}
-
-/**
- * Returns true if the callingUid is allowed to interact in the targetUid's
- * namespace.
- */
-bool is_granted_to(uid_t callingUid, uid_t targetUid) {
-    if (callingUid == targetUid) {
-        return true;
-    }
-    for (size_t i = 0; i < sizeof(user_euids) / sizeof(user_euids[0]); i++) {
-        struct user_euid user = user_euids[i];
-        if (user.euid == callingUid && user.uid == targetUid) {
-            return true;
-        }
-    }
-
-    return false;
-}
diff --git a/keystore/permissions.h b/keystore/permissions.h
deleted file mode 100644
index 1dd0089..0000000
--- a/keystore/permissions.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 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_PERMISSIONS_H_
-#define KEYSTORE_PERMISSIONS_H_
-
-#include <unistd.h>
-
-/* Here are the permissions, actions, users, and the main function. */
-enum perm_t {
-    P_GET_STATE = 1 << 0,
-    P_GET = 1 << 1,
-    P_INSERT = 1 << 2,
-    P_DELETE = 1 << 3,
-    P_EXIST = 1 << 4,
-    P_LIST = 1 << 5,
-    P_RESET = 1 << 6,
-    P_PASSWORD = 1 << 7,
-    P_LOCK = 1 << 8,
-    P_UNLOCK = 1 << 9,
-    P_IS_EMPTY = 1 << 10,
-    P_SIGN = 1 << 11,
-    P_VERIFY = 1 << 12,
-    P_GRANT = 1 << 13,
-    P_DUPLICATE = 1 << 14,
-    P_CLEAR_UID = 1 << 15,
-    P_ADD_AUTH = 1 << 16,
-    P_USER_CHANGED = 1 << 17,
-    P_GEN_UNIQUE_ID = 1 << 18,
-};
-
-const char* get_perm_label(perm_t perm);
-
-/**
- * Returns the UID that the callingUid should act as. This is here for
- * legacy support of the WiFi and VPN systems and should be removed
- * when WiFi can operate in its own namespace.
- */
-uid_t get_keystore_euid(uid_t uid);
-
-/**
- * Returns true if the uid/pid/sid has a permission. Checks based on sid if available.
- *
- * sid may be null on older kernels
- */
-bool has_permission(uid_t uid, perm_t perm, pid_t spid, const char* sid);
-
-/**
- * Returns true if the callingUid is allowed to interact in the targetUid's
- * namespace.
- */
-bool is_granted_to(uid_t callingUid, uid_t targetUid);
-
-int configure_selinux();
-
-/*
- * Keystore grants.
- *
- * What are keystore grants?
- *
- * Keystore grants are a mechanism that allows an app to grant the permission to use one of its
- * keys to an other app.
- *
- * Liftime of a grant:
- *
- * A keystore grant is ephemeral in that is never persistently stored. When the keystore process
- * exits, all grants are lost. Also, grants can be explicitly revoked by the granter by invoking
- * the ungrant operation.
- *
- * What happens when a grant is created?
- *
- * The grant operation expects a valid key alias and the uid of the grantee, i.e., the app that
- * shall be allowed to use the key denoted by the alias. It then makes an entry in the grant store
- * which generates a new alias of the form <alias>_KEYSTOREGRANT_<random_grant_no_>. This grant
- * alias is returned to the caller which can pass the new alias to the grantee. For every grantee,
- * the grant store keeps a set of grants, an entry of which holds the following information:
- *  - the owner of the key by uid, aka granter uid,
- *  - the original alias of the granted key, and
- *  - the random grant number.
- * (See "grant_store.h:class Grant")
- *
- * What happens when a grant is used?
- *
- * Upon any keystore operation that expects an alias, the alias and the caller's uid are used
- * to retrieve a key file. If that fails some operations try to retrieve a key file indirectly
- * through a grant. These operations include:
- *  - attestKey
- *  - begin
- *  - exportKey
- *  - get
- *  - getKeyCharacteristics
- *  - del
- *  - exist
- *  - getmtime
- * Operations that DO NOT follow the grant indirection are:
- *  - import
- *  - generate
- *  - grant
- *  - ungrant
- * Especially, the latter two mean that neither can a grantee transitively grant a granted key
- * to a third, nor can they relinquish access to the key or revoke access to the key by a third.
- */
-
-#endif  // KEYSTORE_PERMISSIONS_H_
diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp
index 883e020..249cb77 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",
@@ -9,10 +18,6 @@
     ],
     srcs: [
         "aaid_truncation_test.cpp",
-        "auth_token_table_test.cpp",
-        "auth_token_formatting_test.cpp",
-        "blob_test.cpp",
-        "confirmationui_rate_limiting_test.cpp",
         "verification_token_seralization_test.cpp",
         "gtest_main.cpp",
     ],
@@ -26,7 +31,6 @@
         "libhidlbase",
         "libkeymaster4support",
         "libkeymaster4_1support",
-        "libkeystore_test",
         "liblog",
         "libutils",
     ],
@@ -54,17 +58,14 @@
     ],
     name: "confirmationui_invocation_test",
     static_libs: [
-        "android.hardware.confirmationui@1.0",
         "libbase",
         "libgtest_main",
         "libutils",
         "liblog",
     ],
     shared_libs: [
-        "libbinder",
-        "libkeystore_aidl", // for IKeyStoreService.asInterface()
-        "libkeystore_binder",
-        "libkeystore_parcelables",
+        "android.security.apc-ndk_platform",
+        "libbinder_ndk",
     ],
    sanitize: {
      cfi: false,
diff --git a/keystore/tests/Makefile b/keystore/tests/Makefile
index 2720b0f..b50b94a 100644
--- a/keystore/tests/Makefile
+++ b/keystore/tests/Makefile
@@ -17,7 +17,6 @@
 KEYMASTER=$(BASE)/system/keymaster
 
 INCLUDES=$(foreach dir,$(SUBS),-I $(BASE)/$(dir)/include) \
-	-I $(BASE)/libnativehelper/include/nativehelper \
 	-I $(GTEST) -Iinclude
 
 # Add USE_CLANG=1 to the make command line to build with clang, which has better error
diff --git a/keystore/tests/aaid_truncation_test.cpp b/keystore/tests/aaid_truncation_test.cpp
index 45c54df..fa4d769 100644
--- a/keystore/tests/aaid_truncation_test.cpp
+++ b/keystore/tests/aaid_truncation_test.cpp
@@ -75,15 +75,15 @@
 using ::android::content::pm::Signature;
 using ::android::security::build_attestation_application_id;
 
-std::unique_ptr<KeyAttestationPackageInfo>
+std::optional<KeyAttestationPackageInfo>
 make_package_info_with_signatures(const char* package_name,
                                   KeyAttestationPackageInfo::SignaturesVector signatures) {
-    return std::make_unique<KeyAttestationPackageInfo>(
+    return std::make_optional<KeyAttestationPackageInfo>(
         String16(package_name), 1 /* version code */,
         std::make_shared<KeyAttestationPackageInfo::SignaturesVector>(std::move(signatures)));
 }
 
-std::unique_ptr<KeyAttestationPackageInfo> make_package_info(const char* package_name) {
+std::optional<KeyAttestationPackageInfo> make_package_info(const char* package_name) {
     return make_package_info_with_signatures(package_name,
                                              KeyAttestationPackageInfo::SignaturesVector());
 }
@@ -111,7 +111,7 @@
     KeyAttestationPackageInfo::SignaturesVector signatures;
     // Add 35 signatures which will surely exceed the 1K limit.
     for (size_t i = 0; i < kTooManySignatures; ++i) {
-        signatures.push_back(std::make_unique<Signature>(dummy_sig_data));
+        signatures.push_back(std::make_optional<Signature>(dummy_sig_data));
     }
 
     KeyAttestationApplicationId app_id(
@@ -131,7 +131,7 @@
         KeyAttestationPackageInfo::SignaturesVector signatures;
         // Add a few signatures for each package
         for (int j = 0; j < 3; ++j) {
-            signatures.push_back(std::make_unique<Signature>(dummy_sig_data));
+            signatures.push_back(std::make_optional<Signature>(dummy_sig_data));
         }
         packages.push_back(
             make_package_info_with_signatures(kReasonablePackageName, std::move(signatures)));
diff --git a/keystore/tests/confirmationui_invocation_test.cpp b/keystore/tests/confirmationui_invocation_test.cpp
index f5182b5..7f8a373 100644
--- a/keystore/tests/confirmationui_invocation_test.cpp
+++ b/keystore/tests/confirmationui_invocation_test.cpp
@@ -15,11 +15,10 @@
 ** limitations under the License.
 */
 
-#include <android/hardware/confirmationui/1.0/types.h>
-#include <android/security/BnConfirmationPromptCallback.h>
-#include <android/security/keystore/IKeystoreService.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
+#include <aidl/android/security/apc/BnConfirmationCallback.h>
+#include <aidl/android/security/apc/IProtectedConfirmation.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
 
 #include <gtest/gtest.h>
 
@@ -28,65 +27,50 @@
 #include <tuple>
 #include <vector>
 
-using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
-using android::IBinder;
-using android::IServiceManager;
-using android::sp;
-using android::String16;
-using android::security::keystore::IKeystoreService;
-
 using namespace std::literals::chrono_literals;
+namespace apc = ::aidl::android::security::apc;
 
 class ConfirmationListener
-    : public android::security::BnConfirmationPromptCallback,
-      public std::promise<std::tuple<ConfirmationResponseCode, std::vector<uint8_t>>> {
+    : public apc::BnConfirmationCallback,
+      public std::promise<std::tuple<apc::ResponseCode, std::optional<std::vector<uint8_t>>>> {
   public:
     ConfirmationListener() {}
 
-    virtual ::android::binder::Status
-    onConfirmationPromptCompleted(int32_t result,
-                                  const ::std::vector<uint8_t>& dataThatWasConfirmed) override {
-        this->set_value({static_cast<ConfirmationResponseCode>(result), dataThatWasConfirmed});
-        return ::android::binder::Status::ok();
-    }
+    virtual ::ndk::ScopedAStatus
+    onCompleted(::aidl::android::security::apc::ResponseCode result,
+                const std::optional<std::vector<uint8_t>>& dataConfirmed) override {
+        this->set_value({result, dataConfirmed});
+        return ::ndk::ScopedAStatus::ok();
+    };
 };
 
 TEST(ConfirmationInvocationTest, InvokeAndCancel) {
-    android::ProcessState::self()->startThreadPool();
+    ABinderProcess_startThreadPool();
 
-    sp<IServiceManager> sm = android::defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = android::interface_cast<IKeystoreService>(binder);
-    ASSERT_TRUE(service);
+    ::ndk::SpAIBinder apcBinder(AServiceManager_getService("android.security.apc"));
+    auto apcService = apc::IProtectedConfirmation::fromBinder(apcBinder);
+    ASSERT_TRUE(apcService);
 
-    String16 promptText16("Just a little test!");
-    String16 locale16("en");
+    std::string promptText("Just a little test!");
+    std::string locale("en");
     std::vector<uint8_t> extraData{0xaa, 0xff, 0x00, 0x55};
 
-    sp<ConfirmationListener> listener = new ConfirmationListener();
+    auto listener = std::make_shared<ConfirmationListener>();
 
     auto future = listener->get_future();
-    int32_t aidl_return;
 
-    android::binder::Status status = service->presentConfirmationPrompt(
-        listener, promptText16, extraData, locale16, 0, &aidl_return);
-    ASSERT_TRUE(status.isOk()) << "Presenting confirmation prompt failed with binder status '"
-                               << status.toString8().c_str() << "'.\n";
-    ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
-    ASSERT_EQ(responseCode, ConfirmationResponseCode::OK)
-        << "Presenting confirmation prompt failed with response code " << aidl_return << ".\n";
+    auto rc = apcService->presentPrompt(listener, promptText, extraData, locale, 0);
+
+    ASSERT_TRUE(rc.isOk());
 
     auto fstatus = future.wait_for(2s);
     EXPECT_EQ(fstatus, std::future_status::timeout);
 
-    status = service->cancelConfirmationPrompt(listener, &aidl_return);
-    ASSERT_TRUE(status.isOk());
-
-    responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
-    ASSERT_EQ(responseCode, ConfirmationResponseCode::OK);
+    rc = apcService->cancelPrompt(listener);
+    ASSERT_TRUE(rc.isOk());
 
     future.wait();
-    auto [rc, dataThatWasConfirmed] = future.get();
+    auto [responseCode, dataThatWasConfirmed] = future.get();
 
-    ASSERT_EQ(rc, ConfirmationResponseCode::Aborted);
+    ASSERT_EQ(responseCode, apc::ResponseCode::ABORTED);
 }
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
new file mode 100644
index 0000000..0ba49ed
--- /dev/null
+++ b/keystore2/Android.bp
@@ -0,0 +1,148 @@
+// Copyright 2020, 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 {
+    // 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_defaults {
+    name: "libkeystore2_defaults",
+    crate_name: "keystore2",
+    srcs: ["src/lib.rs"],
+
+    rustlibs: [
+        "android.hardware.security.keymint-V1-rust",
+        "android.hardware.security.secureclock-V1-rust",
+        "android.hardware.security.sharedsecret-V1-rust",
+        "android.os.permissions_aidl-rust",
+        "android.security.apc-rust",
+        "android.security.authorization-rust",
+        "android.security.compat-rust",
+        "android.security.maintenance-rust",
+        "android.security.remoteprovisioning-rust",
+        "android.system.keystore2-V1-rust",
+        "libanyhow",
+        "libbinder_rs",
+        "libcutils_bindgen",
+        "libkeystore2_aaid-rust",
+        "libkeystore2_apc_compat-rust",
+        "libkeystore2_crypto_rust",
+        "libkeystore2_km_compat",
+        "libkeystore2_selinux",
+        "libkeystore2_system_property-rust",
+        "libkeystore2_vintf_rust",
+        "liblazy_static",
+        "liblibc",
+        "liblibsqlite3_sys",
+        "liblog_event_list",
+        "liblog_rust",
+        "librand",
+        "librusqlite",
+        "libstatslog_rust",
+        "libstatslog_rust_header",
+        "libstatspull_rust",
+        "libthiserror",
+    ],
+    shared_libs: [
+        "libcutils",
+    ],
+    features: [
+        "watchdog",
+    ],
+}
+
+rust_library {
+    name: "libkeystore2",
+    defaults: ["libkeystore2_defaults"],
+}
+
+rust_library {
+    name: "libkeystore2_test_utils",
+    crate_name: "keystore2_test_utils",
+    srcs: ["test_utils/lib.rs"],
+    rustlibs: [
+        "liblog_rust",
+        "librand",
+    ],
+}
+
+rust_test {
+    name: "keystore2_test",
+    crate_name: "keystore2",
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    compile_multilib: "first",
+    defaults: ["libkeystore2_defaults"],
+    rustlibs: [
+        "libandroid_logger",
+        "libkeystore2_test_utils",
+        "libnix",
+    ],
+    // The test should always include watchdog.
+    features: [
+        "watchdog",
+    ],
+}
+
+rust_binary {
+    name: "keystore2",
+    srcs: ["src/keystore2_main.rs"],
+    rustlibs: [
+        "libandroid_logger",
+        "libbinder_rs",
+        "libkeystore2",
+        "liblog_rust",
+        "libvpnprofilestore-rust",
+    ],
+    init_rc: ["keystore2.rc"],
+
+    // In S, keystore2 is the only process using dynamically linked Rust from
+    // /system. As a result, the usual savings from sharing libraries don't
+    // apply.
+    // Remove `prefer_rlib: true` once we have several processes, once a space
+    // calculation shows net RAM savings, or once we have automatic variant
+    // selection available in the build system.
+    prefer_rlib: true,
+
+    // TODO(b/187412695)
+    // This is a hack to work around the build system not installing
+    // dynamic dependencies of rlibs to the device. This section should
+    // be removed once that works correctly.
+    shared_libs: [
+        "android.hardware.confirmationui@1.0",
+        "android.hardware.security.sharedsecret-V1-ndk_platform",
+        "android.security.compat-ndk_platform",
+        "libc",
+        "libdl_android",
+        "libdl",
+        "libandroidicu",
+        "libkeymint",
+        "libkeystore2_aaid",
+        "libkeystore2_apc_compat",
+        "libkeystore2_crypto",
+        "libkeystore2_vintf_cpp",
+        "libkm_compat_service",
+        "libkm_compat",
+        "libm",
+        "libstatspull",
+        "libstatssocket",
+    ],
+
+    vintf_fragments: ["android.system.keystore2-service.xml"],
+}
diff --git a/keystore2/TEST_MAPPING b/keystore2/TEST_MAPPING
new file mode 100644
index 0000000..16b6f85
--- /dev/null
+++ b/keystore2/TEST_MAPPING
@@ -0,0 +1,16 @@
+{
+  "presubmit": [
+    {
+      "name": "keystore2_crypto_test"
+    },
+    {
+      "name": "keystore2_crypto_test_rust"
+    },
+    {
+      "name": "keystore2_test"
+    },
+    {
+      "name": "CtsIdentityTestCases"
+    }
+  ]
+}
diff --git a/keystore2/aaid/Android.bp b/keystore2/aaid/Android.bp
new file mode 100644
index 0000000..c04ce51
--- /dev/null
+++ b/keystore2/aaid/Android.bp
@@ -0,0 +1,59 @@
+// Copyright 2020, 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 {
+    // 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: [
+        "aaid.cpp",
+    ],
+    shared_libs: [
+        "libkeystore-attestation-application-id"
+    ],
+}
+
+rust_bindgen {
+    name: "libkeystore2_aaid_bindgen",
+    wrapper_src: "aaid.hpp",
+    crate_name: "keystore2_aaid_bindgen",
+    source_stem: "bindings",
+
+    bindgen_flags: [
+        "--size_t-is-usize",
+        "--allowlist-function=aaid_keystore_attestation_id",
+        "--allowlist-var=KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE",
+    ],
+}
+
+rust_library {
+    name: "libkeystore2_aaid-rust",
+    crate_name: "keystore2_aaid",
+    srcs: [
+        "lib.rs",
+    ],
+    rustlibs: [
+        "libkeystore2_aaid_bindgen",
+    ],
+    shared_libs: [
+        "libkeystore2_aaid",
+    ],
+}
diff --git a/keystore2/aaid/aaid.cpp b/keystore2/aaid/aaid.cpp
new file mode 100644
index 0000000..fd3faf6
--- /dev/null
+++ b/keystore2/aaid/aaid.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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 "aaid.hpp"
+
+#include <keystore/keystore_attestation_id.h>
+
+using android::security::gather_attestation_application_id;
+
+uint32_t aaid_keystore_attestation_id(uint32_t uid, uint8_t* aaid, size_t* aaid_size) {
+    static_assert(sizeof(uint32_t) == sizeof(uid_t), "uid_t has unexpected size");
+    static_assert(sizeof(uint32_t) == sizeof(android::status_t), "status_t has unexpected size");
+    static_assert(KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE ==
+                      android::security::KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE,
+                  "KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE sizes don't match.");
+    auto result = gather_attestation_application_id(uid);
+    if (!result.isOk()) {
+        return result.status();
+    }
+    if (result.value().size() > KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE) {
+        return ::android::NO_MEMORY;
+    }
+    if (*aaid_size != KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE) {
+        return ::android::BAD_VALUE;
+    }
+    std::copy(result.value().begin(), result.value().end(), aaid);
+    *aaid_size = result.value().size();
+    return ::android::OK;
+}
diff --git a/keystore2/aaid/aaid.hpp b/keystore2/aaid/aaid.hpp
new file mode 100644
index 0000000..9e2c148
--- /dev/null
+++ b/keystore2/aaid/aaid.hpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+/**
+ * This is a redefinition of KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE in
+ * system/security/keystore/keystore_attestation_id.h and must be kept in sync.
+ * There is a static assert in aaid.cpp to assure that they are in sync.
+ * We redefine this here to avoid unnecessary build dependencies for
+ * the rust bindgen target.
+ */
+constexpr const size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
+
+extern "C" {
+    /**
+     * Fills the buffer at aaid with the attestation application id of the app uid.
+     * The buffer must be exactly KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE bytes in size.
+     * *aaid_size is set to the number of bytes written to aaid.
+     *
+     * @param uid the uid of the app to retrieve the aaid for.
+     * @param aaid output buffer for the attestation id.
+     * @param aaid_size must be set to the size of the output buffer, which must be exactly
+     *          KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE bytes in size, by the caller. On success
+     *          it is set to the number of bytes written.
+     * @return OK on success.
+     */
+    uint32_t aaid_keystore_attestation_id(uint32_t uid, uint8_t* aaid, size_t* aaid_size);
+}
diff --git a/keystore2/aaid/lib.rs b/keystore2/aaid/lib.rs
new file mode 100644
index 0000000..3187198
--- /dev/null
+++ b/keystore2/aaid/lib.rs
@@ -0,0 +1,35 @@
+// Copyright 2020, 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.
+
+//! Rust binding for getting the attestation application id.
+
+use keystore2_aaid_bindgen::{
+    aaid_keystore_attestation_id, KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE,
+};
+
+/// Returns the attestation application id for the given uid or an error code
+/// corresponding to ::android::status_t.
+pub fn get_aaid(uid: u32) -> Result<Vec<u8>, u32> {
+    let mut buffer = [0u8; KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE];
+    let mut size = KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE;
+    // Safety:
+    // aaid_keystore_attestation_id expects a buffer of exactly
+    // KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE bytes and returns the number of bytes written
+    // in the second pointer argument.
+    let status = unsafe { aaid_keystore_attestation_id(uid, buffer.as_mut_ptr(), &mut size) };
+    match status {
+        0 => Ok(buffer[0..size as usize].to_vec()),
+        status => Err(status),
+    }
+}
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
new file mode 100644
index 0000000..06fdb48
--- /dev/null
+++ b/keystore2/aidl/Android.bp
@@ -0,0 +1,167 @@
+// Copyright 2020, 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 {
+    // 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", ],
+    imports: [ "android.hardware.security.keymint" ],
+    unstable: true,
+    backend: {
+        java: {
+            platform_apis: true,
+            srcs_available: true,
+        },
+        rust: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        }
+    },
+}
+
+aidl_interface {
+    name: "android.security.authorization",
+    srcs: [ "android/security/authorization/*.aidl" ],
+    imports: [
+        "android.hardware.security.keymint",
+        "android.hardware.security.secureclock",
+    ],
+    unstable: true,
+    backend: {
+        java: {
+            platform_apis: true,
+            srcs_available: true,
+        },
+        rust: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        }
+    },
+}
+
+aidl_interface {
+    name: "android.security.apc",
+    srcs: [ "android/security/apc/*.aidl" ],
+    unstable: true,
+    backend: {
+        java: {
+            enabled: true,
+            srcs_available: true,
+        },
+        rust: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+        }
+    },
+}
+
+aidl_interface {
+    name: "android.security.compat",
+    srcs: [ "android/security/compat/*.aidl" ],
+    imports: [
+        "android.hardware.security.keymint",
+        "android.hardware.security.secureclock",
+        "android.hardware.security.sharedsecret",
+    ],
+    unstable: true,
+    backend: {
+        java: {
+            platform_apis: true,
+            srcs_available: true,
+        },
+        rust: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        },
+    },
+}
+
+aidl_interface {
+    name: "android.security.remoteprovisioning",
+    srcs: [ "android/security/remoteprovisioning/*.aidl" ],
+    imports: [
+        "android.hardware.security.keymint",
+    ],
+    unstable: true,
+    backend: {
+        java: {
+            platform_apis: true,
+            srcs_available: true,
+        },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        },
+        rust: {
+            enabled: true,
+        },
+    },
+}
+
+aidl_interface {
+    name: "android.security.maintenance",
+    srcs: [ "android/security/maintenance/*.aidl" ],
+    imports: [
+        "android.system.keystore2",
+    ],
+    unstable: true,
+    backend: {
+        java: {
+            platform_apis: true,
+            srcs_available: true,
+        },
+        rust: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        }
+    },
+}
+
+aidl_interface {
+    name: "android.security.vpnprofilestore",
+    srcs: [ "android/security/vpnprofilestore/*.aidl" ],
+    unstable: true,
+    backend: {
+        java: {
+            platform_apis: true,
+            srcs_available: true,
+        },
+        rust: {
+            enabled: true,
+        },
+    },
+}
+
diff --git a/keystore2/aidl/android/security/apc/IConfirmationCallback.aidl b/keystore2/aidl/android/security/apc/IConfirmationCallback.aidl
new file mode 100644
index 0000000..277b9dd
--- /dev/null
+++ b/keystore2/aidl/android/security/apc/IConfirmationCallback.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.apc;
+
+import android.security.apc.ResponseCode;
+
+/**
+ * This callback interface must be implemented by the client to receive the result of the user
+ * confirmation.
+ * @hide
+ */
+interface IConfirmationCallback {
+    /**
+     * This callback gets called by the implementing service when a pending confirmation prompt
+     * gets finalized.
+     *
+     * @param result
+     *  - ResponseCode.OK On success. In this case dataConfirmed must be non null.
+     *  - ResponseCode.CANCELLED If the user cancelled the prompt. In this case dataConfirmed must
+     *           be null.
+     *  - ResponseCode.ABORTED If the client called IProtectedConfirmation.cancelPrompt() or if the
+     *           prompt was cancelled by the system due to an asynchronous event. In this case
+     *           dataConfirmed must be null.
+     *
+     * @param dataConfirmed This is the message that was confirmed and for which a confirmation
+     *           token is now available in implementing service. A subsequent attempt to sign this
+     *           message with a confirmation bound key will succeed. The message is a CBOR map
+     *           including the prompt text and the extra data.
+     */
+    oneway void onCompleted(in ResponseCode result, in @nullable byte[] dataConfirmed);
+}
diff --git a/keystore2/aidl/android/security/apc/IProtectedConfirmation.aidl b/keystore2/aidl/android/security/apc/IProtectedConfirmation.aidl
new file mode 100644
index 0000000..3162224
--- /dev/null
+++ b/keystore2/aidl/android/security/apc/IProtectedConfirmation.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2020 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.apc;
+
+import android.security.apc.IConfirmationCallback;
+
+/** @hide */
+interface IProtectedConfirmation {
+
+    /**
+     * When set in the uiOptionFlags parameter of presentPrompt, indicates to the implementation
+     * that it shall use inverted color mode.
+     */
+    const int FLAG_UI_OPTION_INVERTED = 1;
+    /**
+     * When set in the uiOptionFlags parameter of presentPrompt, indicates to the implementation
+     * that it shall use magnified font mode.
+     */
+    const int FLAG_UI_OPTION_MAGNIFIED = 2;
+
+    /**
+     * Present the confirmation prompt. The caller must implement IConfirmationCallback and pass
+     * it to this function as listener.
+     *
+     * @param listener Must implement IConfirmationCallback. Doubles as session identifier when
+     *           passed to cancelPrompt.
+     * @param promptText The text that will be displayed to the user using the protected
+     *           confirmation UI.
+     * @param extraData Extra data, e.g., a nonce, that will be included in the to-be-signed
+     *           message.
+     * @param locale The locale string is used to select the language for the instructions
+     *           displayed by the confirmation prompt.
+     * @param uiOptionFlags Bitwise combination of FLAG_UI_OPTION_* see above.
+     *
+     * Service specific error codes:
+     *  - ResponseCode.OPERATION_PENDING If another prompt is already pending.
+     *  - ResponseCode.SYSTEM_ERROR An unexpected error occurred.
+     */
+    void presentPrompt(in IConfirmationCallback listener, in String promptText,
+            in byte[] extraData, in String locale, in int uiOptionFlags);
+
+    /**
+     * Cancel an ongoing prompt.
+     *
+     * @param listener Must implement IConfirmationCallback, although in this context this binder
+     *            token is only used to identify the session that is to be cancelled.
+     *
+     * Service specific error code:
+     *  - ResponseCode.IGNORED If the listener does not represent an ongoing prompt session.
+     */
+    void cancelPrompt(IConfirmationCallback listener);
+
+    /**
+     * Returns true if the device supports Android Protected Confirmation.
+     */
+    boolean isSupported();
+}
diff --git a/keystore2/aidl/android/security/apc/ResponseCode.aidl b/keystore2/aidl/android/security/apc/ResponseCode.aidl
new file mode 100644
index 0000000..9a3619f
--- /dev/null
+++ b/keystore2/aidl/android/security/apc/ResponseCode.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2020, 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.apc;
+
+/**
+ * Used as service specific exception code by IProtectedConfirmation and as result
+ * code by IConfirmationCallback
+ * @hide
+ */
+@Backing(type="int")
+enum ResponseCode {
+    /**
+     * The prompt completed successfully with the user confirming the message (callback result).
+     */
+    OK = 0,
+    /**
+     * The user cancelled the TUI (callback result).
+     */
+    CANCELLED = 1,
+    /**
+     * The prompt was aborted (callback result). This may happen when the app cancels the prompt,
+     * or when the prompt was cancelled due to an unexpected asynchronous event, such as an
+     * incoming phone call.
+     */
+    ABORTED = 2,
+    /**
+     * Another prompt cannot be started because another prompt is pending.
+     */
+    OPERATION_PENDING = 3,
+    /**
+     * The request was ignored.
+     */
+    IGNORED = 4,
+    /**
+     * An unexpected system error occurred.
+     */
+    SYSTEM_ERROR = 5,
+    /**
+     * Backend is not implemented.
+     */
+    UNIMPLEMENTED = 6,
+    /**
+     * Permission Denied.
+     */
+    PERMISSION_DENIED = 30,
+}
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl
similarity index 69%
copy from keystore/binder/android/security/keymaster/OperationResult.aidl
copy to keystore2/aidl/android/security/attestationmanager/ByteArray.aidl
index db689d4..dc37b1b 100644
--- a/keystore/binder/android/security/keymaster/OperationResult.aidl
+++ b/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,12 @@
  * limitations under the License.
  */
 
-package android.security.keymaster;
+package android.security.attestationmanager;
 
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
+/**
+ * Simple data holder for a byte array, allowing for multidimensional arrays in AIDL.
+ * @hide
+ */
+parcelable ByteArray {
+    byte[] data;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl b/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl
new file mode 100644
index 0000000..e77a21e
--- /dev/null
+++ b/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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.attestationmanager;
+
+import android.security.attestationmanager.ByteArray;
+import android.hardware.security.keymint.KeyParameter;
+
+/**
+ * Internal interface for performing device attestation.
+ * @hide
+ */
+interface IAttestationManager {
+    /**
+     * Attest a provided list of device identifiers.
+     *
+     * @return The signed certificate chain, with each individual certificate encoded as a byte
+     *         array.
+     */
+    ByteArray[] attestDevice(
+            in KeyParameter[] deviceIdentifiers, boolean useIndividualAttestation,
+            in byte[] attestationChallenge, int securityLevel);
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/authorization/AuthorizationTokens.aidl b/keystore2/aidl/android/security/authorization/AuthorizationTokens.aidl
new file mode 100644
index 0000000..9061998
--- /dev/null
+++ b/keystore2/aidl/android/security/authorization/AuthorizationTokens.aidl
@@ -0,0 +1,33 @@
+// Copyright 2021, 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.authorization;
+
+import android.hardware.security.keymint.HardwareAuthToken;
+import android.hardware.security.secureclock.TimeStampToken;
+
+/**
+ * This parcelable is returned by `IKeystoreAuthorization::getAuthTokensForCredStore`.
+ * @hide
+ */
+parcelable AuthorizationTokens {
+    /**
+     * HardwareAuthToken provided by an authenticator.
+     */
+    HardwareAuthToken authToken;
+    /**
+     * TimeStampToken provided by a SecureClock.
+     */
+    TimeStampToken timestampToken;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/authorization/IKeystoreAuthorization.aidl b/keystore2/aidl/android/security/authorization/IKeystoreAuthorization.aidl
new file mode 100644
index 0000000..3f33431
--- /dev/null
+++ b/keystore2/aidl/android/security/authorization/IKeystoreAuthorization.aidl
@@ -0,0 +1,116 @@
+// Copyright 2020, 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.authorization;
+
+import android.hardware.security.keymint.HardwareAuthToken;
+import android.security.authorization.LockScreenEvent;
+import android.security.authorization.AuthorizationTokens;
+
+// TODO: mark the interface with @SensitiveData when the annotation is ready (b/176110256).
+
+/**
+ * IKeystoreAuthorization interface exposes the methods for other system components to
+ * provide keystore with the information required to enforce authorizations on key usage.
+ * @hide
+ */
+ @SensitiveData
+interface IKeystoreAuthorization {
+    /**
+     * Allows the Android authenticators to hand over an auth token to Keystore.
+     * Callers require 'AddAuth' permission.
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the callers do not have the 'AddAuth' permission.
+     * `ResponseCode::SYSTEM_ERROR` - if failed to store the auth token in the database or if failed
+     * to add the auth token to the operation, if it is a per-op auth token.
+     *
+     * @param authToken The auth token created by an authenticator, upon user authentication.
+     */
+    void addAuthToken(in HardwareAuthToken authToken);
+
+    /**
+     * Unlocks the keystore for the given user id.
+     * Callers require 'Unlock' permission.
+     * If a password was set, a password must be given on unlock or the operation fails.
+     *
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the callers do not have the 'Unlock' permission.
+     * `ResponseCode::SYSTEM_ERROR` - if failed to perform lock/unlock operations due to various
+     * `ResponseCode::VALUE_CORRUPTED` - if the super key can not be decrypted.
+     * `ResponseCode::KEY_NOT_FOUND` - if the super key is not found.
+     *
+     * @lockScreenEvent - Indicates what happened.
+     *                    * LockScreenEvent.UNLOCK if the screen was unlocked.
+     *                    * LockScreenEvent.LOCK if the screen was locked.
+     *
+     * @param userId - Android user id
+     *
+     * @param password - synthetic password derived by the user denoted by the user id
+     *
+     * @param unlockingSids - list of biometric SIDs for this user. This will be null when
+     *                        lockScreenEvent is UNLOCK, but may be non-null when
+     *                        lockScreenEvent is LOCK.
+     *
+     *                        When the device is unlocked, Keystore stores in memory
+     *                        a super-encryption key that protects UNLOCKED_DEVICE_REQUIRED
+     *                        keys; this key is wiped from memory when the device is locked.
+     *
+     *                        If unlockingSids is non-empty on lock, then before the
+     *                        super-encryption key is wiped from memory, a copy of it
+     *                        is stored in memory encrypted with a fresh AES key.
+     *                        This key is then imported into KM, tagged such that it can be
+     *                        used given a valid, recent auth token for any of the
+     *                        unlockingSids.
+     *
+     *                        Then, when the device is unlocked again, if a suitable auth token
+     *                        has been sent to keystore, it is used to recover the
+     *                        super-encryption key, so that UNLOCKED_DEVICE_REQUIRED keys can
+     *                        be used once again.
+     */
+    void onLockScreenEvent(in LockScreenEvent lockScreenEvent, in int userId,
+                           in @nullable byte[] password, in @nullable long[] unlockingSids);
+
+    /**
+     * Allows Credstore to retrieve a HardwareAuthToken and a TimestampToken.
+     * Identity Credential Trusted App can run either in the TEE or in other secure Hardware.
+     * So, credstore always need to retrieve a TimestampToken along with a HardwareAuthToken.
+     *
+     * The passed in |challenge| parameter must always be non-zero.
+     *
+     * The returned TimestampToken will always have its |challenge| field set to
+     * the |challenge| parameter.
+     *
+     * This method looks through auth-tokens cached by keystore which match
+     * the passed-in |secureUserId|.
+     * The most recent matching auth token which has a |challenge| field which matches
+     * the passed-in |challenge| parameter is returned.
+     * In this case the |authTokenMaxAgeMillis| parameter is not used.
+     *
+     * Otherwise, the most recent matching auth token which is younger
+     * than |authTokenMaxAgeMillis| is returned.
+     *
+     * This method is called by credstore (and only credstore).
+     *
+     * The caller requires 'get_auth_token' permission.
+     *
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the caller does not have the 'get_auth_token'
+     *                                     permission.
+     * `ResponseCode::SYSTEM_ERROR` - if failed to obtain an authtoken from the database.
+     * `ResponseCode::NO_AUTH_TOKEN_FOUND` - a matching auth token is not found.
+     * `ResponseCode::INVALID_ARGUMENT` - if the passed-in |challenge| parameter is zero.
+     */
+    AuthorizationTokens getAuthTokensForCredStore(in long challenge, in long secureUserId,
+     in long authTokenMaxAgeMillis);
+}
diff --git a/keystore2/aidl/android/security/authorization/LockScreenEvent.aidl b/keystore2/aidl/android/security/authorization/LockScreenEvent.aidl
new file mode 100644
index 0000000..c7553a2
--- /dev/null
+++ b/keystore2/aidl/android/security/authorization/LockScreenEvent.aidl
@@ -0,0 +1,22 @@
+// Copyright 2020, 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.authorization;
+
+/** @hide */
+@Backing(type="int")
+enum LockScreenEvent {
+    UNLOCK = 0,
+    LOCK = 1,
+}
diff --git a/keystore2/aidl/android/security/authorization/ResponseCode.aidl b/keystore2/aidl/android/security/authorization/ResponseCode.aidl
new file mode 100644
index 0000000..169dc7b
--- /dev/null
+++ b/keystore2/aidl/android/security/authorization/ResponseCode.aidl
@@ -0,0 +1,57 @@
+// Copyright 2021, 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.authorization;
+
+/**
+ * Used as exception codes by IKeystoreAuthorization.
+ * @hide
+ */
+@Backing(type="int")
+enum ResponseCode {
+    /**
+     * A matching auth token is not found.
+     */
+    NO_AUTH_TOKEN_FOUND = 1,
+    /**
+     * The matching auth token is expired.
+     */
+    AUTH_TOKEN_EXPIRED = 2,
+    /**
+     * Same as in keystore2/ResponseCode.aidl.
+     * Any unexpected Error such as IO or communication errors.
+     */
+    SYSTEM_ERROR = 4,
+    /**
+     * Same as in keystore2/ResponseCode.aidl.
+     * Indicates that the caller does not have the permissions for the attempted request.
+     */
+    PERMISSION_DENIED = 6,
+    /**
+     * Same as in keystore2/ResponseCode.aidl.
+     * Indicates that the requested key does not exist.
+     */
+    KEY_NOT_FOUND = 7,
+    /**
+     * Same as in keystore2/ResponseCode.aidl.
+     * Indicates that a value being processed is corrupted.
+     */
+    VALUE_CORRUPTED = 8,
+    /**
+     * Same as in keystore2/ResponseCode.aidl.
+     * Indicates that an invalid argument was passed to an API call.
+     */
+    INVALID_ARGUMENT = 20,
+
+ }
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/compat/IKeystoreCompatService.aidl b/keystore2/aidl/android/security/compat/IKeystoreCompatService.aidl
new file mode 100644
index 0000000..50bfa19
--- /dev/null
+++ b/keystore2/aidl/android/security/compat/IKeystoreCompatService.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 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.compat;
+
+import android.hardware.security.keymint.IKeyMintDevice;
+import android.hardware.security.keymint.SecurityLevel;
+import android.hardware.security.secureclock.ISecureClock;
+import android.hardware.security.sharedsecret.ISharedSecret;
+
+/**
+ * The compatibility service allows Keystore 2.0 to connect to legacy wrapper implementations that
+ * it hosts itself without registering them as a service. Keystore 2.0 would not be allowed to
+ * register a HAL service, so instead it registers this service which it can then connect to.
+ * @hide
+ */
+interface IKeystoreCompatService {
+    /**
+     * Return an implementation of IKeyMintDevice, that it implemented by Keystore 2.0 itself
+     * by means of Keymaster 4.1 or lower.
+     */
+    IKeyMintDevice getKeyMintDevice (SecurityLevel securityLevel);
+
+    /**
+     * Returns an implementation of ISecureClock, that is implemented by Keystore 2.0 itself
+     * by means of Keymaster 4.x.
+     */
+    ISecureClock getSecureClock ();
+
+    /**
+     * Returns an implementation of ISharedSecret, that is implemented by Keystore 2.0 itself
+     * by means of Keymaster 4.x.
+     */
+    ISharedSecret getSharedSecret (SecurityLevel securityLevel);
+}
diff --git a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
new file mode 100644
index 0000000..5f91e79
--- /dev/null
+++ b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
@@ -0,0 +1,126 @@
+// Copyright 2021, 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.maintenance;
+
+import android.system.keystore2.Domain;
+import android.system.keystore2.KeyDescriptor;
+import android.security.maintenance.UserState;
+
+/**
+ * IKeystoreMaintenance interface exposes the methods for adding/removing users and changing the
+ * user's password.
+ * @hide
+ */
+ @SensitiveData
+interface IKeystoreMaintenance {
+
+    /**
+     * Allows LockSettingsService to inform keystore about adding a new user.
+     * Callers require 'AddUser' permission.
+     *
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the callers do not have the 'AddUser' permission.
+     * `ResponseCode::SYSTEM_ERROR` - if failed to delete the keys of an existing user with the same
+     * user id.
+     *
+     * @param userId - Android user id
+     */
+    void onUserAdded(in int userId);
+
+    /**
+     * Allows LockSettingsService to inform keystore about removing a user.
+     * Callers require 'RemoveUser' permission.
+     *
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the callers do not have the 'RemoveUser' permission.
+     * `ResponseCode::SYSTEM_ERROR` - if failed to delete the keys of the user being deleted.
+     *
+     * @param userId - Android user id
+     */
+    void onUserRemoved(in int userId);
+
+    /**
+     * Allows LockSettingsService to inform keystore about password change of a user.
+     * Callers require 'ChangePassword' permission.
+     *
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the callers does not have the 'ChangePassword'
+     *                                     permission.
+     * `ResponseCode::SYSTEM_ERROR` - if failed to delete the super encrypted keys of the user.
+     * `ResponseCode::Locked' -  if the keystore is locked for the given user.
+     *
+     * @param userId - Android user id
+     * @param password - a secret derived from the synthetic password of the user
+     */
+    void onUserPasswordChanged(in int userId, in @nullable byte[] password);
+
+    /**
+     * This function deletes all keys within a namespace. It mainly gets called when an app gets
+     * removed and all resources of this app need to be cleaned up.
+     *
+     * @param domain - One of Domain.APP or Domain.SELINUX.
+     * @param nspace - The UID of the app that is to be cleared if domain is Domain.APP or
+     *                 the SEPolicy namespace if domain is Domain.SELINUX.
+     */
+    void clearNamespace(Domain domain, long nspace);
+
+    /**
+     * Allows querying user state, given user id.
+     * Callers require 'GetState' permission.
+     *
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the callers do not have the 'GetState'
+     *                                     permission.
+     * `ResponseCode::SYSTEM_ERROR` - if an error occurred when querying the user state.
+     *
+     * @param userId - Android user id
+     */
+    UserState getState(in int userId);
+
+    /**
+     * This function notifies the Keymint device of the specified securityLevel that
+     * early boot has ended, so that they no longer allow early boot keys to be used.
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the caller does not have the 'EarlyBootEnded'
+     *                                     permission.
+     * A KeyMint ErrorCode may be returned indicating a backend diagnosed error.
+     */
+     void earlyBootEnded();
+
+    /**
+     * Informs Keystore 2.0 that the an off body event was detected.
+     *
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - if the caller does not have the `ReportOffBody`
+     *                                     permission.
+     * `ResponseCode::SYSTEM_ERROR` - if an unexpected error occurred.
+     */
+    void onDeviceOffBody();
+
+    /**
+     * Migrate a key from one namespace to another. The caller must have use, grant, and delete
+     * permissions on the source namespace and rebind permissions on the destination namespace.
+     * The source may be specified by Domain::APP, Domain::SELINUX, or Domain::KEY_ID. The target
+     * may be specified by Domain::APP or Domain::SELINUX.
+     *
+     * ## Error conditions:
+     * `ResponseCode::PERMISSION_DENIED` - If the caller lacks any of the required permissions.
+     * `ResponseCode::KEY_NOT_FOUND` - If the source did not exist.
+     * `ResponseCode::INVALID_ARGUMENT` - If the target exists or if any of the above mentioned
+     *                                    requirements for the domain parameter are not met.
+     * `ResponseCode::SYSTEM_ERROR` - An unexpected system error occurred.
+     */
+    void migrateKeyNamespace(in KeyDescriptor source, in KeyDescriptor destination);
+}
diff --git a/keystore2/aidl/android/security/maintenance/UserState.aidl b/keystore2/aidl/android/security/maintenance/UserState.aidl
new file mode 100644
index 0000000..376f4fb
--- /dev/null
+++ b/keystore2/aidl/android/security/maintenance/UserState.aidl
@@ -0,0 +1,23 @@
+// Copyright 2021, 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.maintenance;
+
+/** @hide */
+@Backing(type="int")
+enum UserState {
+    UNINITIALIZED = 0,
+    LSKF_UNLOCKED = 1,
+    LSKF_LOCKED = 2,
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/remoteprovisioning/AttestationPoolStatus.aidl b/keystore2/aidl/android/security/remoteprovisioning/AttestationPoolStatus.aidl
new file mode 100644
index 0000000..3528b42
--- /dev/null
+++ b/keystore2/aidl/android/security/remoteprovisioning/AttestationPoolStatus.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020, 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.remoteprovisioning;
+
+/**
+ * This parcelable provides information about the state of the attestation key pool.
+ * @hide
+ */
+parcelable AttestationPoolStatus {
+    /**
+     * The number of signed attestation certificate chains which will expire when the date provided
+     * to keystore to check against is reached.
+     */
+    int expiring;
+    /**
+     * The number of signed attestation certificate chains which have not yet been assigned to an
+     * app. This should be less than or equal to signed keys. The remainder of `signed` -
+     * `unassigned` gives the number of signed keys that have been assigned to an app.
+     */
+    int unassigned;
+    /**
+     * The number of signed attestation keys. This should be less than or equal to `total`. The
+     * remainder of `total` - `attested` gives the number of keypairs available to be sent off to
+     * the server for signing.
+     */
+    int attested;
+    /**
+     * The total number of attestation keys.
+     */
+    int total;
+}
diff --git a/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
new file mode 100644
index 0000000..4a092af
--- /dev/null
+++ b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2020 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.remoteprovisioning;
+
+import android.hardware.security.keymint.DeviceInfo;
+import android.hardware.security.keymint.ProtectedData;
+import android.hardware.security.keymint.SecurityLevel;
+import android.security.remoteprovisioning.AttestationPoolStatus;
+
+/**
+ * `IRemoteProvisioning` is the interface provided to use the remote provisioning functionality
+ * provided through KeyStore. The intent is for a higher level system component to use these
+ * functions in order to drive the process through which the device can receive functioning
+ * attestation certificates.
+ *
+ * ## Error conditions
+ * Error conditions are reported as service specific errors.
+ * Positive codes correspond to `android.security.remoteprovisioning.ResponseCode`
+ * and indicate error conditions diagnosed by the Keystore 2.0 service.
+ * TODO: Remote Provisioning HAL error code info
+ *
+ * `ResponseCode::PERMISSION_DENIED` if the caller does not have the permissions
+ * to use the RemoteProvisioning API. This permission is defined under access_vectors in SEPolicy
+ * in the keystore2 class: remotely_provision
+ *
+ * `ResponseCode::SYSTEM_ERROR` for any unexpected errors like IO or IPC failures.
+ *
+ * @hide
+ */
+interface IRemoteProvisioning {
+
+    /**
+     * Returns the status of the attestation key pool in the database.
+     *
+     * @param expiredBy The date as seconds since epoch by which to judge expiration status of
+     *                        certificates.
+     *
+     * @param secLevel The security level to specify which KM instance to get the pool for.
+     *
+     * @return The `AttestationPoolStatus` parcelable contains fields communicating information
+     *                        relevant to making decisions about when to generate and provision
+     *                        more attestation keys.
+     */
+    AttestationPoolStatus getPoolStatus(in long expiredBy, in SecurityLevel secLevel);
+
+    /**
+     * This is the primary entry point for beginning a remote provisioning flow. The caller
+     * specifies how many CSRs should be generated and provides an X25519 ECDH public key along
+     * with a challenge to encrypt privacy sensitive portions of the returned CBOR blob and
+     * guarantee freshness of the request to the certifying third party.
+     *
+     * ## Error conditions
+     * `ResponseCode::NO_UNSIGNED_KEYS` if there are no unsigned keypairs in the database that can
+     *                         be used for the CSRs.
+     *
+     * A RemoteProvisioning HAL response code may indicate backend errors such as failed EEK
+     *                         verification.
+     *
+     * @param testMode Whether or not the TA implementing the Remote Provisioning HAL should accept
+     *                         any EEK (Endpoint Encryption Key), or only one signed by a chain
+     *                         that verifies back to the Root of Trust baked into the TA. True
+     *                         means that any key is accepted.
+     *
+     * @param numCsr How many certificate signing requests should be generated.
+     *
+     * @param eek A chain of certificates terminating in an X25519 public key, the Endpoint
+     *                         Encryption Key.
+     *
+     * @param challenge A challenge to be included and MACed in the returned CBOR blob.
+     *
+     * @param secLevel The security level to specify which KM instance from which to generate a
+     *                         CSR.
+     *
+     * @param protectedData The encrypted CBOR blob generated by the remote provisioner
+     *
+     * @return A CBOR blob composed of various elements required by the server to verify the
+     *                         request.
+     */
+    byte[] generateCsr(in boolean testMode, in int numCsr, in byte[] eek, in byte[] challenge,
+        in SecurityLevel secLevel, out ProtectedData protectedData, out DeviceInfo deviceInfo);
+
+    /**
+     * This method provides a way for the returned attestation certificate chains to be provisioned
+     * to the attestation key database. When an app requests an attesation key, it will be assigned
+     * one of these certificate chains along with the corresponding private key.
+     *
+     * @param publicKey The raw public key encoded in the leaf certificate.
+     *
+     * @param batchCert The batch certificate corresponding to the attestation key. Separated for
+     *                          the purpose of making Subject lookup for KM attestation easier.
+     *
+     * @param certs An X.509, DER encoded certificate chain for the attestation key.
+     *
+     * @param expirationDate The expiration date on the certificate chain, provided by the caller
+     *                          for convenience.
+     *
+     * @param secLevel The security level representing the KM instance containing the key that this
+     *                          chain corresponds to.
+     */
+    void provisionCertChain(in byte[] publicKey, in byte[] batchCert, in byte[] certs,
+        in long expirationDate, in SecurityLevel secLevel);
+
+    /**
+     * This method allows the caller to instruct KeyStore to generate and store a key pair to be
+     * used for attestation in the `generateCsr` method. The caller should handle spacing out these
+     * requests so as not to jam up the KeyStore work queue.
+     *
+     * @param is_test_mode Instructs the underlying HAL interface to mark the generated key with a
+     *                        tag to indicate that it's for testing.
+     *
+     * @param secLevel The security level to specify which KM instance should generate a key pair.
+     */
+    void generateKeyPair(in boolean is_test_mode, in SecurityLevel secLevel);
+
+    /**
+     * This method returns the SecurityLevels of whichever instances of
+     * IRemotelyProvisionedComponent are running on the device. The RemoteProvisioner app needs to
+     * know which KM instances it should be generating and managing attestation keys for.
+     *
+     * @return The array of security levels.
+     */
+     SecurityLevel[] getSecurityLevels();
+
+    /**
+     * This method deletes all remotely provisioned attestation keys in the database, regardless
+     * of what state in their life cycle they are in. This is primarily useful to facilitate
+     * testing.
+     *
+     * @return Number of keys deleted
+     */
+    long deleteAllKeys();
+}
diff --git a/keystore2/aidl/android/security/remoteprovisioning/ResponseCode.aidl b/keystore2/aidl/android/security/remoteprovisioning/ResponseCode.aidl
new file mode 100644
index 0000000..c9877db
--- /dev/null
+++ b/keystore2/aidl/android/security/remoteprovisioning/ResponseCode.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020, 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.remoteprovisioning;
+
+@Backing(type="int")
+/** @hide */
+enum ResponseCode {
+    /**
+     * Returned if there are no keys available in the database to be used in a CSR
+     */
+    NO_UNSIGNED_KEYS = 1,
+    /**
+     * The caller has imrproper SELinux permissions to access the Remote Provisioning API.
+     */
+    PERMISSION_DENIED = 2,
+    /**
+     * An unexpected error occurred, likely with IO or IPC.
+     */
+    SYSTEM_ERROR = 3,
+}
diff --git a/keystore2/aidl/android/security/vpnprofilestore/IVpnProfileStore.aidl b/keystore2/aidl/android/security/vpnprofilestore/IVpnProfileStore.aidl
new file mode 100644
index 0000000..8375b7b
--- /dev/null
+++ b/keystore2/aidl/android/security/vpnprofilestore/IVpnProfileStore.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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.vpnprofilestore;
+
+/**
+ * Internal interface for accessing and storing VPN profiles.
+ * @hide
+ */
+interface IVpnProfileStore {
+    /**
+     * Service specific error code indicating that the profile was not found.
+     */
+    const int ERROR_PROFILE_NOT_FOUND = 1;
+
+    /**
+     * Service specific error code indicating that an unexpected system error occurred.
+     */
+    const int ERROR_SYSTEM_ERROR = 2;
+
+    /**
+     * Returns the profile stored under the given alias.
+     *
+     * @param alias name of the profile.
+     * @return The unstructured blob that was passed as profile parameter into put()
+     */
+    byte[] get(in String alias);
+
+    /**
+     * Stores one profile as unstructured blob under the given alias.
+     */
+    void put(in String alias, in byte[] profile);
+
+    /**
+     * Deletes the profile under the given alias.
+     */
+    void remove(in String alias);
+
+    /**
+     * Returns a list of aliases of profiles stored. The list is filtered by prefix.
+     * The resulting strings are the full aliases including the prefix.
+     */
+    String[] list(in String prefix);
+}
\ No newline at end of file
diff --git a/keystore2/android.system.keystore2-service.xml b/keystore2/android.system.keystore2-service.xml
new file mode 100644
index 0000000..6b8d0cb
--- /dev/null
+++ b/keystore2/android.system.keystore2-service.xml
@@ -0,0 +1,9 @@
+<manifest version="1.0" type="framework">
+    <hal format="aidl">
+        <name>android.system.keystore2</name>
+        <interface>
+            <name>IKeystoreService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/keystore2/apc_compat/Android.bp b/keystore2/apc_compat/Android.bp
new file mode 100644
index 0000000..bf21675
--- /dev/null
+++ b/keystore2/apc_compat/Android.bp
@@ -0,0 +1,65 @@
+// Copyright 2020, 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 {
+    // 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: [
+        "apc_compat.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.confirmationui@1.0",
+        "libbase",
+        "libhidlbase",
+        "libutils",
+    ],
+}
+
+rust_bindgen {
+    name: "libkeystore2_apc_compat_bindgen",
+    wrapper_src: "apc_compat.hpp",
+    crate_name: "keystore2_apc_compat_bindgen",
+    source_stem: "bindings",
+
+    bindgen_flags: [
+        "--allowlist-function=tryGetUserConfirmationService",
+        "--allowlist-function=promptUserConfirmation",
+        "--allowlist-function=abortUserConfirmation",
+        "--allowlist-function=closeUserConfirmationService",
+        "--allowlist-var=INVALID_SERVICE_HANDLE",
+        "--allowlist-var=APC_COMPAT_.*",
+    ],
+}
+
+rust_library {
+    name: "libkeystore2_apc_compat-rust",
+    crate_name: "keystore2_apc_compat",
+    srcs: [
+        "apc_compat.rs",
+    ],
+    rustlibs: [
+        "libkeystore2_apc_compat_bindgen",
+    ],
+    shared_libs: [
+        "libkeystore2_apc_compat",
+    ],
+}
diff --git a/keystore2/apc_compat/apc_compat.cpp b/keystore2/apc_compat/apc_compat.cpp
new file mode 100644
index 0000000..08a8e45
--- /dev/null
+++ b/keystore2/apc_compat/apc_compat.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2020 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 "apc_compat.hpp"
+#include <android-base/logging.h>
+#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
+#include <hwbinder/IBinder.h>
+
+#include <memory>
+#include <string>
+#include <thread>
+#include <vector>
+
+#define LOG_TAG "keystore2_apc_compat"
+
+namespace keystore2 {
+
+using android::sp;
+using android::hardware::hidl_death_recipient;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Status;
+using android::hardware::confirmationui::V1_0::IConfirmationResultCallback;
+using android::hardware::confirmationui::V1_0::IConfirmationUI;
+using android::hardware::confirmationui::V1_0::ResponseCode;
+using android::hardware::confirmationui::V1_0::UIOption;
+
+static uint32_t responseCode2Compat(ResponseCode rc) {
+    switch (rc) {
+    case ResponseCode::OK:
+        return APC_COMPAT_ERROR_OK;
+    case ResponseCode::Canceled:
+        return APC_COMPAT_ERROR_CANCELLED;
+    case ResponseCode::Aborted:
+        return APC_COMPAT_ERROR_ABORTED;
+    case ResponseCode::OperationPending:
+        return APC_COMPAT_ERROR_OPERATION_PENDING;
+    case ResponseCode::Ignored:
+        return APC_COMPAT_ERROR_IGNORED;
+    case ResponseCode::SystemError:
+    case ResponseCode::Unimplemented:
+    case ResponseCode::Unexpected:
+    case ResponseCode::UIError:
+    case ResponseCode::UIErrorMissingGlyph:
+    case ResponseCode::UIErrorMessageTooLong:
+    case ResponseCode::UIErrorMalformedUTF8Encoding:
+    default:
+        return APC_COMPAT_ERROR_SYSTEM_ERROR;
+    }
+}
+
+class ConfuiCompatSession : public IConfirmationResultCallback, public hidl_death_recipient {
+  public:
+    static sp<ConfuiCompatSession>* tryGetService() {
+        sp<IConfirmationUI> service = IConfirmationUI::tryGetService();
+        if (service) {
+            return new sp(new ConfuiCompatSession(std::move(service)));
+        } else {
+            return nullptr;
+        }
+    }
+
+    uint32_t promptUserConfirmation(ApcCompatCallback callback, const char* prompt_text,
+                                    const uint8_t* extra_data, size_t extra_data_size,
+                                    const char* locale, ApcCompatUiOptions ui_options) {
+        std::string hidl_prompt(prompt_text);
+        std::vector<uint8_t> hidl_extra(extra_data, extra_data + extra_data_size);
+        std::string hidl_locale(locale);
+        std::vector<UIOption> hidl_ui_options;
+        if (ui_options.inverted) {
+            hidl_ui_options.push_back(UIOption::AccessibilityInverted);
+        }
+        if (ui_options.magnified) {
+            hidl_ui_options.push_back(UIOption::AccessibilityMagnified);
+        }
+        auto lock = std::lock_guard(callback_lock_);
+        if (callback_.result != nullptr) {
+            return APC_COMPAT_ERROR_OPERATION_PENDING;
+        }
+        auto err = service_->linkToDeath(sp(this), 0);
+        if (!err.isOk()) {
+            LOG(ERROR) << "Communication error: promptUserConfirmation: "
+                          "Trying to register death recipient: "
+                       << err.description();
+            return APC_COMPAT_ERROR_SYSTEM_ERROR;
+        }
+
+        auto rc = service_->promptUserConfirmation(sp(this), hidl_prompt, hidl_extra, hidl_locale,
+                                                   hidl_ui_options);
+        if (!rc.isOk()) {
+            LOG(ERROR) << "Communication error: promptUserConfirmation: " << rc.description();
+        }
+        if (rc == ResponseCode::OK) {
+            callback_ = callback;
+        }
+        return responseCode2Compat(rc.withDefault(ResponseCode::SystemError));
+    }
+
+    void abort() { service_->abort(); }
+
+    void
+    finalize(ResponseCode responseCode,
+             std::optional<std::reference_wrapper<const hidl_vec<uint8_t>>> dataConfirmed,
+             std::optional<std::reference_wrapper<const hidl_vec<uint8_t>>> confirmationToken) {
+        ApcCompatCallback callback;
+        {
+            auto lock = std::lock_guard(callback_lock_);
+            // Calling the callback consumes the callback data structure. We have to make
+            // sure that it can only be called once.
+            callback = callback_;
+            callback_ = {nullptr, nullptr};
+            // Unlock the callback_lock_ here. It must never be held while calling the callback.
+        }
+
+        if (callback.result != nullptr) {
+            service_->unlinkToDeath(sp(this));
+
+            size_t dataConfirmedSize = 0;
+            const uint8_t* dataConfirmedPtr = nullptr;
+            size_t confirmationTokenSize = 0;
+            const uint8_t* confirmationTokenPtr = nullptr;
+            if (responseCode == ResponseCode::OK) {
+                if (dataConfirmed) {
+                    dataConfirmedPtr = dataConfirmed->get().data();
+                    dataConfirmedSize = dataConfirmed->get().size();
+                }
+                if (dataConfirmed) {
+                    confirmationTokenPtr = confirmationToken->get().data();
+                    confirmationTokenSize = confirmationToken->get().size();
+                }
+            }
+            callback.result(callback.data, responseCode2Compat(responseCode), dataConfirmedPtr,
+                            dataConfirmedSize, confirmationTokenPtr, confirmationTokenSize);
+        }
+    }
+
+    // IConfirmationResultCallback overrides:
+    android::hardware::Return<void> result(ResponseCode responseCode,
+                                           const hidl_vec<uint8_t>& dataConfirmed,
+                                           const hidl_vec<uint8_t>& confirmationToken) override {
+        finalize(responseCode, dataConfirmed, confirmationToken);
+        return Status::ok();
+    };
+
+    void serviceDied(uint64_t /* cookie */,
+                     const ::android::wp<::android::hidl::base::V1_0::IBase>& /* who */) override {
+        finalize(ResponseCode::SystemError, {}, {});
+    }
+
+  private:
+    ConfuiCompatSession(sp<IConfirmationUI> service)
+        : service_(service), callback_{nullptr, nullptr} {}
+    sp<IConfirmationUI> service_;
+
+    // The callback_lock_ protects the callback_ field against concurrent modification.
+    // IMPORTANT: It must never be held while calling the call back.
+    std::mutex callback_lock_;
+    ApcCompatCallback callback_;
+};
+
+}  // namespace keystore2
+
+using namespace keystore2;
+
+ApcCompatServiceHandle tryGetUserConfirmationService() {
+    return reinterpret_cast<ApcCompatServiceHandle>(ConfuiCompatSession::tryGetService());
+}
+
+uint32_t promptUserConfirmation(ApcCompatServiceHandle handle, ApcCompatCallback callback,
+                                const char* prompt_text, const uint8_t* extra_data,
+                                size_t extra_data_size, char const* locale,
+                                ApcCompatUiOptions ui_options) {
+    auto session = reinterpret_cast<sp<ConfuiCompatSession>*>(handle);
+    return (*session)->promptUserConfirmation(callback, prompt_text, extra_data, extra_data_size,
+                                              locale, ui_options);
+}
+
+void abortUserConfirmation(ApcCompatServiceHandle handle) {
+    auto session = reinterpret_cast<sp<ConfuiCompatSession>*>(handle);
+    (*session)->abort();
+}
+
+void closeUserConfirmationService(ApcCompatServiceHandle handle) {
+    // Closing the handle implicitly aborts an ongoing sessions.
+    // Note that a resulting callback is still safely conducted, because we only delete a
+    // StrongPointer below. libhwbinder still owns another StrongPointer to this session.
+    abortUserConfirmation(handle);
+    delete reinterpret_cast<sp<ConfuiCompatSession>*>(handle);
+}
+
+const ApcCompatServiceHandle INVALID_SERVICE_HANDLE = nullptr;
diff --git a/keystore2/apc_compat/apc_compat.hpp b/keystore2/apc_compat/apc_compat.hpp
new file mode 100644
index 0000000..15fa5f4
--- /dev/null
+++ b/keystore2/apc_compat/apc_compat.hpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+using ApcCompatServiceHandle = void*;
+
+#define APC_COMPAT_ERROR_OK 0
+#define APC_COMPAT_ERROR_CANCELLED 1
+#define APC_COMPAT_ERROR_ABORTED 2
+#define APC_COMPAT_ERROR_OPERATION_PENDING 3
+#define APC_COMPAT_ERROR_IGNORED 4
+#define APC_COMPAT_ERROR_SYSTEM_ERROR 5
+
+extern "C" {
+
+extern const ApcCompatServiceHandle INVALID_SERVICE_HANDLE;
+
+/**
+ * This struct holds the ui options for the protected confirmation dialog.
+ */
+struct ApcCompatUiOptions {
+    /**
+     * If set to true inverted color mode is used.
+     */
+    bool inverted;
+    /**
+     * If set to true magnified fonts are used.
+     */
+    bool magnified;
+};
+
+/**
+ * Represents a result callback that is called when a confirmation session was successfully
+ * started.
+ * The field `data` is an opaque callback context handle. It must be passed to the `result`
+ * function.
+ *
+ * IMPORTANT: The life cycle of `data` ends when `result` is called. The callback must not
+ *            be called a second time.
+ *
+ * The callback function `result` has the prototype:
+ * void result(
+ *     void* data,
+ *     uint32_t rc,
+ *     const uint8_t* tbs_message,
+ *     size_t tbs_message_size,
+ *     const uint8_t* confirmation_token,
+ *     size_t confirmation_token_size)
+ *
+ * * data - must be the data field of the structure.
+ * * rc - response code, one of:
+ *      * APC_COMPAT_ERROR_OK - The user confirmed the prompt text.
+ *      * APC_COMPAT_ERROR_CANCELLED - The user rejected the prompt text.
+ *      * APC_COMPAT_ERROR_ABORTED - `abortUserConfirmation` was called.
+ *      * APC_COMPAT_ERROR_SYSTEM_ERROR - An unspecified system error occurred.
+ * * tbs_message(_size) - Pointer to and size of the to-be-signed message. Must
+ *      be NULL and 0 respectively if `rc != APC_COMPAT_ERROR_OK`.
+ * * confirmation_token(_size) - Pointer to and size of the confirmation token. Must
+ *      be NULL and 0 respectively if `rc != APC_COMPAT_ERROR_OK`.
+ */
+struct ApcCompatCallback {
+    void* data;
+    void (*result)(void*, uint32_t, const uint8_t*, size_t, const uint8_t*, size_t);
+};
+
+/**
+ * Attempts to make a connection to the confirmationui HIDL backend.
+ * If a valid service handle is returned it stays valid until
+ * `closeUserConfirmationService` is called.
+ *
+ * @return A valid service handle on success or INVALID_SERVICE_HANDLE
+ *         on failure.
+ */
+ApcCompatServiceHandle tryGetUserConfirmationService();
+
+/**
+ * Attempts to start a protected confirmation session on the given service handle.
+ * The function takes ownership of the callback object (`cb`) IFF APC_COMPAT_ERROR_OK
+ * is returned. The resources referenced by the callback object must stay valid
+ * until the callback is called.
+ *
+ * @param handle A valid service handle as returned by `tryGetUserConfirmationService()`.
+ * @cb A ApcCompatCallback structure that represents a callback function with session data.
+ * @param prompt_text A UTF-8 encoded prompt string.
+ * @param extra_data Free form extra data.
+ * @param extra_data_size size of the extra data buffer in bytes.
+ * @param locale A locale string.
+ * @param ui_options A UI options. See ApcCompatUiOptions above.
+ * @retval APC_COMPAT_ERROR_OK on success.
+ * @retval APC_COMPAT_ERROR_OPERATION_PENDING if another operation was already in progress.
+ * @retval APC_COMPAT_ERROR_SYSTEM_ERROR if an unspecified system error occurred.
+ */
+uint32_t promptUserConfirmation(ApcCompatServiceHandle handle, struct ApcCompatCallback cb,
+                                const char* prompt_text, const uint8_t* extra_data,
+                                size_t extra_data_size, char const* locale,
+                                ApcCompatUiOptions ui_options);
+
+/**
+ * Aborts a running confirmation session or no-op if no session is running.
+ * If a session is running this results in a `result` callback with
+ * `rc == APC_COMPAT_ERROR_ABORTED`. Mind though that the callback can still yield other
+ * results even after this function was called, because it may race with an actual user
+ * response. In any case, there will be only one callback response for each session
+ * successfully started with promptUserConfirmation.
+ *
+ * @param handle A valid session handle as returned by `tryGetUserConfirmationService()`
+ */
+void abortUserConfirmation(ApcCompatServiceHandle handle);
+
+/**
+ * Closes a valid service session as returned by `tryGetUserConfirmationService()`.
+ * If a session is still running it is implicitly aborted. In this case, freeing up of the resources
+ * referenced by the service handle is deferred until the callback has completed.
+ *
+ * @param handle A valid session handle as returned by `tryGetUserConfirmationService()`
+ */
+void closeUserConfirmationService(ApcCompatServiceHandle);
+
+}
diff --git a/keystore2/apc_compat/apc_compat.rs b/keystore2/apc_compat/apc_compat.rs
new file mode 100644
index 0000000..57f8710
--- /dev/null
+++ b/keystore2/apc_compat/apc_compat.rs
@@ -0,0 +1,205 @@
+// Copyright 2020, 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.
+
+//! This crate implements a safe wrapper around the ConfirmationUI HIDL spec, which
+//! is the backend for Android Protected Confirmation (APC).
+//!
+//! It provides a safe wrapper around a C++ implementation of ConfirmationUI
+//! client.
+
+use keystore2_apc_compat_bindgen::{
+    abortUserConfirmation, closeUserConfirmationService, promptUserConfirmation, size_t,
+    tryGetUserConfirmationService, ApcCompatCallback, ApcCompatServiceHandle,
+};
+pub use keystore2_apc_compat_bindgen::{
+    ApcCompatUiOptions, APC_COMPAT_ERROR_ABORTED, APC_COMPAT_ERROR_CANCELLED,
+    APC_COMPAT_ERROR_IGNORED, APC_COMPAT_ERROR_OK, APC_COMPAT_ERROR_OPERATION_PENDING,
+    APC_COMPAT_ERROR_SYSTEM_ERROR, INVALID_SERVICE_HANDLE,
+};
+use std::{ffi::CString, slice};
+
+/// Safe wrapper around the ConfirmationUI HIDL spec.
+///
+/// # Example
+/// ```
+/// struct Cb();
+/// impl ApcHalCallback for Cb {
+///     fn result(
+///         &self,
+///         rc: u32,
+///         message: Option<&[u8]>,
+///         token: Option<&[u8]>,
+///     ) {
+///         println!("Callback called with rc: {}, message: {}, token: {}", rc, message, token);
+///     }
+/// };
+///
+/// fn prompt() -> Result<(), u32> {
+///     let hal = ApcHal::try_get_service()?;
+///     hal.prompt_user_confirmation(Box::new(Cb()), "Do you agree?", b"extra data", "en", 0)?;
+/// }
+///
+/// ```
+pub struct ApcHal(ApcCompatServiceHandle);
+
+unsafe impl Send for ApcHal {}
+unsafe impl Sync for ApcHal {}
+
+impl Drop for ApcHal {
+    fn drop(&mut self) {
+        // # Safety:
+        // This ends the life cycle of the contained `ApcCompatServiceHandle` owned by this
+        // `ApcHal` object.
+        //
+        // `ApcHal` objects are only created if a valid handle was acquired so self.0 is
+        // always valid when dropped.
+        unsafe {
+            closeUserConfirmationService(self.0);
+        }
+    }
+}
+
+type Callback = dyn FnOnce(u32, Option<&[u8]>, Option<&[u8]>);
+
+extern "C" fn confirmation_result_callback(
+    handle: *mut ::std::os::raw::c_void,
+    rc: u32,
+    tbs_message: *const u8,
+    tbs_message_size: size_t,
+    confirmation_token: *const u8,
+    confirmation_token_size: size_t,
+) {
+    // # Safety:
+    // The C/C++ implementation must pass to us the handle that was created
+    // and assigned to the `ApcCompatCallback::data` field in
+    // `ApcHal::prompt_user_confirmation` below. Also we consume the handle,
+    // by letting `hal_cb` go out of scope with this function call. So
+    // the C/C++ implementation must assure that each `ApcCompatCallback` is only used once.
+    let hal_cb: Box<Box<Callback>> = unsafe { Box::from_raw(handle as *mut Box<Callback>) };
+    let tbs_message = match (tbs_message.is_null(), tbs_message_size) {
+        (true, _) | (_, 0) => None,
+        (false, s) => Some(
+            // # Safety:
+            // If the pointer and size is not nullptr and not 0 respectively, the C/C++
+            // implementation must pass a valid pointer to an allocation of at least size bytes,
+            // and the pointer must be valid until this function returns.
+            unsafe { slice::from_raw_parts(tbs_message, s as usize) },
+        ),
+    };
+    let confirmation_token = match (confirmation_token.is_null(), confirmation_token_size) {
+        (true, _) | (_, 0) => None,
+        (false, s) => Some(
+            // # Safety:
+            // If the pointer and size is not nullptr and not 0 respectively, the C/C++
+            // implementation must pass a valid pointer to an allocation of at least size bytes,
+            // and the pointer must be valid until this function returns.
+            unsafe { slice::from_raw_parts(confirmation_token, s as usize) },
+        ),
+    };
+    hal_cb(rc, tbs_message, confirmation_token)
+}
+
+impl ApcHal {
+    /// Attempts to connect to the APC (confirmationui) backend. On success, it returns an
+    /// initialized `ApcHal` object.
+    pub fn try_get_service() -> Option<Self> {
+        // # Safety:
+        // `tryGetUserConfirmationService` returns a valid handle or INVALID_SERVICE_HANDLE.
+        // On success, `ApcHal` takes ownership of this handle and frees it with
+        // `closeUserConfirmationService` when dropped.
+        let handle = unsafe { tryGetUserConfirmationService() };
+        match handle {
+            h if h == unsafe { INVALID_SERVICE_HANDLE } => None,
+            h => Some(Self(h)),
+        }
+    }
+
+    /// Attempts to start a confirmation prompt. The given callback is consumed, and it is
+    /// guaranteed to be called eventually IFF this function returns `APC_COMPAT_ERROR_OK`.
+    ///
+    /// The callback has the following arguments:
+    /// rc: u32 - The reason for the termination which takes one of the values.
+    ///       * `APC_COMPAT_ERROR_OK` - The user confirmed the prompted message.
+    ///       * `APC_COMPAT_ERROR_CANCELLED` - The user rejected the prompted message.
+    ///       * `APC_COMPAT_ERROR_ABORTED` - The prompt was aborted either because the client
+    ///          aborted. the session or an asynchronous system event occurred that ended the
+    ///          prompt prematurely.
+    ///       * `APC_COMPAT_ERROR_SYSTEMERROR` - An unspecified system error occurred. Logs may
+    ///          have more information.
+    ///
+    /// data_confirmed: Option<&[u8]> and
+    /// confirmation_token: Option<&[u8]> hold the confirmed message and the confirmation token
+    /// respectively. They must be `Some()` if `rc == APC_COMPAT_ERROR_OK` and `None` otherwise.
+    ///
+    /// `cb` does not get called if this function returns an error.
+    /// (Thus the allow(unused_must_use))
+    #[allow(unused_must_use)]
+    pub fn prompt_user_confirmation<F>(
+        &self,
+        prompt_text: &str,
+        extra_data: &[u8],
+        locale: &str,
+        ui_opts: ApcCompatUiOptions,
+        cb: F,
+    ) -> Result<(), u32>
+    where
+        F: FnOnce(u32, Option<&[u8]>, Option<&[u8]>) + 'static,
+    {
+        let cb_data_ptr = Box::into_raw(Box::new(Box::new(cb) as Box<Callback>));
+        let cb = ApcCompatCallback {
+            data: cb_data_ptr as *mut std::ffi::c_void,
+            result: Some(confirmation_result_callback),
+        };
+        let prompt_text = CString::new(prompt_text).unwrap();
+        let locale = CString::new(locale).unwrap();
+        // # Safety:
+        // The `ApcCompatCallback` object (`cb`) is passed to the callee by value, and with it
+        // ownership of the `data` field pointer. The data pointer is guaranteed to be valid
+        // until the C/C++ implementation calls the callback. Calling the callback consumes
+        // the data pointer. The C/C++ implementation must not access it after calling the
+        // callback and it must not call the callback a second time.
+        //
+        // The C/C++ must make no assumptions about the life time of the other parameters after
+        // the function returns.
+        let rc = unsafe {
+            promptUserConfirmation(
+                self.0,
+                cb,
+                prompt_text.as_ptr(),
+                extra_data.as_ptr(),
+                extra_data.len() as size_t,
+                locale.as_ptr(),
+                ui_opts,
+            )
+        };
+        match rc {
+            APC_COMPAT_ERROR_OK => Ok(()),
+            rc => {
+                // # Safety:
+                // If promptUserConfirmation does not succeed, it must not take ownership of the
+                // callback, so we must destroy it.
+                unsafe { Box::from_raw(cb_data_ptr) };
+                Err(rc)
+            }
+        }
+    }
+
+    /// Aborts a running confirmation session, or no-op if none is running.
+    pub fn abort(&self) {
+        // # Safety:
+        // It is always safe to call `abortUserConfirmation`, because spurious calls are ignored.
+        // The handle argument must be valid, but this is an invariant of `ApcHal`.
+        unsafe { abortUserConfirmation(self.0) }
+    }
+}
diff --git a/keystore2/keystore2.rc b/keystore2/keystore2.rc
new file mode 100644
index 0000000..82bf3b8
--- /dev/null
+++ b/keystore2/keystore2.rc
@@ -0,0 +1,13 @@
+# Start the keystore2 service.
+# Keystore 2.0 changes its working directory to the first positional
+# command line option, i.e., /data/misc/keystore, where it stores its
+# database.
+# Keystore shall run as user keystore and groups keystore, readproc, and log.
+#
+# See system/core/init/README.md for information on the init.rc language.
+
+service keystore2 /system/bin/keystore2 /data/misc/keystore
+    class early_hal
+    user keystore
+    group keystore readproc log
+    writepid /dev/cpuset/foreground/tasks
diff --git a/keystore2/selinux/Android.bp b/keystore2/selinux/Android.bp
new file mode 100644
index 0000000..18063d3
--- /dev/null
+++ b/keystore2/selinux/Android.bp
@@ -0,0 +1,63 @@
+// Copyright 2020, 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 {
+    // 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",
+    srcs: [
+        "src/lib.rs",
+    ],
+
+    shared_libs: [
+        "libselinux",
+    ],
+
+    rustlibs: [
+        "libanyhow",
+        "liblog_rust",
+        "libselinux_bindgen",
+        "libthiserror",
+    ],
+}
+
+rust_test {
+    name: "keystore2_selinux_test",
+    srcs: [
+        "src/lib.rs",
+    ],
+    crate_name: "keystore2_selinux_test",
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+
+    shared_libs: [
+        "libselinux",
+    ],
+
+    rustlibs: [
+        "libandroid_logger",
+        "libanyhow",
+        "liblog_rust",
+        "libselinux_bindgen",
+        "libthiserror",
+    ],
+}
diff --git a/keystore2/selinux/TEST_MAPPING b/keystore2/selinux/TEST_MAPPING
new file mode 100644
index 0000000..0e68257
--- /dev/null
+++ b/keystore2/selinux/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "keystore2_selinux_test"
+    }
+  ]
+}
diff --git a/keystore2/selinux/src/lib.rs b/keystore2/selinux/src/lib.rs
new file mode 100644
index 0000000..cc707e7
--- /dev/null
+++ b/keystore2/selinux/src/lib.rs
@@ -0,0 +1,470 @@
+// Copyright 2020, 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.
+
+//! This crate provides some safe wrappers around the libselinux API. It is currently limited
+//! to the API surface that Keystore 2.0 requires to perform permission checks against
+//! the SEPolicy. Notably, it provides wrappers for:
+//!  * getcon
+//!  * selinux_check_access
+//!  * selabel_lookup for the keystore2_key backend.
+//! And it provides an owning wrapper around context strings `Context`.
+
+use std::ffi::{CStr, CString};
+use std::fmt;
+use std::io;
+use std::marker::{Send, Sync};
+pub use std::ops::Deref;
+use std::os::raw::c_char;
+use std::ptr;
+use std::sync;
+
+use selinux_bindgen as selinux;
+
+use anyhow::Context as AnyhowContext;
+use anyhow::{anyhow, Result};
+
+use selinux::SELABEL_CTX_ANDROID_KEYSTORE2_KEY;
+use selinux::SELINUX_CB_LOG;
+
+pub use selinux::pid_t;
+
+static SELINUX_LOG_INIT: sync::Once = sync::Once::new();
+
+fn redirect_selinux_logs_to_logcat() {
+    // `selinux_set_callback` assigns the static lifetime function pointer
+    // `selinux_log_callback` to a static lifetime variable.
+    let cb = selinux::selinux_callback { func_log: Some(selinux::selinux_log_callback) };
+    unsafe {
+        selinux::selinux_set_callback(SELINUX_CB_LOG as i32, cb);
+    }
+}
+
+// This function must be called before any entry point into lib selinux.
+// Or leave a comment reasoning why calling this macro is not necessary
+// for a given entry point.
+fn init_logger_once() {
+    SELINUX_LOG_INIT.call_once(redirect_selinux_logs_to_logcat)
+}
+
+/// Selinux Error code.
+#[derive(thiserror::Error, Debug, PartialEq)]
+pub enum Error {
+    /// Indicates that an access check yielded no access.
+    #[error("Permission Denied")]
+    PermissionDenied,
+    /// Indicates an unexpected system error. Nested string provides some details.
+    #[error("Selinux SystemError: {0}")]
+    SystemError(String),
+}
+
+impl Error {
+    /// Constructs a `PermissionDenied` error.
+    pub fn perm() -> Self {
+        Error::PermissionDenied
+    }
+    fn sys<T: Into<String>>(s: T) -> Self {
+        Error::SystemError(s.into())
+    }
+}
+
+/// Context represents an SELinux context string. It can take ownership of a raw
+/// s-string as allocated by `getcon` or `selabel_lookup`. In this case it uses
+/// `freecon` to free the resources when dropped. In its second variant it stores
+/// an `std::ffi::CString` that can be initialized from a Rust string slice.
+#[derive(Debug)]
+pub enum Context {
+    /// Wraps a raw context c-string as returned by libselinux.
+    Raw(*mut ::std::os::raw::c_char),
+    /// Stores a context string as `std::ffi::CString`.
+    CString(CString),
+}
+
+impl PartialEq for Context {
+    fn eq(&self, other: &Self) -> bool {
+        // We dereference both and thereby delegate the comparison
+        // to `CStr`'s implementation of `PartialEq`.
+        **self == **other
+    }
+}
+
+impl Eq for Context {}
+
+impl fmt::Display for Context {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", (**self).to_str().unwrap_or("Invalid context"))
+    }
+}
+
+impl Drop for Context {
+    fn drop(&mut self) {
+        if let Self::Raw(p) = self {
+            // No need to initialize the logger here, because
+            // `freecon` cannot run unless `Backend::lookup` or `getcon`
+            // has run.
+            unsafe { selinux::freecon(*p) };
+        }
+    }
+}
+
+impl Deref for Context {
+    type Target = CStr;
+
+    fn deref(&self) -> &Self::Target {
+        match self {
+            Self::Raw(p) => unsafe { CStr::from_ptr(*p) },
+            Self::CString(cstr) => &cstr,
+        }
+    }
+}
+
+impl Context {
+    /// Initializes the `Context::CString` variant from a Rust string slice.
+    pub fn new(con: &str) -> Result<Self> {
+        Ok(Self::CString(
+            CString::new(con)
+                .with_context(|| format!("Failed to create Context with \"{}\"", con))?,
+        ))
+    }
+}
+
+/// The backend trait provides a uniform interface to all libselinux context backends.
+/// Currently, we only implement the KeystoreKeyBackend though.
+pub trait Backend {
+    /// Implementers use libselinux `selabel_lookup` to lookup the context for the given `key`.
+    fn lookup(&self, key: &str) -> Result<Context>;
+}
+
+/// Keystore key backend takes onwnership of the SELinux context handle returned by
+/// `selinux_android_keystore2_key_context_handle` and uses `selabel_close` to free
+/// the handle when dropped.
+/// It implements `Backend` to provide keystore_key label lookup functionality.
+pub struct KeystoreKeyBackend {
+    handle: *mut selinux::selabel_handle,
+}
+
+// KeystoreKeyBackend is Sync because selabel_lookup is thread safe.
+unsafe impl Sync for KeystoreKeyBackend {}
+unsafe impl Send for KeystoreKeyBackend {}
+
+impl KeystoreKeyBackend {
+    const BACKEND_TYPE: i32 = SELABEL_CTX_ANDROID_KEYSTORE2_KEY as i32;
+
+    /// Creates a new instance representing an SELinux context handle as returned by
+    /// `selinux_android_keystore2_key_context_handle`.
+    pub fn new() -> Result<Self> {
+        init_logger_once();
+        let handle = unsafe { selinux::selinux_android_keystore2_key_context_handle() };
+        if handle.is_null() {
+            return Err(anyhow!(Error::sys("Failed to open KeystoreKeyBackend")));
+        }
+        Ok(KeystoreKeyBackend { handle })
+    }
+}
+
+impl Drop for KeystoreKeyBackend {
+    fn drop(&mut self) {
+        // No need to initialize the logger here because it cannot be called unless
+        // KeystoreKeyBackend::new has run.
+        unsafe { selinux::selabel_close(self.handle) };
+    }
+}
+
+// Because KeystoreKeyBackend is Sync and Send, member function must never call
+// non thread safe libselinux functions. As of this writing no non thread safe
+// functions exist that could be called on a label backend handle.
+impl Backend for KeystoreKeyBackend {
+    fn lookup(&self, key: &str) -> Result<Context> {
+        let mut con: *mut c_char = ptr::null_mut();
+        let c_key = CString::new(key).with_context(|| {
+            format!("selabel_lookup: Failed to convert key \"{}\" to CString.", key)
+        })?;
+        match unsafe {
+            // No need to initialize the logger here because it cannot run unless
+            // KeystoreKeyBackend::new has run.
+            selinux::selabel_lookup(self.handle, &mut con, c_key.as_ptr(), Self::BACKEND_TYPE)
+        } {
+            0 => {
+                if !con.is_null() {
+                    Ok(Context::Raw(con))
+                } else {
+                    Err(anyhow!(Error::sys(format!(
+                        "selabel_lookup returned a NULL context for key \"{}\"",
+                        key
+                    ))))
+                }
+            }
+            _ => Err(anyhow!(io::Error::last_os_error()))
+                .with_context(|| format!("selabel_lookup failed for key \"{}\"", key)),
+        }
+    }
+}
+
+/// Safe wrapper around libselinux `getcon`. It initializes the `Context::Raw` variant of the
+/// returned `Context`.
+///
+/// ## Return
+///  * Ok(Context::Raw()) if successful.
+///  * Err(Error::sys()) if getcon succeeded but returned a NULL pointer.
+///  * Err(io::Error::last_os_error()) if getcon failed.
+pub fn getcon() -> Result<Context> {
+    init_logger_once();
+    let mut con: *mut c_char = ptr::null_mut();
+    match unsafe { selinux::getcon(&mut con) } {
+        0 => {
+            if !con.is_null() {
+                Ok(Context::Raw(con))
+            } else {
+                Err(anyhow!(Error::sys("getcon returned a NULL context")))
+            }
+        }
+        _ => Err(anyhow!(io::Error::last_os_error())).context("getcon failed"),
+    }
+}
+
+/// Safe wrapper around libselinux `getpidcon`. It initializes the `Context::Raw` variant of the
+/// returned `Context`.
+///
+/// ## Return
+///  * Ok(Context::Raw()) if successful.
+///  * Err(Error::sys()) if getpidcon succeeded but returned a NULL pointer.
+///  * Err(io::Error::last_os_error()) if getpidcon failed.
+pub fn getpidcon(pid: selinux::pid_t) -> Result<Context> {
+    init_logger_once();
+    let mut con: *mut c_char = ptr::null_mut();
+    match unsafe { selinux::getpidcon(pid, &mut con) } {
+        0 => {
+            if !con.is_null() {
+                Ok(Context::Raw(con))
+            } else {
+                Err(anyhow!(Error::sys(format!(
+                    "getpidcon returned a NULL context for pid {}",
+                    pid
+                ))))
+            }
+        }
+        _ => Err(anyhow!(io::Error::last_os_error()))
+            .context(format!("getpidcon failed for pid {}", pid)),
+    }
+}
+
+/// Safe wrapper around selinux_check_access.
+///
+/// ## Return
+///  * Ok(()) iff the requested access was granted.
+///  * Err(anyhow!(Error::perm()))) if the permission was denied.
+///  * Err(anyhow!(ioError::last_os_error())) if any other error occurred while performing
+///            the access check.
+pub fn check_access(source: &CStr, target: &CStr, tclass: &str, perm: &str) -> Result<()> {
+    init_logger_once();
+    let c_tclass = CString::new(tclass).with_context(|| {
+        format!("check_access: Failed to convert tclass \"{}\" to CString.", tclass)
+    })?;
+    let c_perm = CString::new(perm).with_context(|| {
+        format!("check_access: Failed to convert perm \"{}\" to CString.", perm)
+    })?;
+
+    match unsafe {
+        selinux::selinux_check_access(
+            source.as_ptr(),
+            target.as_ptr(),
+            c_tclass.as_ptr(),
+            c_perm.as_ptr(),
+            ptr::null_mut(),
+        )
+    } {
+        0 => Ok(()),
+        _ => {
+            let e = io::Error::last_os_error();
+            match e.kind() {
+                io::ErrorKind::PermissionDenied => Err(anyhow!(Error::perm())),
+                _ => Err(anyhow!(e)),
+            }
+            .with_context(|| {
+                format!(
+                    concat!(
+                        "check_access: Failed with sctx: {:?} tctx: {:?}",
+                        " with target class: \"{}\" perm: \"{}\""
+                    ),
+                    source, target, tclass, perm
+                )
+            })
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use anyhow::Result;
+
+    /// The su_key namespace as defined in su.te and keystore_key_contexts of the
+    /// SePolicy (system/sepolicy).
+    static SU_KEY_NAMESPACE: &str = "0";
+    /// The shell_key namespace as defined in shell.te and keystore_key_contexts of the
+    /// SePolicy (system/sepolicy).
+    static SHELL_KEY_NAMESPACE: &str = "1";
+
+    fn check_context() -> Result<(Context, &'static str, bool)> {
+        let context = getcon()?;
+        match context.to_str().unwrap() {
+            "u:r:su:s0" => Ok((context, SU_KEY_NAMESPACE, true)),
+            "u:r:shell:s0" => Ok((context, SHELL_KEY_NAMESPACE, false)),
+            c => Err(anyhow!(format!(
+                "This test must be run as \"su\" or \"shell\". Current context: \"{}\"",
+                c
+            ))),
+        }
+    }
+
+    #[test]
+    fn test_getcon() -> Result<()> {
+        check_context()?;
+        Ok(())
+    }
+
+    #[test]
+    fn test_label_lookup() -> Result<()> {
+        let (_context, namespace, is_su) = check_context()?;
+        let backend = crate::KeystoreKeyBackend::new()?;
+        let context = backend.lookup(namespace)?;
+        if is_su {
+            assert_eq!(context.to_str(), Ok("u:object_r:su_key:s0"));
+        } else {
+            assert_eq!(context.to_str(), Ok("u:object_r:shell_key:s0"));
+        }
+        Ok(())
+    }
+
+    #[test]
+    fn context_from_string() -> Result<()> {
+        let tctx = Context::new("u:object_r:keystore:s0").unwrap();
+        let sctx = Context::new("u:r:system_server:s0").unwrap();
+        check_access(&sctx, &tctx, "keystore2_key", "use")?;
+        Ok(())
+    }
+
+    mod perm {
+        use super::super::*;
+        use super::*;
+        use anyhow::Result;
+
+        /// check_key_perm(perm, privileged, priv_domain)
+        /// `perm` is a permission of the keystore2_key class and `privileged` is a boolean
+        /// indicating whether the permission is considered privileged.
+        /// Privileged permissions are expected to be denied to `shell` users but granted
+        /// to the given priv_domain.
+        macro_rules! check_key_perm {
+            // "use" is a keyword and cannot be used as an identifier, but we must keep
+            // the permission string intact. So we map the identifier name on use_ while using
+            // the permission string "use". In all other cases we can simply use the stringified
+            // identifier as permission string.
+            (use, $privileged:expr) => {
+                check_key_perm!(use_, $privileged, "use");
+            };
+            ($perm:ident, $privileged:expr) => {
+                check_key_perm!($perm, $privileged, stringify!($perm));
+            };
+            ($perm:ident, $privileged:expr, $p_str:expr) => {
+                #[test]
+                fn $perm() -> Result<()> {
+                    android_logger::init_once(
+                        android_logger::Config::default()
+                            .with_tag("keystore_selinux_tests")
+                            .with_min_level(log::Level::Debug),
+                    );
+                    let scontext = Context::new("u:r:shell:s0")?;
+                    let backend = KeystoreKeyBackend::new()?;
+                    let tcontext = backend.lookup(SHELL_KEY_NAMESPACE)?;
+
+                    if $privileged {
+                        assert_eq!(
+                            Some(&Error::perm()),
+                            check_access(
+                                &scontext,
+                                &tcontext,
+                                "keystore2_key",
+                                $p_str
+                            )
+                            .err()
+                            .unwrap()
+                            .root_cause()
+                            .downcast_ref::<Error>()
+                        );
+                    } else {
+                        assert!(check_access(
+                            &scontext,
+                            &tcontext,
+                            "keystore2_key",
+                            $p_str
+                        )
+                        .is_ok());
+                    }
+                    Ok(())
+                }
+            };
+        }
+
+        check_key_perm!(manage_blob, true);
+        check_key_perm!(delete, false);
+        check_key_perm!(use_dev_id, true);
+        check_key_perm!(req_forced_op, true);
+        check_key_perm!(gen_unique_id, true);
+        check_key_perm!(grant, true);
+        check_key_perm!(get_info, false);
+        check_key_perm!(rebind, false);
+        check_key_perm!(update, false);
+        check_key_perm!(use, false);
+
+        macro_rules! check_keystore_perm {
+            ($perm:ident) => {
+                #[test]
+                fn $perm() -> Result<()> {
+                    let ks_context = Context::new("u:object_r:keystore:s0")?;
+                    let priv_context = Context::new("u:r:system_server:s0")?;
+                    let unpriv_context = Context::new("u:r:shell:s0")?;
+                    assert!(check_access(
+                        &priv_context,
+                        &ks_context,
+                        "keystore2",
+                        stringify!($perm)
+                    )
+                    .is_ok());
+                    assert_eq!(
+                        Some(&Error::perm()),
+                        check_access(&unpriv_context, &ks_context, "keystore2", stringify!($perm))
+                            .err()
+                            .unwrap()
+                            .root_cause()
+                            .downcast_ref::<Error>()
+                    );
+                    Ok(())
+                }
+            };
+        }
+
+        check_keystore_perm!(add_auth);
+        check_keystore_perm!(clear_ns);
+        check_keystore_perm!(lock);
+        check_keystore_perm!(reset);
+        check_keystore_perm!(unlock);
+    }
+
+    #[test]
+    fn test_getpidcon() {
+        // Check that `getpidcon` of our pid is equal to what `getcon` returns.
+        // And by using `unwrap` we make sure that both also have to return successfully
+        // fully to pass the test.
+        assert_eq!(getpidcon(std::process::id() as i32).unwrap(), getcon().unwrap());
+    }
+}
diff --git a/keystore2/src/apc.rs b/keystore2/src/apc.rs
new file mode 100644
index 0000000..0096686
--- /dev/null
+++ b/keystore2/src/apc.rs
@@ -0,0 +1,384 @@
+// Copyright 2020, 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.
+
+//! This module implements the Android Protected Confirmation (APC) service as defined
+//! in the android.security.apc AIDL spec.
+
+use std::{
+    cmp::PartialEq,
+    collections::HashMap,
+    sync::{mpsc::Sender, Arc, Mutex},
+};
+
+use crate::utils::{compat_2_response_code, ui_opts_2_compat, watchdog as wd};
+use android_security_apc::aidl::android::security::apc::{
+    IConfirmationCallback::IConfirmationCallback,
+    IProtectedConfirmation::{BnProtectedConfirmation, IProtectedConfirmation},
+    ResponseCode::ResponseCode,
+};
+use android_security_apc::binder::{
+    BinderFeatures, ExceptionCode, Interface, Result as BinderResult, SpIBinder,
+    Status as BinderStatus, Strong, ThreadState,
+};
+use anyhow::{Context, Result};
+use keystore2_apc_compat::ApcHal;
+use keystore2_selinux as selinux;
+use std::time::{Duration, Instant};
+
+/// This is the main APC error type, it wraps binder exceptions and the
+/// APC ResponseCode.
+#[derive(Debug, thiserror::Error, PartialEq)]
+pub enum Error {
+    /// Wraps an Android Protected Confirmation (APC) response code as defined by the
+    /// android.security.apc AIDL interface specification.
+    #[error("Error::Rc({0:?})")]
+    Rc(ResponseCode),
+    /// Wraps a Binder exception code other than a service specific exception.
+    #[error("Binder exception code {0:?}, {1:?}")]
+    Binder(ExceptionCode, i32),
+}
+
+impl Error {
+    /// Short hand for `Error::Rc(ResponseCode::SYSTEM_ERROR)`
+    pub fn sys() -> Self {
+        Error::Rc(ResponseCode::SYSTEM_ERROR)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::OPERATION_PENDING)`
+    pub fn pending() -> Self {
+        Error::Rc(ResponseCode::OPERATION_PENDING)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::CANCELLED)`
+    pub fn cancelled() -> Self {
+        Error::Rc(ResponseCode::CANCELLED)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::ABORTED)`
+    pub fn aborted() -> Self {
+        Error::Rc(ResponseCode::ABORTED)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::IGNORED)`
+    pub fn ignored() -> Self {
+        Error::Rc(ResponseCode::IGNORED)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::UNIMPLEMENTED)`
+    pub fn unimplemented() -> Self {
+        Error::Rc(ResponseCode::UNIMPLEMENTED)
+    }
+}
+
+/// This function should be used by confirmation service calls to translate error conditions
+/// into service specific exceptions.
+///
+/// All error conditions get logged by this function.
+///
+/// `Error::Rc(x)` variants get mapped onto a service specific error code of `x`.
+/// `selinux::Error::perm()` is mapped on `ResponseCode::PERMISSION_DENIED`.
+///
+/// All non `Error` error conditions get mapped onto ResponseCode::SYSTEM_ERROR`.
+///
+/// `handle_ok` will be called if `result` is `Ok(value)` where `value` will be passed
+/// as argument to `handle_ok`. `handle_ok` must generate a `BinderResult<T>`, but it
+/// typically returns Ok(value).
+pub fn map_or_log_err<T, U, F>(result: Result<U>, handle_ok: F) -> BinderResult<T>
+where
+    F: FnOnce(U) -> BinderResult<T>,
+{
+    result.map_or_else(
+        |e| {
+            log::error!("{:#?}", e);
+            let root_cause = e.root_cause();
+            let rc = match root_cause.downcast_ref::<Error>() {
+                Some(Error::Rc(rcode)) => rcode.0,
+                Some(Error::Binder(_, _)) => ResponseCode::SYSTEM_ERROR.0,
+                None => match root_cause.downcast_ref::<selinux::Error>() {
+                    Some(selinux::Error::PermissionDenied) => ResponseCode::PERMISSION_DENIED.0,
+                    _ => ResponseCode::SYSTEM_ERROR.0,
+                },
+            };
+            Err(BinderStatus::new_service_specific_error(rc, None))
+        },
+        handle_ok,
+    )
+}
+
+/// Rate info records how many failed attempts a client has made to display a protected
+/// confirmation prompt. Clients are penalized for attempts that get declined by the user
+/// or attempts that get aborted by the client itself.
+///
+/// After the third failed attempt the client has to cool down for 30 seconds before it
+/// it can retry. After the sixth failed attempt, the time doubles with every failed attempt
+/// until it goes into saturation at 24h.
+///
+/// A successful user prompt resets the counter.
+#[derive(Debug, Clone)]
+struct RateInfo {
+    counter: u32,
+    timestamp: Instant,
+}
+
+impl RateInfo {
+    const ONE_DAY: Duration = Duration::from_secs(60u64 * 60u64 * 24u64);
+
+    fn get_remaining_back_off(&self) -> Option<Duration> {
+        let back_off = match self.counter {
+            // The first three attempts come without penalty.
+            0..=2 => return None,
+            // The next three attempts are are penalized with 30 seconds back off time.
+            3..=5 => Duration::from_secs(30),
+            // After that we double the back off time the with every additional attempt
+            // until we reach 1024m (~17h).
+            6..=16 => Duration::from_secs(60)
+                .checked_mul(1u32 << (self.counter - 6))
+                .unwrap_or(Self::ONE_DAY),
+            // After that we cap of at 24h between attempts.
+            _ => Self::ONE_DAY,
+        };
+        let elapsed = self.timestamp.elapsed();
+        // This does exactly what we want.
+        // `back_off - elapsed` is the remaining back off duration or None if elapsed is larger
+        // than back_off. Also, this operation cannot overflow as long as elapsed is less than
+        // back_off, which is all that we care about.
+        back_off.checked_sub(elapsed)
+    }
+}
+
+impl Default for RateInfo {
+    fn default() -> Self {
+        Self { counter: 0u32, timestamp: Instant::now() }
+    }
+}
+
+/// The APC session state represents the state of an APC session.
+struct ApcSessionState {
+    /// A reference to the APC HAL backend.
+    hal: Arc<ApcHal>,
+    /// The client callback object.
+    cb: SpIBinder,
+    /// The uid of the owner of this APC session.
+    uid: u32,
+    /// The time when this session was started.
+    start: Instant,
+    /// This is set when the client calls abort.
+    /// This is used by the rate limiting logic to determine
+    /// if the client needs to be penalized for this attempt.
+    client_aborted: bool,
+}
+
+struct ApcState {
+    session: Option<ApcSessionState>,
+    rate_limiting: HashMap<u32, RateInfo>,
+    confirmation_token_sender: Sender<Vec<u8>>,
+}
+
+impl ApcState {
+    fn new(confirmation_token_sender: Sender<Vec<u8>>) -> Self {
+        Self { session: None, rate_limiting: Default::default(), confirmation_token_sender }
+    }
+}
+
+/// Implementation of the APC service.
+pub struct ApcManager {
+    state: Arc<Mutex<ApcState>>,
+}
+
+impl Interface for ApcManager {}
+
+impl ApcManager {
+    /// Create a new instance of the Android Protected Confirmation service.
+    pub fn new_native_binder(
+        confirmation_token_sender: Sender<Vec<u8>>,
+    ) -> Result<Strong<dyn IProtectedConfirmation>> {
+        Ok(BnProtectedConfirmation::new_binder(
+            Self { state: Arc::new(Mutex::new(ApcState::new(confirmation_token_sender))) },
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        ))
+    }
+
+    fn result(
+        state: Arc<Mutex<ApcState>>,
+        rc: u32,
+        data_confirmed: Option<&[u8]>,
+        confirmation_token: Option<&[u8]>,
+    ) {
+        let mut state = state.lock().unwrap();
+        let (callback, uid, start, client_aborted) = match state.session.take() {
+            None => return, // Nothing to do
+            Some(ApcSessionState { cb: callback, uid, start, client_aborted, .. }) => {
+                (callback, uid, start, client_aborted)
+            }
+        };
+
+        let rc = compat_2_response_code(rc);
+
+        // Update rate limiting information.
+        match (rc, client_aborted, confirmation_token) {
+            // If the user confirmed the dialog.
+            (ResponseCode::OK, _, Some(confirmation_token)) => {
+                // Reset counter.
+                state.rate_limiting.remove(&uid);
+                // Send confirmation token to the enforcement module.
+                if let Err(e) = state.confirmation_token_sender.send(confirmation_token.to_vec()) {
+                    log::error!("Got confirmation token, but receiver would not have it. {:?}", e);
+                }
+            }
+            // If cancelled by the user or if aborted by the client.
+            (ResponseCode::CANCELLED, _, _) | (ResponseCode::ABORTED, true, _) => {
+                // Penalize.
+                let mut rate_info = state.rate_limiting.entry(uid).or_default();
+                rate_info.counter += 1;
+                rate_info.timestamp = start;
+            }
+            (ResponseCode::OK, _, None) => {
+                log::error!(
+                    "Confirmation prompt was successful but no confirmation token was returned."
+                );
+            }
+            // In any other case this try does not count at all.
+            _ => {}
+        }
+        drop(state);
+
+        if let Ok(listener) = callback.into_interface::<dyn IConfirmationCallback>() {
+            if let Err(e) = listener.onCompleted(rc, data_confirmed) {
+                log::error!(
+                    "In ApcManagerCallback::result: Reporting completion to client failed {:?}",
+                    e
+                )
+            }
+        } else {
+            log::error!("In ApcManagerCallback::result: SpIBinder is not a IConfirmationCallback.");
+        }
+    }
+
+    fn present_prompt(
+        &self,
+        listener: &binder::Strong<dyn IConfirmationCallback>,
+        prompt_text: &str,
+        extra_data: &[u8],
+        locale: &str,
+        ui_option_flags: i32,
+    ) -> Result<()> {
+        let mut state = self.state.lock().unwrap();
+        if state.session.is_some() {
+            return Err(Error::pending())
+                .context("In ApcManager::present_prompt: Session pending.");
+        }
+
+        // Perform rate limiting.
+        let uid = ThreadState::get_calling_uid();
+        match state.rate_limiting.get(&uid) {
+            None => {}
+            Some(rate_info) => {
+                if let Some(back_off) = rate_info.get_remaining_back_off() {
+                    return Err(Error::sys()).context(format!(
+                        "In ApcManager::present_prompt: Cooling down. Remaining back-off: {}s",
+                        back_off.as_secs()
+                    ));
+                }
+            }
+        }
+
+        let hal = ApcHal::try_get_service();
+        let hal = match hal {
+            None => {
+                return Err(Error::unimplemented())
+                    .context("In ApcManager::present_prompt: APC not supported.")
+            }
+            Some(h) => Arc::new(h),
+        };
+
+        let ui_opts = ui_opts_2_compat(ui_option_flags);
+
+        let state_clone = self.state.clone();
+        hal.prompt_user_confirmation(
+            prompt_text,
+            extra_data,
+            locale,
+            ui_opts,
+            move |rc, data_confirmed, confirmation_token| {
+                Self::result(state_clone, rc, data_confirmed, confirmation_token)
+            },
+        )
+        .map_err(|rc| Error::Rc(compat_2_response_code(rc)))
+        .context("In present_prompt: Failed to present prompt.")?;
+        state.session = Some(ApcSessionState {
+            hal,
+            cb: listener.as_binder(),
+            uid,
+            start: Instant::now(),
+            client_aborted: false,
+        });
+        Ok(())
+    }
+
+    fn cancel_prompt(&self, listener: &binder::Strong<dyn IConfirmationCallback>) -> Result<()> {
+        let mut state = self.state.lock().unwrap();
+        let hal = match &mut state.session {
+            None => {
+                return Err(Error::ignored())
+                    .context("In cancel_prompt: Attempt to cancel non existing session. Ignoring.")
+            }
+            Some(session) => {
+                if session.cb != listener.as_binder() {
+                    return Err(Error::ignored()).context(concat!(
+                        "In cancel_prompt: Attempt to cancel session not belonging to caller. ",
+                        "Ignoring."
+                    ));
+                }
+                session.client_aborted = true;
+                session.hal.clone()
+            }
+        };
+        drop(state);
+        hal.abort();
+        Ok(())
+    }
+
+    fn is_supported() -> Result<bool> {
+        Ok(ApcHal::try_get_service().is_some())
+    }
+}
+
+impl IProtectedConfirmation for ApcManager {
+    fn presentPrompt(
+        &self,
+        listener: &binder::Strong<dyn IConfirmationCallback>,
+        prompt_text: &str,
+        extra_data: &[u8],
+        locale: &str,
+        ui_option_flags: i32,
+    ) -> BinderResult<()> {
+        // presentPrompt can take more time than other operations.
+        let _wp = wd::watch_millis("IProtectedConfirmation::presentPrompt", 3000);
+        map_or_log_err(
+            self.present_prompt(listener, prompt_text, extra_data, locale, ui_option_flags),
+            Ok,
+        )
+    }
+    fn cancelPrompt(
+        &self,
+        listener: &binder::Strong<dyn IConfirmationCallback>,
+    ) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IProtectedConfirmation::cancelPrompt", 500);
+        map_or_log_err(self.cancel_prompt(listener), Ok)
+    }
+    fn isSupported(&self) -> BinderResult<bool> {
+        let _wp = wd::watch_millis("IProtectedConfirmation::isSupported", 500);
+        map_or_log_err(Self::is_supported(), Ok)
+    }
+}
diff --git a/keystore2/src/async_task.rs b/keystore2/src/async_task.rs
new file mode 100644
index 0000000..4d0034a
--- /dev/null
+++ b/keystore2/src/async_task.rs
@@ -0,0 +1,531 @@
+// Copyright 2020, 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.
+
+//! This module implements the handling of async tasks.
+//! The worker thread has a high priority and a low priority queue. Adding a job to either
+//! will cause one thread to be spawned if none exists. As a compromise between performance
+//! and resource consumption, the thread will linger for about 30 seconds after it has
+//! processed all tasks before it terminates.
+//! Note that low priority tasks are processed only when the high priority queue is empty.
+
+use std::{any::Any, any::TypeId, time::Duration};
+use std::{
+    collections::{HashMap, VecDeque},
+    sync::Arc,
+    sync::{Condvar, Mutex, MutexGuard},
+    thread,
+};
+
+#[derive(Debug, PartialEq, Eq)]
+enum State {
+    Exiting,
+    Running,
+}
+
+/// The Shelf allows async tasks to store state across invocations.
+/// Note: Store elves at your own peril ;-).
+#[derive(Debug, Default)]
+pub struct Shelf(HashMap<TypeId, Box<dyn Any + Send>>);
+
+impl Shelf {
+    /// Get a reference to the shelved data of type T. Returns Some if the data exists.
+    pub fn get_downcast_ref<T: Any + Send>(&self) -> Option<&T> {
+        self.0.get(&TypeId::of::<T>()).and_then(|v| v.downcast_ref::<T>())
+    }
+
+    /// Get a mutable reference to the shelved data of type T. If a T was inserted using put,
+    /// get_mut, or get_or_put_with.
+    pub fn get_downcast_mut<T: Any + Send>(&mut self) -> Option<&mut T> {
+        self.0.get_mut(&TypeId::of::<T>()).and_then(|v| v.downcast_mut::<T>())
+    }
+
+    /// Remove the entry of the given type and returns the stored data if it existed.
+    pub fn remove_downcast_ref<T: Any + Send>(&mut self) -> Option<T> {
+        self.0.remove(&TypeId::of::<T>()).and_then(|v| v.downcast::<T>().ok().map(|b| *b))
+    }
+
+    /// Puts data `v` on the shelf. If there already was an entry of type T it is returned.
+    pub fn put<T: Any + Send>(&mut self, v: T) -> Option<T> {
+        self.0
+            .insert(TypeId::of::<T>(), Box::new(v) as Box<dyn Any + Send>)
+            .and_then(|v| v.downcast::<T>().ok().map(|b| *b))
+    }
+
+    /// Gets a mutable reference to the entry of the given type and default creates it if necessary.
+    /// The type must implement Default.
+    pub fn get_mut<T: Any + Send + Default>(&mut self) -> &mut T {
+        self.0
+            .entry(TypeId::of::<T>())
+            .or_insert_with(|| Box::new(T::default()) as Box<dyn Any + Send>)
+            .downcast_mut::<T>()
+            .unwrap()
+    }
+
+    /// Gets a mutable reference to the entry of the given type or creates it using the init
+    /// function. Init is not executed if the entry already existed.
+    pub fn get_or_put_with<T: Any + Send, F>(&mut self, init: F) -> &mut T
+    where
+        F: FnOnce() -> T,
+    {
+        self.0
+            .entry(TypeId::of::<T>())
+            .or_insert_with(|| Box::new(init()) as Box<dyn Any + Send>)
+            .downcast_mut::<T>()
+            .unwrap()
+    }
+}
+
+struct AsyncTaskState {
+    state: State,
+    thread: Option<thread::JoinHandle<()>>,
+    timeout: Duration,
+    hi_prio_req: VecDeque<Box<dyn FnOnce(&mut Shelf) + Send>>,
+    lo_prio_req: VecDeque<Box<dyn FnOnce(&mut Shelf) + Send>>,
+    idle_fns: Vec<Arc<dyn Fn(&mut Shelf) + Send + Sync>>,
+    /// The store allows tasks to store state across invocations. It is passed to each invocation
+    /// of each task. Tasks need to cooperate on the ids they use for storing state.
+    shelf: Option<Shelf>,
+}
+
+/// AsyncTask spawns one worker thread on demand to process jobs inserted into
+/// a low and a high priority work queue. The queues are processed FIFO, and low
+/// priority queue is processed if the high priority queue is empty.
+/// Note: Because there is only one worker thread at a time for a given AsyncTask instance,
+/// all scheduled requests are guaranteed to be serialized with respect to one another.
+pub struct AsyncTask {
+    state: Arc<(Condvar, Mutex<AsyncTaskState>)>,
+}
+
+impl Default for AsyncTask {
+    fn default() -> Self {
+        Self::new(Duration::from_secs(30))
+    }
+}
+
+impl AsyncTask {
+    /// Construct an [`AsyncTask`] with a specific timeout value.
+    pub fn new(timeout: Duration) -> Self {
+        Self {
+            state: Arc::new((
+                Condvar::new(),
+                Mutex::new(AsyncTaskState {
+                    state: State::Exiting,
+                    thread: None,
+                    timeout,
+                    hi_prio_req: VecDeque::new(),
+                    lo_prio_req: VecDeque::new(),
+                    idle_fns: Vec::new(),
+                    shelf: None,
+                }),
+            )),
+        }
+    }
+
+    /// Adds a one-off job to the high priority queue. High priority jobs are
+    /// completed before low priority jobs and can also overtake low priority
+    /// jobs. But they cannot preempt them.
+    pub fn queue_hi<F>(&self, f: F)
+    where
+        F: for<'r> FnOnce(&'r mut Shelf) + Send + 'static,
+    {
+        self.queue(f, true)
+    }
+
+    /// Adds a one-off job to the low priority queue. Low priority jobs are
+    /// completed after high priority. And they are not executed as long as high
+    /// priority jobs are present. Jobs always run to completion and are never
+    /// preempted by high priority jobs.
+    pub fn queue_lo<F>(&self, f: F)
+    where
+        F: FnOnce(&mut Shelf) + Send + 'static,
+    {
+        self.queue(f, false)
+    }
+
+    /// Adds an idle callback. This will be invoked whenever the worker becomes
+    /// idle (all high and low priority jobs have been performed).
+    pub fn add_idle<F>(&self, f: F)
+    where
+        F: Fn(&mut Shelf) + Send + Sync + 'static,
+    {
+        let (ref _condvar, ref state) = *self.state;
+        let mut state = state.lock().unwrap();
+        state.idle_fns.push(Arc::new(f));
+    }
+
+    fn queue<F>(&self, f: F, hi_prio: bool)
+    where
+        F: for<'r> FnOnce(&'r mut Shelf) + Send + 'static,
+    {
+        let (ref condvar, ref state) = *self.state;
+        let mut state = state.lock().unwrap();
+        if hi_prio {
+            state.hi_prio_req.push_back(Box::new(f));
+        } else {
+            state.lo_prio_req.push_back(Box::new(f));
+        }
+
+        if state.state != State::Running {
+            self.spawn_thread(&mut state);
+        }
+        drop(state);
+        condvar.notify_all();
+    }
+
+    fn spawn_thread(&self, state: &mut MutexGuard<AsyncTaskState>) {
+        if let Some(t) = state.thread.take() {
+            t.join().expect("AsyncTask panicked.");
+        }
+
+        let cloned_state = self.state.clone();
+        let timeout_period = state.timeout;
+
+        state.thread = Some(thread::spawn(move || {
+            let (ref condvar, ref state) = *cloned_state;
+
+            enum Action {
+                QueuedFn(Box<dyn FnOnce(&mut Shelf) + Send>),
+                IdleFns(Vec<Arc<dyn Fn(&mut Shelf) + Send + Sync>>),
+            }
+            let mut done_idle = false;
+
+            // When the worker starts, it takes the shelf and puts it on the stack.
+            let mut shelf = state.lock().unwrap().shelf.take().unwrap_or_default();
+            loop {
+                if let Some(action) = {
+                    let state = state.lock().unwrap();
+                    if !done_idle && state.hi_prio_req.is_empty() && state.lo_prio_req.is_empty() {
+                        // No jobs queued so invoke the idle callbacks.
+                        Some(Action::IdleFns(state.idle_fns.clone()))
+                    } else {
+                        // Wait for either a queued job to arrive or a timeout.
+                        let (mut state, timeout) = condvar
+                            .wait_timeout_while(state, timeout_period, |state| {
+                                state.hi_prio_req.is_empty() && state.lo_prio_req.is_empty()
+                            })
+                            .unwrap();
+                        match (
+                            state.hi_prio_req.pop_front(),
+                            state.lo_prio_req.is_empty(),
+                            timeout.timed_out(),
+                        ) {
+                            (Some(f), _, _) => Some(Action::QueuedFn(f)),
+                            (None, false, _) => {
+                                state.lo_prio_req.pop_front().map(|f| Action::QueuedFn(f))
+                            }
+                            (None, true, true) => {
+                                // When the worker exits it puts the shelf back into the shared
+                                // state for the next worker to use. So state is preserved not
+                                // only across invocations but also across worker thread shut down.
+                                state.shelf = Some(shelf);
+                                state.state = State::Exiting;
+                                break;
+                            }
+                            (None, true, false) => None,
+                        }
+                    }
+                } {
+                    // Now that the lock has been dropped, perform the action.
+                    match action {
+                        Action::QueuedFn(f) => {
+                            f(&mut shelf);
+                            done_idle = false;
+                        }
+                        Action::IdleFns(idle_fns) => {
+                            for idle_fn in idle_fns {
+                                idle_fn(&mut shelf);
+                            }
+                            done_idle = true;
+                        }
+                    }
+                }
+            }
+        }));
+        state.state = State::Running;
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{AsyncTask, Shelf};
+    use std::sync::{
+        mpsc::{channel, sync_channel, RecvTimeoutError},
+        Arc,
+    };
+    use std::time::Duration;
+
+    #[test]
+    fn test_shelf() {
+        let mut shelf = Shelf::default();
+
+        let s = "A string".to_string();
+        assert_eq!(shelf.put(s), None);
+
+        let s2 = "Another string".to_string();
+        assert_eq!(shelf.put(s2), Some("A string".to_string()));
+
+        // Put something of a different type on the shelf.
+        #[derive(Debug, PartialEq, Eq)]
+        struct Elf {
+            pub name: String,
+        }
+        let e1 = Elf { name: "Glorfindel".to_string() };
+        assert_eq!(shelf.put(e1), None);
+
+        // The String value is still on the shelf.
+        let s3 = shelf.get_downcast_ref::<String>().unwrap();
+        assert_eq!(s3, "Another string");
+
+        // As is the Elf.
+        {
+            let e2 = shelf.get_downcast_mut::<Elf>().unwrap();
+            assert_eq!(e2.name, "Glorfindel");
+            e2.name = "Celeborn".to_string();
+        }
+
+        // Take the Elf off the shelf.
+        let e3 = shelf.remove_downcast_ref::<Elf>().unwrap();
+        assert_eq!(e3.name, "Celeborn");
+
+        assert_eq!(shelf.remove_downcast_ref::<Elf>(), None);
+
+        // No u64 value has been put on the shelf, so getting one gives the default value.
+        {
+            let i = shelf.get_mut::<u64>();
+            assert_eq!(*i, 0);
+            *i = 42;
+        }
+        let i2 = shelf.get_downcast_ref::<u64>().unwrap();
+        assert_eq!(*i2, 42);
+
+        // No i32 value has ever been seen near the shelf.
+        assert_eq!(shelf.get_downcast_ref::<i32>(), None);
+        assert_eq!(shelf.get_downcast_mut::<i32>(), None);
+        assert_eq!(shelf.remove_downcast_ref::<i32>(), None);
+    }
+
+    #[test]
+    fn test_async_task() {
+        let at = AsyncTask::default();
+
+        // First queue up a job that blocks until we release it, to avoid
+        // unpredictable synchronization.
+        let (start_sender, start_receiver) = channel();
+        at.queue_hi(move |shelf| {
+            start_receiver.recv().unwrap();
+            // Put a trace vector on the shelf
+            shelf.put(Vec::<String>::new());
+        });
+
+        // Queue up some high-priority and low-priority jobs.
+        for i in 0..3 {
+            let j = i;
+            at.queue_lo(move |shelf| {
+                let trace = shelf.get_mut::<Vec<String>>();
+                trace.push(format!("L{}", j));
+            });
+            let j = i;
+            at.queue_hi(move |shelf| {
+                let trace = shelf.get_mut::<Vec<String>>();
+                trace.push(format!("H{}", j));
+            });
+        }
+
+        // Finally queue up a low priority job that emits the trace.
+        let (trace_sender, trace_receiver) = channel();
+        at.queue_lo(move |shelf| {
+            let trace = shelf.get_downcast_ref::<Vec<String>>().unwrap();
+            trace_sender.send(trace.clone()).unwrap();
+        });
+
+        // Ready, set, go.
+        start_sender.send(()).unwrap();
+        let trace = trace_receiver.recv().unwrap();
+
+        assert_eq!(trace, vec!["H0", "H1", "H2", "L0", "L1", "L2"]);
+    }
+
+    #[test]
+    fn test_async_task_chain() {
+        let at = Arc::new(AsyncTask::default());
+        let (sender, receiver) = channel();
+        // Queue up a job that will queue up another job. This confirms
+        // that the job is not invoked with any internal AsyncTask locks held.
+        let at_clone = at.clone();
+        at.queue_hi(move |_shelf| {
+            at_clone.queue_lo(move |_shelf| {
+                sender.send(()).unwrap();
+            });
+        });
+        receiver.recv().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_async_task_panic() {
+        let at = AsyncTask::default();
+        at.queue_hi(|_shelf| {
+            panic!("Panic from queued job");
+        });
+        // Queue another job afterwards to ensure that the async thread gets joined.
+        let (done_sender, done_receiver) = channel();
+        at.queue_hi(move |_shelf| {
+            done_sender.send(()).unwrap();
+        });
+        done_receiver.recv().unwrap();
+    }
+
+    #[test]
+    fn test_async_task_idle() {
+        let at = AsyncTask::new(Duration::from_secs(3));
+        // Need a SyncSender as it is Send+Sync.
+        let (idle_done_sender, idle_done_receiver) = sync_channel::<()>(3);
+        at.add_idle(move |_shelf| {
+            idle_done_sender.send(()).unwrap();
+        });
+
+        // Queue up some high-priority and low-priority jobs that take time.
+        for _i in 0..3 {
+            at.queue_lo(|_shelf| {
+                std::thread::sleep(Duration::from_millis(500));
+            });
+            at.queue_hi(|_shelf| {
+                std::thread::sleep(Duration::from_millis(500));
+            });
+        }
+        // Final low-priority job.
+        let (done_sender, done_receiver) = channel();
+        at.queue_lo(move |_shelf| {
+            done_sender.send(()).unwrap();
+        });
+
+        // Nothing happens until the last job completes.
+        assert_eq!(
+            idle_done_receiver.recv_timeout(Duration::from_secs(1)),
+            Err(RecvTimeoutError::Timeout)
+        );
+        done_receiver.recv().unwrap();
+        idle_done_receiver.recv_timeout(Duration::from_millis(1)).unwrap();
+
+        // Idle callback not executed again even if we wait for a while.
+        assert_eq!(
+            idle_done_receiver.recv_timeout(Duration::from_secs(3)),
+            Err(RecvTimeoutError::Timeout)
+        );
+
+        // However, if more work is done then there's another chance to go idle.
+        let (done_sender, done_receiver) = channel();
+        at.queue_hi(move |_shelf| {
+            std::thread::sleep(Duration::from_millis(500));
+            done_sender.send(()).unwrap();
+        });
+        // Idle callback not immediately executed, because the high priority
+        // job is taking a while.
+        assert_eq!(
+            idle_done_receiver.recv_timeout(Duration::from_millis(1)),
+            Err(RecvTimeoutError::Timeout)
+        );
+        done_receiver.recv().unwrap();
+        idle_done_receiver.recv_timeout(Duration::from_millis(1)).unwrap();
+    }
+
+    #[test]
+    fn test_async_task_multiple_idle() {
+        let at = AsyncTask::new(Duration::from_secs(3));
+        let (idle_sender, idle_receiver) = sync_channel::<i32>(5);
+        // Queue a high priority job to start things off
+        at.queue_hi(|_shelf| {
+            std::thread::sleep(Duration::from_millis(500));
+        });
+
+        // Multiple idle callbacks.
+        for i in 0..3 {
+            let idle_sender = idle_sender.clone();
+            at.add_idle(move |_shelf| {
+                idle_sender.send(i).unwrap();
+            });
+        }
+
+        // Nothing happens immediately.
+        assert_eq!(
+            idle_receiver.recv_timeout(Duration::from_millis(1)),
+            Err(RecvTimeoutError::Timeout)
+        );
+        // Wait for a moment and the idle jobs should have run.
+        std::thread::sleep(Duration::from_secs(1));
+
+        let mut results = Vec::new();
+        while let Ok(i) = idle_receiver.recv_timeout(Duration::from_millis(1)) {
+            results.push(i);
+        }
+        assert_eq!(results, [0, 1, 2]);
+    }
+
+    #[test]
+    fn test_async_task_idle_queues_job() {
+        let at = Arc::new(AsyncTask::new(Duration::from_secs(1)));
+        let at_clone = at.clone();
+        let (idle_sender, idle_receiver) = sync_channel::<i32>(100);
+        // Add an idle callback that queues a low-priority job.
+        at.add_idle(move |shelf| {
+            at_clone.queue_lo(|_shelf| {
+                // Slow things down so the channel doesn't fill up.
+                std::thread::sleep(Duration::from_millis(50));
+            });
+            let i = shelf.get_mut::<i32>();
+            idle_sender.send(*i).unwrap();
+            *i += 1;
+        });
+
+        // Nothing happens immediately.
+        assert_eq!(
+            idle_receiver.recv_timeout(Duration::from_millis(1500)),
+            Err(RecvTimeoutError::Timeout)
+        );
+
+        // Once we queue a normal job, things start.
+        at.queue_hi(|_shelf| {});
+        assert_eq!(0, idle_receiver.recv_timeout(Duration::from_millis(200)).unwrap());
+
+        // The idle callback queues a job, and completion of that job
+        // means the task is going idle again...so the idle callback will
+        // be called repeatedly.
+        assert_eq!(1, idle_receiver.recv_timeout(Duration::from_millis(100)).unwrap());
+        assert_eq!(2, idle_receiver.recv_timeout(Duration::from_millis(100)).unwrap());
+        assert_eq!(3, idle_receiver.recv_timeout(Duration::from_millis(100)).unwrap());
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_async_task_idle_panic() {
+        let at = AsyncTask::new(Duration::from_secs(1));
+        let (idle_sender, idle_receiver) = sync_channel::<()>(3);
+        // Add an idle callback that panics.
+        at.add_idle(move |_shelf| {
+            idle_sender.send(()).unwrap();
+            panic!("Panic from idle callback");
+        });
+        // Queue a job to trigger idleness and ensuing panic.
+        at.queue_hi(|_shelf| {});
+        idle_receiver.recv().unwrap();
+
+        // Queue another job afterwards to ensure that the async thread gets joined
+        // and the panic detected.
+        let (done_sender, done_receiver) = channel();
+        at.queue_hi(move |_shelf| {
+            done_sender.send(()).unwrap();
+        });
+        done_receiver.recv().unwrap();
+    }
+}
diff --git a/keystore2/src/attestation_key_utils.rs b/keystore2/src/attestation_key_utils.rs
new file mode 100644
index 0000000..425eec6
--- /dev/null
+++ b/keystore2/src/attestation_key_utils.rs
@@ -0,0 +1,126 @@
+// Copyright 2021, 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.
+
+//! Implements get_attestation_key_info which loads remote provisioned or user
+//! generated attestation keys.
+
+use crate::database::{BlobMetaData, KeyEntryLoadBits, KeyType};
+use crate::database::{KeyIdGuard, KeystoreDB};
+use crate::error::{Error, ErrorCode};
+use crate::permission::KeyPerm;
+use crate::remote_provisioning::RemProvState;
+use crate::utils::check_key_permission;
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    AttestationKey::AttestationKey, Certificate::Certificate, KeyParameter::KeyParameter,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor,
+};
+use anyhow::{Context, Result};
+use keystore2_crypto::parse_subject_from_certificate;
+
+/// KeyMint takes two different kinds of attestation keys. Remote provisioned keys
+/// and those that have been generated by the user. Unfortunately, they need to be
+/// handled quite differently, thus the different representations.
+pub enum AttestationKeyInfo {
+    RemoteProvisioned {
+        attestation_key: AttestationKey,
+        attestation_certs: Certificate,
+    },
+    UserGenerated {
+        key_id_guard: KeyIdGuard,
+        blob: Vec<u8>,
+        blob_metadata: BlobMetaData,
+        issuer_subject: Vec<u8>,
+    },
+}
+
+/// This function loads and, optionally, assigns the caller's remote provisioned
+/// attestation key or, if `attest_key_descriptor` is given, it loads the user
+/// generated attestation key from the database.
+pub fn get_attest_key_info(
+    key: &KeyDescriptor,
+    caller_uid: u32,
+    attest_key_descriptor: Option<&KeyDescriptor>,
+    params: &[KeyParameter],
+    rem_prov_state: &RemProvState,
+    db: &mut KeystoreDB,
+) -> Result<Option<AttestationKeyInfo>> {
+    match attest_key_descriptor {
+        None => rem_prov_state
+            .get_remotely_provisioned_attestation_key_and_certs(&key, caller_uid, params, db)
+            .context(concat!(
+                "In get_attest_key_and_cert_chain: ",
+                "Trying to get remotely provisioned attestation key."
+            ))
+            .map(|result| {
+                result.map(|(attestation_key, attestation_certs)| {
+                    AttestationKeyInfo::RemoteProvisioned { attestation_key, attestation_certs }
+                })
+            }),
+        Some(attest_key) => get_user_generated_attestation_key(&attest_key, caller_uid, db)
+            .context("In get_attest_key_and_cert_chain: Trying to load attest key")
+            .map(Some),
+    }
+}
+
+fn get_user_generated_attestation_key(
+    key: &KeyDescriptor,
+    caller_uid: u32,
+    db: &mut KeystoreDB,
+) -> Result<AttestationKeyInfo> {
+    let (key_id_guard, blob, cert, blob_metadata) =
+        load_attest_key_blob_and_cert(&key, caller_uid, db)
+            .context("In get_user_generated_attestation_key: Failed to load blob and cert")?;
+
+    let issuer_subject: Vec<u8> = parse_subject_from_certificate(&cert).context(
+        "In get_user_generated_attestation_key: Failed to parse subject from certificate.",
+    )?;
+
+    Ok(AttestationKeyInfo::UserGenerated { key_id_guard, blob, issuer_subject, blob_metadata })
+}
+
+fn load_attest_key_blob_and_cert(
+    key: &KeyDescriptor,
+    caller_uid: u32,
+    db: &mut KeystoreDB,
+) -> Result<(KeyIdGuard, Vec<u8>, Vec<u8>, BlobMetaData)> {
+    match key.domain {
+        Domain::BLOB => Err(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
+                .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, blob_metadata) =
+                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((key_id_guard, blob, cert, blob_metadata))
+        }
+    }
+}
diff --git a/keystore2/src/audit_log.rs b/keystore2/src/audit_log.rs
new file mode 100644
index 0000000..30fc155
--- /dev/null
+++ b/keystore2/src/audit_log.rs
@@ -0,0 +1,68 @@
+// Copyright 2021, 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.
+
+//! This module implements functions to log audit events to binary security log buffer for NIAP
+//! compliance.
+
+use crate::globals::LOGS_HANDLER;
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor,
+};
+use libc::uid_t;
+use log_event_list::{LogContext, LogIdSecurity};
+
+const TAG_KEY_GENERATED: u32 = 210024;
+const TAG_KEY_IMPORTED: u32 = 210025;
+const TAG_KEY_DESTROYED: u32 = 210026;
+
+const NAMESPACE_MASK: i64 = 0x80000000;
+
+/// For app domain returns calling app uid, for SELinux domain returns masked namespace.
+fn key_owner(key: &KeyDescriptor, calling_app: uid_t) -> i32 {
+    match key.domain {
+        Domain::APP => calling_app as i32,
+        Domain::SELINUX => (key.nspace | NAMESPACE_MASK) as i32,
+        _ => {
+            log::info!("Not logging audit event for key with unexpected domain");
+            0
+        }
+    }
+}
+
+/// Logs key generation event to NIAP audit log.
+pub fn log_key_generated(key: &KeyDescriptor, calling_app: uid_t, success: bool) {
+    log_key_event(TAG_KEY_GENERATED, key, calling_app, success);
+}
+
+/// Logs key import event to NIAP audit log.
+pub fn log_key_imported(key: &KeyDescriptor, calling_app: uid_t, success: bool) {
+    log_key_event(TAG_KEY_IMPORTED, key, calling_app, success);
+}
+
+/// Logs key deletion event to NIAP audit log.
+pub fn log_key_deleted(key: &KeyDescriptor, calling_app: uid_t, success: bool) {
+    log_key_event(TAG_KEY_DESTROYED, key, calling_app, success);
+}
+
+fn log_key_event(tag: u32, key: &KeyDescriptor, calling_app: uid_t, success: bool) {
+    if let Some(ctx) = LogContext::new(LogIdSecurity, tag) {
+        let event = ctx
+            .append_i32(if success { 1 } else { 0 })
+            .append_str(key.alias.as_ref().map_or("none", String::as_str))
+            .append_i32(key_owner(key, calling_app));
+        LOGS_HANDLER.queue_lo(move |_| {
+            event.write();
+        });
+    }
+}
diff --git a/keystore2/src/authorization.rs b/keystore2/src/authorization.rs
new file mode 100644
index 0000000..d07dab5
--- /dev/null
+++ b/keystore2/src/authorization.rs
@@ -0,0 +1,279 @@
+// Copyright 2020, 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.
+
+//! This module implements IKeystoreAuthorization AIDL interface.
+
+use crate::error::Error as KeystoreError;
+use crate::globals::{ENFORCEMENTS, SUPER_KEY, DB, LEGACY_MIGRATOR};
+use crate::permission::KeystorePerm;
+use crate::super_key::UserState;
+use crate::utils::{check_keystore_permission, watchdog as wd};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    HardwareAuthToken::HardwareAuthToken,
+};
+use android_security_authorization::binder::{BinderFeatures,ExceptionCode, Interface, Result as BinderResult,
+     Strong, Status as BinderStatus};
+use android_security_authorization::aidl::android::security::authorization::{
+    IKeystoreAuthorization::BnKeystoreAuthorization, IKeystoreAuthorization::IKeystoreAuthorization,
+    LockScreenEvent::LockScreenEvent, AuthorizationTokens::AuthorizationTokens,
+    ResponseCode::ResponseCode,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    ResponseCode::ResponseCode as KsResponseCode };
+use anyhow::{Context, Result};
+use keystore2_crypto::Password;
+use keystore2_selinux as selinux;
+
+/// This is the Authorization error type, it wraps binder exceptions and the
+/// Authorization ResponseCode
+#[derive(Debug, thiserror::Error, PartialEq)]
+pub enum Error {
+    /// Wraps an IKeystoreAuthorization response code as defined by
+    /// android.security.authorization AIDL interface specification.
+    #[error("Error::Rc({0:?})")]
+    Rc(ResponseCode),
+    /// Wraps a Binder exception code other than a service specific exception.
+    #[error("Binder exception code {0:?}, {1:?}")]
+    Binder(ExceptionCode, i32),
+}
+
+/// This function should be used by authorization service calls to translate error conditions
+/// into service specific exceptions.
+///
+/// All error conditions get logged by this function.
+///
+/// `Error::Rc(x)` variants get mapped onto a service specific error code of `x`.
+/// Certain response codes may be returned from keystore/ResponseCode.aidl by the keystore2 modules,
+/// which are then converted to the corresponding response codes of android.security.authorization
+/// AIDL interface specification.
+///
+/// `selinux::Error::perm()` is mapped on `ResponseCode::PERMISSION_DENIED`.
+///
+/// All non `Error` error conditions get mapped onto ResponseCode::SYSTEM_ERROR`.
+///
+/// `handle_ok` will be called if `result` is `Ok(value)` where `value` will be passed
+/// as argument to `handle_ok`. `handle_ok` must generate a `BinderResult<T>`, but it
+/// typically returns Ok(value).
+pub fn map_or_log_err<T, U, F>(result: Result<U>, handle_ok: F) -> BinderResult<T>
+where
+    F: FnOnce(U) -> BinderResult<T>,
+{
+    result.map_or_else(
+        |e| {
+            log::error!("{:#?}", e);
+            let root_cause = e.root_cause();
+            if let Some(KeystoreError::Rc(ks_rcode)) = root_cause.downcast_ref::<KeystoreError>() {
+                let rc = match *ks_rcode {
+                    // Although currently keystore2/ResponseCode.aidl and
+                    // authorization/ResponseCode.aidl share the same integer values for the
+                    // common response codes, this may deviate in the future, hence the
+                    // conversion here.
+                    KsResponseCode::SYSTEM_ERROR => ResponseCode::SYSTEM_ERROR.0,
+                    KsResponseCode::KEY_NOT_FOUND => ResponseCode::KEY_NOT_FOUND.0,
+                    KsResponseCode::VALUE_CORRUPTED => ResponseCode::VALUE_CORRUPTED.0,
+                    KsResponseCode::INVALID_ARGUMENT => ResponseCode::INVALID_ARGUMENT.0,
+                    // If the code paths of IKeystoreAuthorization aidl's methods happen to return
+                    // other error codes from KsResponseCode in the future, they should be converted
+                    // as well.
+                    _ => ResponseCode::SYSTEM_ERROR.0,
+                };
+                return Err(BinderStatus::new_service_specific_error(rc, None));
+            }
+            let rc = match root_cause.downcast_ref::<Error>() {
+                Some(Error::Rc(rcode)) => rcode.0,
+                Some(Error::Binder(_, _)) => ResponseCode::SYSTEM_ERROR.0,
+                None => match root_cause.downcast_ref::<selinux::Error>() {
+                    Some(selinux::Error::PermissionDenied) => ResponseCode::PERMISSION_DENIED.0,
+                    _ => ResponseCode::SYSTEM_ERROR.0,
+                },
+            };
+            Err(BinderStatus::new_service_specific_error(rc, None))
+        },
+        handle_ok,
+    )
+}
+
+/// This struct is defined to implement the aforementioned AIDL interface.
+/// As of now, it is an empty struct.
+pub struct AuthorizationManager;
+
+impl AuthorizationManager {
+    /// Create a new instance of Keystore Authorization service.
+    pub fn new_native_binder() -> Result<Strong<dyn IKeystoreAuthorization>> {
+        Ok(BnKeystoreAuthorization::new_binder(
+            Self,
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        ))
+    }
+
+    fn add_auth_token(&self, auth_token: &HardwareAuthToken) -> Result<()> {
+        // Check keystore permission.
+        check_keystore_permission(KeystorePerm::add_auth()).context("In add_auth_token.")?;
+
+        ENFORCEMENTS.add_auth_token(auth_token.clone())?;
+        Ok(())
+    }
+
+    fn on_lock_screen_event(
+        &self,
+        lock_screen_event: LockScreenEvent,
+        user_id: i32,
+        password: Option<Password>,
+        unlocking_sids: Option<&[i64]>,
+    ) -> Result<()> {
+        log::info!(
+            "on_lock_screen_event({:?}, user_id={:?}, password.is_some()={}, unlocking_sids={:?})",
+            lock_screen_event,
+            user_id,
+            password.is_some(),
+            unlocking_sids
+        );
+        match (lock_screen_event, password) {
+            (LockScreenEvent::UNLOCK, Some(password)) => {
+                // This corresponds to the unlock() method in legacy keystore API.
+                // check permission
+                check_keystore_permission(KeystorePerm::unlock())
+                    .context("In on_lock_screen_event: Unlock with password.")?;
+                ENFORCEMENTS.set_device_locked(user_id, false);
+
+                DB.with(|db| {
+                    SUPER_KEY.unlock_screen_lock_bound_key(
+                        &mut db.borrow_mut(),
+                        user_id as u32,
+                        &password,
+                    )
+                })
+                .context("In on_lock_screen_event: unlock_screen_lock_bound_key failed")?;
+
+                // Unlock super key.
+                if let UserState::Uninitialized = DB
+                    .with(|db| {
+                        UserState::get_with_password_unlock(
+                            &mut db.borrow_mut(),
+                            &LEGACY_MIGRATOR,
+                            &SUPER_KEY,
+                            user_id as u32,
+                            &password,
+                        )
+                    })
+                    .context("In on_lock_screen_event: Unlock with password.")?
+                {
+                    log::info!(
+                        "In on_lock_screen_event. Trying to unlock when LSKF is uninitialized."
+                    );
+                }
+
+                Ok(())
+            }
+            (LockScreenEvent::UNLOCK, None) => {
+                check_keystore_permission(KeystorePerm::unlock())
+                    .context("In on_lock_screen_event: Unlock.")?;
+                ENFORCEMENTS.set_device_locked(user_id, false);
+                DB.with(|db| {
+                    SUPER_KEY.try_unlock_user_with_biometric(&mut db.borrow_mut(), user_id as u32)
+                })
+                .context("In on_lock_screen_event: try_unlock_user_with_biometric failed")?;
+                Ok(())
+            }
+            (LockScreenEvent::LOCK, None) => {
+                check_keystore_permission(KeystorePerm::lock())
+                    .context("In on_lock_screen_event: Lock")?;
+                ENFORCEMENTS.set_device_locked(user_id, true);
+                DB.with(|db| {
+                    SUPER_KEY.lock_screen_lock_bound_key(
+                        &mut db.borrow_mut(),
+                        user_id as u32,
+                        unlocking_sids.unwrap_or(&[]),
+                    );
+                });
+                Ok(())
+            }
+            _ => {
+                // Any other combination is not supported.
+                Err(Error::Rc(ResponseCode::INVALID_ARGUMENT))
+                    .context("In on_lock_screen_event: Unknown event.")
+            }
+        }
+    }
+
+    fn get_auth_tokens_for_credstore(
+        &self,
+        challenge: i64,
+        secure_user_id: i64,
+        auth_token_max_age_millis: i64,
+    ) -> Result<AuthorizationTokens> {
+        // Check permission. Function should return if this failed. Therefore having '?' at the end
+        // is very important.
+        check_keystore_permission(KeystorePerm::get_auth_token())
+            .context("In get_auth_tokens_for_credstore.")?;
+
+        // If the challenge is zero, return error
+        if challenge == 0 {
+            return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT))
+                .context("In get_auth_tokens_for_credstore. Challenge can not be zero.");
+        }
+        // Obtain the auth token and the timestamp token from the enforcement module.
+        let (auth_token, ts_token) =
+            ENFORCEMENTS.get_auth_tokens(challenge, secure_user_id, auth_token_max_age_millis)?;
+        Ok(AuthorizationTokens { authToken: auth_token, timestampToken: ts_token })
+    }
+}
+
+impl Interface for AuthorizationManager {}
+
+impl IKeystoreAuthorization for AuthorizationManager {
+    fn addAuthToken(&self, auth_token: &HardwareAuthToken) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreAuthorization::addAuthToken", 500);
+        map_or_log_err(self.add_auth_token(auth_token), Ok)
+    }
+
+    fn onLockScreenEvent(
+        &self,
+        lock_screen_event: LockScreenEvent,
+        user_id: i32,
+        password: Option<&[u8]>,
+        unlocking_sids: Option<&[i64]>,
+    ) -> BinderResult<()> {
+        let _wp =
+            wd::watch_millis_with("IKeystoreAuthorization::onLockScreenEvent", 500, move || {
+                format!("lock event: {}", lock_screen_event.0)
+            });
+        map_or_log_err(
+            self.on_lock_screen_event(
+                lock_screen_event,
+                user_id,
+                password.map(|pw| pw.into()),
+                unlocking_sids,
+            ),
+            Ok,
+        )
+    }
+
+    fn getAuthTokensForCredStore(
+        &self,
+        challenge: i64,
+        secure_user_id: i64,
+        auth_token_max_age_millis: i64,
+    ) -> binder::public_api::Result<AuthorizationTokens> {
+        let _wp = wd::watch_millis("IKeystoreAuthorization::getAuthTokensForCredStore", 500);
+        map_or_log_err(
+            self.get_auth_tokens_for_credstore(
+                challenge,
+                secure_user_id,
+                auth_token_max_age_millis,
+            ),
+            Ok,
+        )
+    }
+}
diff --git a/keystore2/src/boot_level_keys.rs b/keystore2/src/boot_level_keys.rs
new file mode 100644
index 0000000..3084195
--- /dev/null
+++ b/keystore2/src/boot_level_keys.rs
@@ -0,0 +1,227 @@
+// Copyright 2021, 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.
+
+//! Offer keys based on the "boot level" for superencryption.
+
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, Digest::Digest, KeyPurpose::KeyPurpose, SecurityLevel::SecurityLevel,
+};
+use anyhow::{Context, Result};
+use keystore2_crypto::{hkdf_expand, ZVec, AES_256_KEY_LENGTH};
+use std::{collections::VecDeque, convert::TryFrom};
+
+use crate::{database::KeystoreDB, key_parameter::KeyParameterValue, raw_device::KeyMintDevice};
+
+/// This is not thread safe; caller must hold a lock before calling.
+/// In practice the caller is SuperKeyManager and the lock is the
+/// Mutex on its internal state.
+pub fn get_level_zero_key(db: &mut KeystoreDB) -> Result<ZVec> {
+    let key_desc = KeyMintDevice::internal_descriptor("boot_level_key".to_string());
+    let params = [
+        KeyParameterValue::Algorithm(Algorithm::HMAC).into(),
+        KeyParameterValue::Digest(Digest::SHA_2_256).into(),
+        KeyParameterValue::KeySize(256).into(),
+        KeyParameterValue::MinMacLength(256).into(),
+        KeyParameterValue::KeyPurpose(KeyPurpose::SIGN).into(),
+        KeyParameterValue::NoAuthRequired.into(),
+        KeyParameterValue::MaxUsesPerBoot(1).into(),
+    ];
+    // We use TRUSTED_ENVIRONMENT here because it is the authority on when
+    // the device has rebooted.
+    let km_dev: KeyMintDevice = KeyMintDevice::get(SecurityLevel::TRUSTED_ENVIRONMENT)
+        .context("In get_level_zero_key: KeyMintDevice::get failed")?;
+    let (key_id_guard, key_entry) = km_dev
+        .lookup_or_generate_key(db, &key_desc, &params)
+        .context("In get_level_zero_key: lookup_or_generate_key failed")?;
+
+    let params = [KeyParameterValue::MacLength(256).into()];
+    let level_zero_key = km_dev
+        .use_key_in_one_step(
+            db,
+            &key_id_guard,
+            &key_entry,
+            KeyPurpose::SIGN,
+            &params,
+            None,
+            b"Create boot level key",
+        )
+        .context("In get_level_zero_key: use_key_in_one_step failed")?;
+    // TODO: this is rather unsatisfactory, we need a better way to handle
+    // sensitive binder returns.
+    let level_zero_key = ZVec::try_from(level_zero_key)
+        .context("In get_level_zero_key: conversion to ZVec failed")?;
+    Ok(level_zero_key)
+}
+
+/// Holds the key for the current boot level, and a cache of future keys generated as required.
+/// When the boot level advances, keys prior to the current boot level are securely dropped.
+pub struct BootLevelKeyCache {
+    /// Least boot level currently accessible, if any is.
+    current: usize,
+    /// Invariant: cache entry *i*, if it exists, holds the HKDF key for boot level
+    /// *i* + `current`. If the cache is non-empty it can be grown forwards, but it cannot be
+    /// grown backwards, so keys below `current` are inaccessible.
+    /// `cache.clear()` makes all keys inaccessible.
+    cache: VecDeque<ZVec>,
+}
+
+impl BootLevelKeyCache {
+    const HKDF_ADVANCE: &'static [u8] = b"Advance KDF one step";
+    const HKDF_AES: &'static [u8] = b"Generate AES-256-GCM key";
+    const HKDF_KEY_SIZE: usize = 32;
+
+    /// Initialize the cache with the level zero key.
+    pub fn new(level_zero_key: ZVec) -> Self {
+        let mut cache: VecDeque<ZVec> = VecDeque::new();
+        cache.push_back(level_zero_key);
+        Self { current: 0, cache }
+    }
+
+    /// Report whether the key for the given level can be inferred.
+    pub fn level_accessible(&self, boot_level: usize) -> bool {
+        // If the requested boot level is lower than the current boot level
+        // or if we have reached the end (`cache.empty()`) we can't retrieve
+        // the boot key.
+        boot_level >= self.current && !self.cache.is_empty()
+    }
+
+    /// Get the HKDF key for boot level `boot_level`. The key for level *i*+1
+    /// is calculated from the level *i* key using `hkdf_expand`.
+    fn get_hkdf_key(&mut self, boot_level: usize) -> Result<Option<&ZVec>> {
+        if !self.level_accessible(boot_level) {
+            return Ok(None);
+        }
+        // `self.cache.len()` represents the first entry not in the cache,
+        // so `self.current + self.cache.len()` is the first boot level not in the cache.
+        let first_not_cached = self.current + self.cache.len();
+
+        // Grow the cache forwards until it contains the desired boot level.
+        for _level in first_not_cached..=boot_level {
+            // We check at the start that cache is non-empty and future iterations only push,
+            // so this must unwrap.
+            let highest_key = self.cache.back().unwrap();
+            let next_key = hkdf_expand(Self::HKDF_KEY_SIZE, highest_key, Self::HKDF_ADVANCE)
+                .context("In BootLevelKeyCache::get_hkdf_key: Advancing key one step")?;
+            self.cache.push_back(next_key);
+        }
+
+        // If we reach this point, we should have a key at index boot_level - current.
+        Ok(Some(self.cache.get(boot_level - self.current).unwrap()))
+    }
+
+    /// Drop keys prior to the given boot level, while retaining the ability to generate keys for
+    /// that level and later.
+    pub fn advance_boot_level(&mut self, new_boot_level: usize) -> Result<()> {
+        if !self.level_accessible(new_boot_level) {
+            log::error!(
+                concat!(
+                    "In BootLevelKeyCache::advance_boot_level: ",
+                    "Failed to advance boot level to {}, current is {}, cache size {}"
+                ),
+                new_boot_level,
+                self.current,
+                self.cache.len()
+            );
+            return Ok(());
+        }
+
+        // We `get` the new boot level for the side effect of advancing the cache to a point
+        // where the new boot level is present.
+        self.get_hkdf_key(new_boot_level)
+            .context("In BootLevelKeyCache::advance_boot_level: Advancing cache")?;
+
+        // Then we split the queue at the index of the new boot level and discard the front,
+        // keeping only the keys with the current boot level or higher.
+        self.cache = self.cache.split_off(new_boot_level - self.current);
+
+        // The new cache has the new boot level at index 0, so we set `current` to
+        // `new_boot_level`.
+        self.current = new_boot_level;
+
+        Ok(())
+    }
+
+    /// Drop all keys, effectively raising the current boot level to infinity; no keys can
+    /// be inferred from this point on.
+    pub fn finish(&mut self) {
+        self.cache.clear();
+    }
+
+    fn expand_key(
+        &mut self,
+        boot_level: usize,
+        out_len: usize,
+        info: &[u8],
+    ) -> Result<Option<ZVec>> {
+        self.get_hkdf_key(boot_level)
+            .context("In BootLevelKeyCache::expand_key: Looking up HKDF key")?
+            .map(|k| hkdf_expand(out_len, k, info))
+            .transpose()
+            .context("In BootLevelKeyCache::expand_key: Calling hkdf_expand")
+    }
+
+    /// Return the AES-256-GCM key for the current boot level.
+    pub fn aes_key(&mut self, boot_level: usize) -> Result<Option<ZVec>> {
+        self.expand_key(boot_level, AES_256_KEY_LENGTH, BootLevelKeyCache::HKDF_AES)
+            .context("In BootLevelKeyCache::aes_key: expand_key failed")
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_output_is_consistent() -> Result<()> {
+        let initial_key = b"initial key";
+        let mut blkc = BootLevelKeyCache::new(ZVec::try_from(initial_key as &[u8])?);
+        assert_eq!(true, blkc.level_accessible(0));
+        assert_eq!(true, blkc.level_accessible(9));
+        assert_eq!(true, blkc.level_accessible(10));
+        assert_eq!(true, blkc.level_accessible(100));
+        let v0 = blkc.aes_key(0).unwrap().unwrap();
+        let v10 = blkc.aes_key(10).unwrap().unwrap();
+        assert_eq!(Some(&v0), blkc.aes_key(0)?.as_ref());
+        assert_eq!(Some(&v10), blkc.aes_key(10)?.as_ref());
+        blkc.advance_boot_level(5)?;
+        assert_eq!(false, blkc.level_accessible(0));
+        assert_eq!(true, blkc.level_accessible(9));
+        assert_eq!(true, blkc.level_accessible(10));
+        assert_eq!(true, blkc.level_accessible(100));
+        assert_eq!(None, blkc.aes_key(0)?);
+        assert_eq!(Some(&v10), blkc.aes_key(10)?.as_ref());
+        blkc.advance_boot_level(10)?;
+        assert_eq!(false, blkc.level_accessible(0));
+        assert_eq!(false, blkc.level_accessible(9));
+        assert_eq!(true, blkc.level_accessible(10));
+        assert_eq!(true, blkc.level_accessible(100));
+        assert_eq!(None, blkc.aes_key(0)?);
+        assert_eq!(Some(&v10), blkc.aes_key(10)?.as_ref());
+        blkc.advance_boot_level(0)?;
+        assert_eq!(false, blkc.level_accessible(0));
+        assert_eq!(false, blkc.level_accessible(9));
+        assert_eq!(true, blkc.level_accessible(10));
+        assert_eq!(true, blkc.level_accessible(100));
+        assert_eq!(None, blkc.aes_key(0)?);
+        assert_eq!(Some(v10), blkc.aes_key(10)?);
+        blkc.finish();
+        assert_eq!(false, blkc.level_accessible(0));
+        assert_eq!(false, blkc.level_accessible(9));
+        assert_eq!(false, blkc.level_accessible(10));
+        assert_eq!(false, blkc.level_accessible(100));
+        assert_eq!(None, blkc.aes_key(0)?);
+        assert_eq!(None, blkc.aes_key(10)?);
+        Ok(())
+    }
+}
diff --git a/keystore2/src/crypto/Android.bp b/keystore2/src/crypto/Android.bp
new file mode 100644
index 0000000..3ba47cd
--- /dev/null
+++ b/keystore2/src/crypto/Android.bp
@@ -0,0 +1,127 @@
+// Copyright 2020, 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 {
+    // 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",
+    srcs: ["lib.rs"],
+    rustlibs: [
+        "libkeystore2_crypto_bindgen",
+        "liblog_rust",
+        "libnix",
+        "libthiserror",
+    ],
+    shared_libs: [
+        "libkeystore2_crypto",
+        "libcrypto",
+    ],
+}
+
+cc_library {
+    name: "libkeystore2_crypto",
+    srcs: [
+        "crypto.cpp",
+        "certificate_utils.cpp",
+    ],
+    export_include_dirs: ["include"],
+    shared_libs: [
+        "libcrypto",
+        "liblog",
+    ],
+}
+
+rust_bindgen {
+    name: "libkeystore2_crypto_bindgen",
+    wrapper_src: "crypto.hpp",
+    crate_name: "keystore2_crypto_bindgen",
+    source_stem: "bindings",
+    host_supported: true,
+    shared_libs: ["libcrypto"],
+    bindgen_flags: [
+        "--size_t-is-usize",
+        "--allowlist-function", "randomBytes",
+        "--allowlist-function", "AES_gcm_encrypt",
+        "--allowlist-function", "AES_gcm_decrypt",
+        "--allowlist-function", "CreateKeyId",
+        "--allowlist-function", "generateKeyFromPassword",
+        "--allowlist-function", "HKDFExtract",
+        "--allowlist-function", "HKDFExpand",
+        "--allowlist-function", "ECDHComputeKey",
+        "--allowlist-function", "ECKEYGenerateKey",
+        "--allowlist-function", "ECKEYMarshalPrivateKey",
+        "--allowlist-function", "ECKEYParsePrivateKey",
+        "--allowlist-function", "EC_KEY_get0_public_key",
+        "--allowlist-function", "ECPOINTPoint2Oct",
+        "--allowlist-function", "ECPOINTOct2Point",
+        "--allowlist-function", "EC_KEY_free",
+        "--allowlist-function", "EC_POINT_free",
+        "--allowlist-function", "extractSubjectFromCertificate",
+        "--allowlist-type", "EC_KEY",
+        "--allowlist-type", "EC_POINT",
+        "--allowlist-var", "EC_MAX_BYTES",
+        "--allowlist-var", "EVP_MAX_MD_SIZE",
+    ],
+    cflags: ["-DBORINGSSL_NO_CXX"],
+}
+
+rust_test {
+    name: "keystore2_crypto_test_rust",
+    crate_name: "keystore2_crypto_test_rust",
+    srcs: ["lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    rustlibs: [
+        "libkeystore2_crypto_bindgen",
+        "liblog_rust",
+        "libnix",
+        "libthiserror",
+    ],
+    static_libs: [
+        "libkeystore2_crypto",
+    ],
+    shared_libs: [
+        "libc++",
+        "libcrypto",
+        "liblog",
+    ],
+}
+
+cc_test {
+    name: "keystore2_crypto_test",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    srcs: [
+        "tests/certificate_utils_test.cpp",
+        "tests/gtest_main.cpp",
+    ],
+    test_suites: ["general-tests"],
+    static_libs: [
+        "libkeystore2_crypto",
+    ],
+    shared_libs: [
+        "libcrypto",
+    ],
+}
diff --git a/keystore2/src/crypto/TEST_MAPPING b/keystore2/src/crypto/TEST_MAPPING
new file mode 100644
index 0000000..f6fb97a
--- /dev/null
+++ b/keystore2/src/crypto/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "keystore2_crypto_test_rust"
+    },
+    {
+      "name": "keystore2_crypto_test"
+    }
+  ]
+}
diff --git a/keystore2/src/crypto/certificate_utils.cpp b/keystore2/src/crypto/certificate_utils.cpp
new file mode 100644
index 0000000..31c7fb4
--- /dev/null
+++ b/keystore2/src/crypto/certificate_utils.cpp
@@ -0,0 +1,628 @@
+/*
+ * Copyright 2020, 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 <certificate_utils.h>
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+#include <openssl/x509v3.h>
+
+#include <functional>
+#include <limits>
+#include <string>
+#include <variant>
+#include <vector>
+
+namespace keystore {
+
+namespace {
+
+constexpr int kDigitalSignatureKeyUsageBit = 0;
+constexpr int kKeyEnciphermentKeyUsageBit = 2;
+constexpr int kDataEnciphermentKeyUsageBit = 3;
+constexpr int kKeyCertSignBit = 5;
+constexpr int kMaxKeyUsageBit = 8;
+
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_STRING);
+DEFINE_OPENSSL_OBJECT_POINTER(RSA_PSS_PARAMS);
+DEFINE_OPENSSL_OBJECT_POINTER(AUTHORITY_KEYID);
+DEFINE_OPENSSL_OBJECT_POINTER(BASIC_CONSTRAINTS);
+DEFINE_OPENSSL_OBJECT_POINTER(X509_ALGOR);
+DEFINE_OPENSSL_OBJECT_POINTER(BIGNUM);
+
+}  // namespace
+
+constexpr const char kDefaultCommonName[] = "Default Common Name";
+
+std::variant<CertUtilsError, X509_NAME_Ptr>
+makeCommonName(std::optional<std::reference_wrapper<const std::vector<uint8_t>>> name) {
+    if (name) {
+        const uint8_t* p = name->get().data();
+        X509_NAME_Ptr x509_name(d2i_X509_NAME(nullptr, &p, name->get().size()));
+        if (!x509_name) {
+            return CertUtilsError::MemoryAllocation;
+        }
+        return x509_name;
+    }
+
+    X509_NAME_Ptr x509_name(X509_NAME_new());
+    if (!x509_name) {
+        return CertUtilsError::MemoryAllocation;
+    }
+    if (!X509_NAME_add_entry_by_txt(x509_name.get(), "CN", MBSTRING_ASC,
+                                    reinterpret_cast<const uint8_t*>(kDefaultCommonName),
+                                    sizeof(kDefaultCommonName) - 1, -1 /* loc */, 0 /* set */)) {
+        return CertUtilsError::BoringSsl;
+    }
+    return x509_name;
+}
+
+std::variant<CertUtilsError, std::vector<uint8_t>> makeKeyId(const X509* cert) {
+    std::vector<uint8_t> keyid(20);
+    unsigned int len;
+    if (!X509_pubkey_digest(cert, EVP_sha1(), keyid.data(), &len)) {
+        return CertUtilsError::Encoding;
+    }
+    return keyid;
+}
+
+std::variant<CertUtilsError, AUTHORITY_KEYID_Ptr>
+makeAuthorityKeyExtension(const std::vector<uint8_t>& keyid) {
+    AUTHORITY_KEYID_Ptr auth_key(AUTHORITY_KEYID_new());
+    if (!auth_key) {
+        return CertUtilsError::MemoryAllocation;
+    }
+
+    auth_key->keyid = ASN1_OCTET_STRING_new();
+    if (auth_key->keyid == nullptr) {
+        return CertUtilsError::MemoryAllocation;
+    }
+
+    if (!ASN1_OCTET_STRING_set(auth_key->keyid, keyid.data(), keyid.size())) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    return auth_key;
+}
+
+std::variant<CertUtilsError, ASN1_OCTET_STRING_Ptr>
+makeSubjectKeyExtension(const std::vector<uint8_t>& keyid) {
+
+    // Build OCTET_STRING
+    ASN1_OCTET_STRING_Ptr keyid_str(ASN1_OCTET_STRING_new());
+    if (!keyid_str || !ASN1_OCTET_STRING_set(keyid_str.get(), keyid.data(), keyid.size())) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    return keyid_str;
+}
+
+std::variant<CertUtilsError, BASIC_CONSTRAINTS_Ptr>
+makeBasicConstraintsExtension(bool is_ca, std::optional<int> path_length) {
+
+    BASIC_CONSTRAINTS_Ptr bcons(BASIC_CONSTRAINTS_new());
+    if (!bcons) {
+        return CertUtilsError::MemoryAllocation;
+    }
+
+    bcons->ca = is_ca;
+    bcons->pathlen = nullptr;
+    if (path_length) {
+        bcons->pathlen = ASN1_INTEGER_new();
+        if (bcons->pathlen == nullptr || !ASN1_INTEGER_set(bcons->pathlen, *path_length)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+
+    return bcons;
+}
+
+std::variant<CertUtilsError, ASN1_BIT_STRING_Ptr>
+makeKeyUsageExtension(bool is_signing_key, bool is_encryption_key, bool is_cert_key) {
+    // Build BIT_STRING with correct contents.
+    ASN1_BIT_STRING_Ptr key_usage(ASN1_BIT_STRING_new());
+    if (!key_usage) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    for (size_t i = 0; i <= kMaxKeyUsageBit; ++i) {
+        if (!ASN1_BIT_STRING_set_bit(key_usage.get(), i, 0)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+
+    if (is_signing_key) {
+        if (!ASN1_BIT_STRING_set_bit(key_usage.get(), kDigitalSignatureKeyUsageBit, 1)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+
+    if (is_encryption_key) {
+        if (!ASN1_BIT_STRING_set_bit(key_usage.get(), kKeyEnciphermentKeyUsageBit, 1) ||
+            !ASN1_BIT_STRING_set_bit(key_usage.get(), kDataEnciphermentKeyUsageBit, 1)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+
+    if (is_cert_key) {
+        if (!ASN1_BIT_STRING_set_bit(key_usage.get(), kKeyCertSignBit, 1)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+
+    return key_usage;
+}
+
+template <typename Out, typename In> static Out saturate(In in) {
+    if constexpr (std::is_signed_v<Out> == std::is_signed_v<In>) {
+        if constexpr (sizeof(Out) >= sizeof(In)) {
+            // Same sign, and In fits into Out. Cast is lossless.
+            return static_cast<Out>(in);
+        } else {
+            // Out is smaller than In we may need to truncate.
+            // We pick the smaller of `out::max()` and the greater of `out::min()` and `in`.
+            return static_cast<Out>(
+                std::min(static_cast<In>(std::numeric_limits<Out>::max()),
+                         std::max(static_cast<In>(std::numeric_limits<Out>::min()), in)));
+        }
+    } else {
+        // So we have different signs. This puts the lower bound at 0 because either input or output
+        // is unsigned. The upper bound is max of the smaller type or, if they are equal the max of
+        // the signed type.
+        if constexpr (std::is_signed_v<Out>) {
+            if constexpr (sizeof(Out) > sizeof(In)) {
+                return static_cast<Out>(in);
+            } else {
+                // Because `out` is the signed one, the lower bound of `in` is 0 and fits into
+                // `out`. We just have to compare the maximum and we do it in type In because it has
+                // a greater range than Out, so Out::max() is guaranteed to fit.
+                return static_cast<Out>(
+                    std::min(static_cast<In>(std::numeric_limits<Out>::max()), in));
+            }
+        } else {
+            // Out is unsigned. So we can return 0 if in is negative.
+            if (in < 0) return 0;
+            if constexpr (sizeof(Out) >= sizeof(In)) {
+                // If Out is wider or equal we can assign lossless.
+                return static_cast<Out>(in);
+            } else {
+                // Otherwise we have to take the minimum of Out::max() and `in`.
+                return static_cast<Out>(
+                    std::min(static_cast<In>(std::numeric_limits<Out>::max()), in));
+            }
+        }
+    }
+}
+
+// Creates a rump certificate structure with serial, subject and issuer names, as well as
+// activation and expiry date.
+// Callers should pass an empty X509_Ptr and check the return value for CertUtilsError::Ok (0)
+// before accessing the result.
+std::variant<CertUtilsError, X509_Ptr>
+makeCertRump(std::optional<std::reference_wrapper<const std::vector<uint8_t>>> serial,
+             std::optional<std::reference_wrapper<const std::vector<uint8_t>>> subject,
+             const int64_t activeDateTimeMilliSeconds,
+             const int64_t usageExpireDateTimeMilliSeconds) {
+
+    // Create certificate structure.
+    X509_Ptr certificate(X509_new());
+    if (!certificate) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    // Set the X509 version.
+    if (!X509_set_version(certificate.get(), 2 /* version 3, but zero-based */)) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    BIGNUM_Ptr bn_serial;
+    if (serial) {
+        bn_serial = BIGNUM_Ptr(BN_bin2bn(serial->get().data(), serial->get().size(), nullptr));
+        if (!bn_serial) {
+            return CertUtilsError::MemoryAllocation;
+        }
+    } else {
+        bn_serial = BIGNUM_Ptr(BN_new());
+        if (!bn_serial) {
+            return CertUtilsError::MemoryAllocation;
+        }
+        BN_zero(bn_serial.get());
+    }
+
+    // Set the certificate serialNumber
+    ASN1_INTEGER_Ptr serialNumber(ASN1_INTEGER_new());
+    if (!serialNumber || !BN_to_ASN1_INTEGER(bn_serial.get(), serialNumber.get()) ||
+        !X509_set_serialNumber(certificate.get(), serialNumber.get() /* Don't release; copied */))
+        return CertUtilsError::BoringSsl;
+
+    // Set Subject Name
+    auto subjectName = makeCommonName(subject);
+    if (auto x509_subject = std::get_if<X509_NAME_Ptr>(&subjectName)) {
+        if (!X509_set_subject_name(certificate.get(), x509_subject->get() /* copied */)) {
+            return CertUtilsError::BoringSsl;
+        }
+    } else {
+        return std::get<CertUtilsError>(subjectName);
+    }
+
+    time_t notBeforeTime = saturate<time_t>(activeDateTimeMilliSeconds / 1000);
+    // Set activation date.
+    ASN1_TIME_Ptr notBefore(ASN1_TIME_new());
+    if (!notBefore || !ASN1_TIME_set(notBefore.get(), notBeforeTime) ||
+        !X509_set_notBefore(certificate.get(), notBefore.get() /* Don't release; copied */))
+        return CertUtilsError::BoringSsl;
+
+    // Set expiration date.
+    time_t notAfterTime;
+    notAfterTime = saturate<time_t>(usageExpireDateTimeMilliSeconds / 1000);
+
+    ASN1_TIME_Ptr notAfter(ASN1_TIME_new());
+    if (!notAfter || !ASN1_TIME_set(notAfter.get(), notAfterTime) ||
+        !X509_set_notAfter(certificate.get(), notAfter.get() /* Don't release; copied */)) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    return certificate;
+}
+
+std::variant<CertUtilsError, X509_Ptr>
+makeCert(const EVP_PKEY* evp_pkey,
+         std::optional<std::reference_wrapper<const std::vector<uint8_t>>> serial,
+         std::optional<std::reference_wrapper<const std::vector<uint8_t>>> subject,
+         const int64_t activeDateTimeMilliSeconds, const int64_t usageExpireDateTimeMilliSeconds,
+         bool addSubjectKeyIdEx, std::optional<KeyUsageExtension> keyUsageEx,
+         std::optional<BasicConstraintsExtension> basicConstraints) {
+
+    // Make the rump certificate with serial, subject, not before and not after dates.
+    auto certificateV =
+        makeCertRump(serial, subject, activeDateTimeMilliSeconds, usageExpireDateTimeMilliSeconds);
+    if (auto error = std::get_if<CertUtilsError>(&certificateV)) {
+        return *error;
+    }
+    auto certificate = std::move(std::get<X509_Ptr>(certificateV));
+
+    // Set the public key.
+    if (!X509_set_pubkey(certificate.get(), const_cast<EVP_PKEY*>(evp_pkey))) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    if (keyUsageEx) {
+        // Make and add the key usage extension.
+        auto key_usage_extensionV = makeKeyUsageExtension(
+            keyUsageEx->isSigningKey, keyUsageEx->isEncryptionKey, keyUsageEx->isCertificationKey);
+        if (auto error = std::get_if<CertUtilsError>(&key_usage_extensionV)) {
+            return *error;
+        }
+        auto key_usage_extension = std::move(std::get<ASN1_BIT_STRING_Ptr>(key_usage_extensionV));
+        if (!X509_add1_ext_i2d(certificate.get(), NID_key_usage,
+                               key_usage_extension.get() /* Don't release; copied */,
+                               true /* critical */, 0 /* flags */)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+
+    if (basicConstraints) {
+        // Make and add basic constraints
+        auto basic_constraints_extensionV =
+            makeBasicConstraintsExtension(basicConstraints->isCa, basicConstraints->pathLength);
+        if (auto error = std::get_if<CertUtilsError>(&basic_constraints_extensionV)) {
+            return *error;
+        }
+        auto basic_constraints_extension =
+            std::move(std::get<BASIC_CONSTRAINTS_Ptr>(basic_constraints_extensionV));
+        if (!X509_add1_ext_i2d(certificate.get(), NID_basic_constraints,
+                               basic_constraints_extension.get() /* Don't release; copied */,
+                               true /* critical */, 0 /* flags */)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+
+    if (addSubjectKeyIdEx) {
+        // Make and add subject key id extension.
+        auto keyidV = makeKeyId(certificate.get());
+        if (auto error = std::get_if<CertUtilsError>(&keyidV)) {
+            return *error;
+        }
+        auto& keyid = std::get<std::vector<uint8_t>>(keyidV);
+
+        auto subject_key_extensionV = makeSubjectKeyExtension(keyid);
+        if (auto error = std::get_if<CertUtilsError>(&subject_key_extensionV)) {
+            return *error;
+        }
+        auto subject_key_extension =
+            std::move(std::get<ASN1_OCTET_STRING_Ptr>(subject_key_extensionV));
+        if (!X509_add1_ext_i2d(certificate.get(), NID_subject_key_identifier,
+                               subject_key_extension.get() /* Don't release; copied */,
+                               false /* critical */, 0 /* flags */)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+
+    return certificate;
+}
+
+CertUtilsError setIssuer(X509* cert, const X509* signingCert, bool addAuthKeyExt) {
+
+    X509_NAME* issuerName(X509_get_subject_name(signingCert));
+
+    // Set Issuer Name
+    if (issuerName) {
+        if (!X509_set_issuer_name(cert, issuerName /* copied */)) {
+            return CertUtilsError::BoringSsl;
+        }
+    } else {
+        return CertUtilsError::Encoding;
+    }
+
+    if (addAuthKeyExt) {
+        // Make and add authority key extension - self signed.
+        auto keyidV = makeKeyId(signingCert);
+        if (auto error = std::get_if<CertUtilsError>(&keyidV)) {
+            return *error;
+        }
+        auto& keyid = std::get<std::vector<uint8_t>>(keyidV);
+
+        auto auth_key_extensionV = makeAuthorityKeyExtension(keyid);
+        if (auto error = std::get_if<CertUtilsError>(&auth_key_extensionV)) {
+            return *error;
+        }
+        auto auth_key_extension = std::move(std::get<AUTHORITY_KEYID_Ptr>(auth_key_extensionV));
+        if (!X509_add1_ext_i2d(cert, NID_authority_key_identifier, auth_key_extension.get(), false,
+                               0)) {
+            return CertUtilsError::BoringSsl;
+        }
+    }
+    return CertUtilsError::Ok;
+}
+
+// Takes a certificate a signing certificate and the raw private signing_key. And signs
+// the certificate with the latter.
+CertUtilsError signCert(X509* certificate, EVP_PKEY* signing_key) {
+
+    if (certificate == nullptr) {
+        return CertUtilsError::UnexpectedNullPointer;
+    }
+
+    if (!X509_sign(certificate, signing_key, EVP_sha256())) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    return CertUtilsError::Ok;
+}
+
+std::variant<CertUtilsError, std::vector<uint8_t>> encodeCert(X509* certificate) {
+    int len = i2d_X509(certificate, nullptr);
+    if (len < 0) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    auto result = std::vector<uint8_t>(len);
+    uint8_t* p = result.data();
+
+    if (i2d_X509(certificate, &p) < 0) {
+        return CertUtilsError::BoringSsl;
+    }
+    return result;
+}
+
+CertUtilsError setRsaDigestAlgorField(X509_ALGOR** alg_ptr, const EVP_MD* digest) {
+    if (alg_ptr == nullptr || digest == nullptr) {
+        return CertUtilsError::UnexpectedNullPointer;
+    }
+    *alg_ptr = X509_ALGOR_new();
+    if (*alg_ptr == nullptr) {
+        return CertUtilsError::MemoryAllocation;
+    }
+    X509_ALGOR_set_md(*alg_ptr, digest);
+    return CertUtilsError::Ok;
+}
+
+CertUtilsError setPssMaskGeneratorField(X509_ALGOR** alg_ptr, const EVP_MD* digest) {
+    X509_ALGOR* mgf1_digest = nullptr;
+    if (auto error = setRsaDigestAlgorField(&mgf1_digest, digest)) {
+        return error;
+    }
+    X509_ALGOR_Ptr mgf1_digest_ptr(mgf1_digest);
+
+    ASN1_OCTET_STRING* mgf1_digest_algor_str = nullptr;
+    if (!ASN1_item_pack(mgf1_digest, ASN1_ITEM_rptr(X509_ALGOR), &mgf1_digest_algor_str)) {
+        return CertUtilsError::Encoding;
+    }
+    ASN1_OCTET_STRING_Ptr mgf1_digest_algor_str_ptr(mgf1_digest_algor_str);
+
+    *alg_ptr = X509_ALGOR_new();
+    if (*alg_ptr == nullptr) {
+        return CertUtilsError::MemoryAllocation;
+    }
+    X509_ALGOR_set0(*alg_ptr, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, mgf1_digest_algor_str);
+    // *alg_ptr took ownership of the octet string
+    mgf1_digest_algor_str_ptr.release();
+    return CertUtilsError::Ok;
+}
+
+static CertUtilsError setSaltLength(RSA_PSS_PARAMS* pss_params, unsigned length) {
+    pss_params->saltLength = ASN1_INTEGER_new();
+    if (pss_params->saltLength == nullptr) {
+        return CertUtilsError::MemoryAllocation;
+    }
+    if (!ASN1_INTEGER_set(pss_params->saltLength, length)) {
+        return CertUtilsError::Encoding;
+    };
+    return CertUtilsError::Ok;
+}
+
+std::variant<CertUtilsError, ASN1_STRING_Ptr> buildRsaPssParameter(Digest digest) {
+    RSA_PSS_PARAMS_Ptr pss(RSA_PSS_PARAMS_new());
+    if (!pss) {
+        return CertUtilsError::MemoryAllocation;
+    }
+
+    const EVP_MD* md = nullptr;
+
+    switch (digest) {
+    case Digest::SHA1:
+        break;
+    case Digest::SHA224:
+        md = EVP_sha224();
+        break;
+    case Digest::SHA256:
+        md = EVP_sha256();
+        break;
+    case Digest::SHA384:
+        md = EVP_sha384();
+        break;
+    case Digest::SHA512:
+        md = EVP_sha512();
+        break;
+    default:
+        return CertUtilsError::InvalidArgument;
+    }
+
+    if (md != nullptr) {
+        if (auto error = setSaltLength(pss.get(), EVP_MD_size(md))) {
+            return error;
+        }
+        if (auto error = setRsaDigestAlgorField(&pss->hashAlgorithm, md)) {
+            return error;
+        }
+        if (auto error = setPssMaskGeneratorField(&pss->maskGenAlgorithm, md)) {
+            return error;
+        }
+    }
+
+    ASN1_STRING* algo_str = nullptr;
+    if (!ASN1_item_pack(pss.get(), ASN1_ITEM_rptr(RSA_PSS_PARAMS), &algo_str)) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    return ASN1_STRING_Ptr(algo_str);
+}
+
+CertUtilsError makeAndSetAlgo(X509_ALGOR* algo_field, Algo algo, Padding padding, Digest digest) {
+    if (algo_field == nullptr) {
+        return CertUtilsError::UnexpectedNullPointer;
+    }
+    ASN1_STRING_Ptr param;
+    int param_type = V_ASN1_UNDEF;
+    int nid = 0;
+    switch (algo) {
+    case Algo::ECDSA:
+        switch (digest) {
+        case Digest::SHA1:
+            nid = NID_ecdsa_with_SHA1;
+            break;
+        case Digest::SHA224:
+            nid = NID_ecdsa_with_SHA224;
+            break;
+        case Digest::SHA256:
+            nid = NID_ecdsa_with_SHA256;
+            break;
+        case Digest::SHA384:
+            nid = NID_ecdsa_with_SHA384;
+            break;
+        case Digest::SHA512:
+            nid = NID_ecdsa_with_SHA512;
+            break;
+        default:
+            return CertUtilsError::InvalidArgument;
+        }
+        break;
+    case Algo::RSA:
+        switch (padding) {
+        case Padding::PKCS1_5:
+            param_type = V_ASN1_NULL;
+            switch (digest) {
+            case Digest::SHA1:
+                nid = NID_sha1WithRSAEncryption;
+                break;
+            case Digest::SHA224:
+                nid = NID_sha224WithRSAEncryption;
+                break;
+            case Digest::SHA256:
+                nid = NID_sha256WithRSAEncryption;
+                break;
+            case Digest::SHA384:
+                nid = NID_sha384WithRSAEncryption;
+                break;
+            case Digest::SHA512:
+                nid = NID_sha512WithRSAEncryption;
+                break;
+            default:
+                return CertUtilsError::InvalidArgument;
+            }
+            break;
+        case Padding::PSS: {
+            auto v = buildRsaPssParameter(digest);
+            if (auto param_str = std::get_if<ASN1_STRING_Ptr>(&v)) {
+                param = std::move(*param_str);
+                param_type = V_ASN1_SEQUENCE;
+                nid = NID_rsassaPss;
+            } else {
+                return std::get<CertUtilsError>(v);
+            }
+            break;
+        }
+        default:
+            return CertUtilsError::InvalidArgument;
+        }
+        break;
+    default:
+        return CertUtilsError::InvalidArgument;
+    }
+
+    if (!X509_ALGOR_set0(algo_field, OBJ_nid2obj(nid), param_type, param.get())) {
+        return CertUtilsError::Encoding;
+    }
+    // The X509 struct took ownership.
+    param.release();
+    return CertUtilsError::Ok;
+}
+
+// This function allows for signing a
+CertUtilsError signCertWith(X509* certificate,
+                            std::function<std::vector<uint8_t>(const uint8_t*, size_t)> sign,
+                            Algo algo, Padding padding, Digest digest) {
+    if (auto error = makeAndSetAlgo(certificate->sig_alg, algo, padding, digest)) {
+        return error;
+    }
+    if (auto error = makeAndSetAlgo(certificate->cert_info->signature, algo, padding, digest)) {
+        return error;
+    }
+
+    uint8_t* cert_buf = nullptr;
+    int buf_len = i2d_re_X509_tbs(certificate, &cert_buf);
+    if (buf_len < 0) {
+        return CertUtilsError::Encoding;
+    }
+
+    bssl::UniquePtr<uint8_t> free_cert_buf(cert_buf);
+    auto signature = sign(cert_buf, buf_len);
+    if (signature.empty()) {
+        return CertUtilsError::SignatureFailed;
+    }
+
+    if (!ASN1_STRING_set(certificate->signature, signature.data(), signature.size())) {
+        return CertUtilsError::BoringSsl;
+    }
+
+    certificate->signature->flags &= ~(0x07);
+    certificate->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+    return CertUtilsError::Ok;
+}
+
+}  // namespace keystore
diff --git a/keystore2/src/crypto/crypto.cpp b/keystore2/src/crypto/crypto.cpp
new file mode 100644
index 0000000..e4a1ac3
--- /dev/null
+++ b/keystore2/src/crypto/crypto.cpp
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "keystore2"
+
+#include "crypto.hpp"
+
+#include <log/log.h>
+#include <openssl/aes.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdh.h>
+#include <openssl/evp.h>
+#include <openssl/hkdf.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+
+#include <vector>
+
+// Copied from system/security/keystore/blob.h.
+
+constexpr size_t kGcmTagLength = 128 / 8;
+constexpr size_t kAes128KeySizeBytes = 128 / 8;
+
+// Copied from system/security/keystore/blob.cpp.
+
+#if defined(__clang__)
+#define OPTNONE __attribute__((optnone))
+#elif defined(__GNUC__)
+#define OPTNONE __attribute__((optimize("O0")))
+#else
+#error Need a definition for OPTNONE
+#endif
+
+class ArrayEraser {
+  public:
+    ArrayEraser(uint8_t* arr, size_t size) : mArr(arr), mSize(size) {}
+    OPTNONE ~ArrayEraser() { std::fill(mArr, mArr + mSize, 0); }
+
+  private:
+    volatile uint8_t* mArr;
+    size_t mSize;
+};
+
+/**
+ * Returns a EVP_CIPHER appropriate for the given key size.
+ */
+const EVP_CIPHER* getAesCipherForKey(size_t key_size) {
+    const EVP_CIPHER* cipher = EVP_aes_256_gcm();
+    if (key_size == kAes128KeySizeBytes) {
+        cipher = EVP_aes_128_gcm();
+    }
+    return cipher;
+}
+
+bool randomBytes(uint8_t* out, size_t len) {
+    return RAND_bytes(out, len);
+}
+
+/*
+ * Encrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
+ * 'iv' and write output to 'out' (which may be the same location as 'in') and 128-bit tag to
+ * 'tag'.
+ */
+bool AES_gcm_encrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t* key,
+                     size_t key_size, const uint8_t* iv, uint8_t* tag) {
+
+    // There can be 128-bit and 256-bit keys
+    const EVP_CIPHER* cipher = getAesCipherForKey(key_size);
+
+    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
+
+    EVP_EncryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, iv);
+    EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
+
+    std::vector<uint8_t> out_tmp(len);
+    uint8_t* out_pos = out_tmp.data();
+    int out_len;
+
+    EVP_EncryptUpdate(ctx.get(), out_pos, &out_len, in, len);
+    out_pos += out_len;
+    EVP_EncryptFinal_ex(ctx.get(), out_pos, &out_len);
+    out_pos += out_len;
+    if (out_pos - out_tmp.data() != static_cast<ssize_t>(len)) {
+        ALOGD("Encrypted ciphertext is the wrong size, expected %zu, got %zd", len,
+              out_pos - out_tmp.data());
+        return false;
+    }
+
+    std::copy(out_tmp.data(), out_pos, out);
+    EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kGcmTagLength, tag);
+
+    return true;
+}
+
+/*
+ * Decrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
+ * 'iv', checking 128-bit tag at 'tag' and writing plaintext to 'out'(which may be the same
+ * location as 'in').
+ */
+bool AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t* key,
+                     size_t key_size, const uint8_t* iv, const uint8_t* tag) {
+
+    // There can be 128-bit and 256-bit keys
+    const EVP_CIPHER* cipher = getAesCipherForKey(key_size);
+
+    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
+
+    EVP_DecryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, iv);
+    EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
+    EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kGcmTagLength, const_cast<uint8_t*>(tag));
+
+    std::vector<uint8_t> out_tmp(len);
+    ArrayEraser out_eraser(out_tmp.data(), len);
+    uint8_t* out_pos = out_tmp.data();
+    int out_len;
+
+    EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
+    out_pos += out_len;
+    if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
+        ALOGE("Failed to decrypt blob; ciphertext or tag is likely corrupted");
+        return false;
+    }
+    out_pos += out_len;
+    if (out_pos - out_tmp.data() != static_cast<ssize_t>(len)) {
+        ALOGE("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
+              out_pos - out_tmp.data());
+        return false;
+    }
+
+    std::copy(out_tmp.data(), out_pos, out);
+
+    return true;
+}
+
+// Copied from system/security/keystore/keymaster_enforcement.cpp.
+
+class EvpMdCtx {
+  public:
+    EvpMdCtx() { EVP_MD_CTX_init(&ctx_); }
+    ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); }
+
+    EVP_MD_CTX* get() { return &ctx_; }
+
+  private:
+    EVP_MD_CTX ctx_;
+};
+
+bool CreateKeyId(const uint8_t* key_blob, size_t len, km_id_t* out_id) {
+    EvpMdCtx ctx;
+
+    uint8_t hash[EVP_MAX_MD_SIZE];
+    unsigned int hash_len;
+    if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr /* ENGINE */) &&
+        EVP_DigestUpdate(ctx.get(), key_blob, len) &&
+        EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) {
+        assert(hash_len >= sizeof(*out_id));
+        memcpy(out_id, hash, sizeof(*out_id));
+        return true;
+    }
+
+    return false;
+}
+
+// Copied from system/security/keystore/user_state.h
+
+static constexpr size_t SALT_SIZE = 16;
+
+// Copied from system/security/keystore/user_state.cpp.
+
+void generateKeyFromPassword(uint8_t* key, size_t key_len, const char* pw, size_t pw_len,
+                             const uint8_t* salt) {
+    size_t saltSize;
+    if (salt != nullptr) {
+        saltSize = SALT_SIZE;
+    } else {
+        // Pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
+        salt = reinterpret_cast<const uint8_t*>("keystore");
+        // sizeof = 9, not strlen = 8
+        saltSize = sizeof("keystore");
+    }
+
+    const EVP_MD* digest = EVP_sha256();
+
+    // SHA1 was used prior to increasing the key size
+    if (key_len == kAes128KeySizeBytes) {
+        digest = EVP_sha1();
+    }
+
+    PKCS5_PBKDF2_HMAC(pw, pw_len, salt, saltSize, 8192, digest, key_len, key);
+}
+
+// New code.
+
+bool HKDFExtract(uint8_t* out_key, size_t* out_len, const uint8_t* secret, size_t secret_len,
+                 const uint8_t* salt, size_t salt_len) {
+    const EVP_MD* digest = EVP_sha256();
+    auto result = HKDF_extract(out_key, out_len, digest, secret, secret_len, salt, salt_len);
+    return result == 1;
+}
+
+bool HKDFExpand(uint8_t* out_key, size_t out_len, const uint8_t* prk, size_t prk_len,
+                const uint8_t* info, size_t info_len) {
+    const EVP_MD* digest = EVP_sha256();
+    auto result = HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len);
+    return result == 1;
+}
+
+int ECDHComputeKey(void* out, const EC_POINT* pub_key, const EC_KEY* priv_key) {
+    return ECDH_compute_key(out, EC_MAX_BYTES, pub_key, priv_key, nullptr);
+}
+
+EC_KEY* ECKEYGenerateKey() {
+    EC_KEY* key = EC_KEY_new();
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    EC_KEY_set_group(key, group);
+    auto result = EC_KEY_generate_key(key);
+    if (result == 0) {
+        EC_GROUP_free(group);
+        EC_KEY_free(key);
+        return nullptr;
+    }
+    return key;
+}
+
+size_t ECKEYMarshalPrivateKey(const EC_KEY* priv_key, uint8_t* buf, size_t len) {
+    CBB cbb;
+    size_t out_len;
+    if (!CBB_init_fixed(&cbb, buf, len) ||
+        !EC_KEY_marshal_private_key(&cbb, priv_key, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY) ||
+        !CBB_finish(&cbb, nullptr, &out_len)) {
+        return 0;
+    } else {
+        return out_len;
+    }
+}
+
+EC_KEY* ECKEYParsePrivateKey(const uint8_t* buf, size_t len) {
+    CBS cbs;
+    CBS_init(&cbs, buf, len);
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    auto result = EC_KEY_parse_private_key(&cbs, group);
+    EC_GROUP_free(group);
+    if (result != nullptr && CBS_len(&cbs) != 0) {
+        EC_KEY_free(result);
+        return nullptr;
+    }
+    return result;
+}
+
+size_t ECPOINTPoint2Oct(const EC_POINT* point, uint8_t* buf, size_t len) {
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
+    auto result = EC_POINT_point2oct(group, point, form, buf, len, nullptr);
+    EC_GROUP_free(group);
+    return result;
+}
+
+EC_POINT* ECPOINTOct2Point(const uint8_t* buf, size_t len) {
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    EC_POINT* point = EC_POINT_new(group);
+    auto result = EC_POINT_oct2point(group, point, buf, len, nullptr);
+    EC_GROUP_free(group);
+    if (result == 0) {
+        EC_POINT_free(point);
+        return nullptr;
+    }
+    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
new file mode 100644
index 0000000..f841eb3
--- /dev/null
+++ b/keystore2/src/crypto/crypto.hpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 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 __CRYPTO_H__
+#define __CRYPTO_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+
+extern "C" {
+  bool randomBytes(uint8_t* out, size_t len);
+  bool AES_gcm_encrypt(const uint8_t* in, uint8_t* out, size_t len,
+                       const uint8_t* key, size_t key_size, const uint8_t* iv, uint8_t* tag);
+  bool AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len,
+                       const uint8_t* key, size_t key_size, const uint8_t* iv,
+                       const uint8_t* tag);
+
+  // Copied from system/security/keystore/keymaster_enforcement.h.
+  typedef uint64_t km_id_t;
+
+  bool CreateKeyId(const uint8_t* key_blob, size_t len, km_id_t* out_id);
+
+  void generateKeyFromPassword(uint8_t* key, size_t key_len, const char* pw,
+                               size_t pw_len, const uint8_t* salt);
+
+  #include "openssl/digest.h"
+  #include "openssl/ec_key.h"
+
+  bool HKDFExtract(uint8_t *out_key, size_t *out_len,
+                   const uint8_t *secret, size_t secret_len,
+                   const uint8_t *salt, size_t salt_len);
+
+  bool HKDFExpand(uint8_t *out_key, size_t out_len,
+                  const uint8_t *prk, size_t prk_len,
+                  const uint8_t *info, size_t info_len);
+
+  // We define this as field_elem_size.
+  static const size_t EC_MAX_BYTES = 32;
+
+  int ECDHComputeKey(void *out, const EC_POINT *pub_key, const EC_KEY *priv_key);
+
+  EC_KEY* ECKEYGenerateKey();
+
+  size_t ECKEYMarshalPrivateKey(const EC_KEY *priv_key, uint8_t *buf, size_t len);
+
+  EC_KEY* ECKEYParsePrivateKey(const uint8_t *buf, size_t len);
+
+  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 subject is unknown, and because 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
new file mode 100644
index 0000000..a369012
--- /dev/null
+++ b/keystore2/src/crypto/error.rs
@@ -0,0 +1,96 @@
+// Copyright 2020, 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.
+
+//! This module implements Error for the keystore2_crypto library.
+
+/// Crypto specific error codes.
+#[derive(Debug, thiserror::Error, Eq, PartialEq)]
+pub enum Error {
+    /// This is returned if the C/C++ implementation of AES_gcm_decrypt returned false.
+    #[error("Failed to decrypt.")]
+    DecryptionFailed,
+
+    /// This is returned if the C/C++ implementation of AES_gcm_encrypt returned false.
+    #[error("Failed to encrypt.")]
+    EncryptionFailed,
+
+    /// The initialization vector has the wrong length.
+    #[error("Invalid IV length.")]
+    InvalidIvLength,
+
+    /// The aead tag has the wrong length.
+    #[error("Invalid AEAD tag length.")]
+    InvalidAeadTagLength,
+
+    /// The key has the wrong length.
+    #[error("Invalid key length.")]
+    InvalidKeyLength,
+
+    /// Invalid data length.
+    #[error("Invalid data length.")]
+    InvalidDataLength,
+
+    /// Invalid salt length.
+    #[error("Invalid salt length.")]
+    InvalidSaltLength,
+
+    /// Random number generation failed.
+    #[error("Random number generation failed.")]
+    RandomNumberGenerationFailed,
+
+    /// ZVec construction failed.
+    #[error(transparent)]
+    LayoutError(#[from] std::alloc::LayoutErr),
+
+    /// Nix error.
+    #[error(transparent)]
+    NixError(#[from] nix::Error),
+
+    /// This is returned if the C implementation of HKDFExtract returned false
+    /// or otherwise failed.
+    #[error("Failed to extract.")]
+    HKDFExtractFailed,
+
+    /// This is returned if the C implementation of HKDFExpand returned false.
+    #[error("Failed to expand.")]
+    HKDFExpandFailed,
+
+    /// This is returned if the C implementation of ECDHComputeKey returned -1.
+    #[error("Failed to compute ecdh key.")]
+    ECDHComputeKeyFailed,
+
+    /// This is returned if the C implementation of ECKEYGenerateKey returned null.
+    #[error("Failed to generate key.")]
+    ECKEYGenerateKeyFailed,
+
+    /// This is returned if the C implementation of ECKEYMarshalPrivateKey returned 0.
+    #[error("Failed to marshal private key.")]
+    ECKEYMarshalPrivateKeyFailed,
+
+    /// This is returned if the C implementation of ECKEYParsePrivateKey returned null.
+    #[error("Failed to parse private key.")]
+    ECKEYParsePrivateKeyFailed,
+
+    /// This is returned if the C implementation of ECPOINTPoint2Oct returned 0.
+    #[error("Failed to convert point to oct.")]
+    ECPoint2OctFailed,
+
+    /// 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/include/certificate_utils.h b/keystore2/src/crypto/include/certificate_utils.h
new file mode 100644
index 0000000..6c25b9a
--- /dev/null
+++ b/keystore2/src/crypto/include/certificate_utils.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2020, 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.
+ */
+
+#pragma once
+
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <stdint.h>
+
+#include <memory>
+#include <optional>
+#include <variant>
+
+namespace keystore {
+// We use boringssl error codes. Error codes that we add are folded into LIB_USER.
+// The CertificateUtilsInternallErrorCodes enum should not be used by callers, instead use the
+// BoringSslError constant definitions below for error codes.
+using BoringSslError = unsigned long;
+
+#define DEFINE_OPENSSL_OBJECT_POINTER(name) using name##_Ptr = bssl::UniquePtr<name>
+
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_BIT_STRING);
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_STRING);
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_INTEGER);
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_OCTET_STRING);
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_TIME);
+DEFINE_OPENSSL_OBJECT_POINTER(EVP_PKEY);
+DEFINE_OPENSSL_OBJECT_POINTER(X509);
+DEFINE_OPENSSL_OBJECT_POINTER(X509_EXTENSION);
+DEFINE_OPENSSL_OBJECT_POINTER(X509_NAME);
+DEFINE_OPENSSL_OBJECT_POINTER(EVP_PKEY_CTX);
+
+class CertUtilsError {
+  public:
+    enum Error {
+        Ok = 0,
+        BoringSsl,
+        Encoding,
+        MemoryAllocation,
+        InvalidArgument,
+        UnexpectedNullPointer,
+        SignatureFailed,
+    };
+
+  private:
+    Error e_;
+
+  public:
+    constexpr CertUtilsError(Error e) : e_(e) {}
+    explicit constexpr operator bool() const { return e_ != Ok; }
+};
+
+struct KeyUsageExtension {
+    bool isSigningKey;
+    bool isEncryptionKey;
+    bool isCertificationKey;
+};
+
+struct BasicConstraintsExtension {
+    bool isCa;
+    std::optional<int> pathLength;
+};
+
+/**
+ * This function allocates and prepares an X509 certificate structure with all of the information
+ * given. Next steps would be to set an Issuer with `setIssuer` and sign it with either
+ * `signCert` or `signCertWith`.
+ * @param evp_pkey The public key that the certificate is issued for.
+ * @param serial The certificate serial number.
+ * @param subject The X509 name encoded subject common name.
+ * @param activeDateTimeMilliSeconds The not before date in epoch milliseconds.
+ * @param usageExpireDateTimeMilliSeconds The not after date in epoch milliseconds.
+ * @param addSubjectKeyIdEx If true, adds the subject key id extension.
+ * @param keyUsageEx If given adds, the key usage extension with the given flags.
+ * @param basicConstraints If given, adds the basic constraints extension with the given data.
+ * @return CertUtilsError::Ok on success.
+ */
+std::variant<CertUtilsError, X509_Ptr>
+makeCert(const EVP_PKEY* evp_pkey,                                                   //
+         std::optional<std::reference_wrapper<const std::vector<uint8_t>>> serial,   //
+         std::optional<std::reference_wrapper<const std::vector<uint8_t>>> subject,  //
+         const int64_t activeDateTimeMilliSeconds,                                   //
+         const int64_t usageExpireDateTimeMilliSeconds,                              //
+         bool addSubjectKeyIdEx,                                                     //
+         std::optional<KeyUsageExtension> keyUsageEx,                                //
+         std::optional<BasicConstraintsExtension> basicConstraints);                 //
+
+/**
+ * Takes the subject name from `signingCert` and sets it as issuer name in `cert`.
+ * if `addAuthKeyExt` is true it also generates the digest of the signing certificates's public key
+ * and sets it as authority key id extension in `cert`.
+ * For self signed certificates pass the same pointer to both `cert` and `signingCert`.
+ *
+ * @param cert
+ * @param signingCert
+ * @param addAuthKeyExt
+ * @return CertUtilsError::Ok on success.
+ */
+CertUtilsError setIssuer(X509* cert, const X509* signingCert, bool addAuthKeyExt);
+
+/**
+ * Takes a certificate, and private signing_key.
+ * Signs the certificate with the latter.
+ */
+CertUtilsError signCert(X509* certificate, EVP_PKEY* signing_key);
+
+enum class Digest {
+    SHA1,
+    SHA224,
+    SHA256,
+    SHA384,
+    SHA512,
+};
+
+enum class Algo {
+    ECDSA,
+    RSA,
+};
+
+enum class Padding {
+    Ignored,
+    PKCS1_5,
+    PSS,
+};
+
+/**
+ * Sets the signature specifier of the certificate and the signature according to the parameters
+ * c. Then it signs the certificate with the `sign` callback.
+ * IMPORTANT: The parameters `algo`, `padding`, and `digest` do not control the actual signing
+ * algorithm. The caller is responsible to provide a callback that actually performs the signature
+ * as described by this triplet.
+ * The `padding` argument is ignored if `algo` is Algo::EC.
+ * The `digest` field controls the message digest used, and, in case of RSA with PSS padding,
+ *              also the MGF1 digest.
+ *
+ * @param certificate X509 certificate structure to be signed.
+ * @param sign Callback function used to digest and sign the DER encoded to-be-signed certificate.
+ * @param algo Algorithm specifier used to encode the signing algorithm id of the X509 certificate.
+ * @param padding Padding specifier used to encode the signing algorithm id of the X509 certificate.
+ * @param digest Digest specifier used to encode the signing algorithm id of the X509 certificate.
+ * @return CertUtilsError::Ok on success.
+ */
+CertUtilsError signCertWith(X509* certificate,
+                            std::function<std::vector<uint8_t>(const uint8_t*, size_t)> sign,
+                            Algo algo, Padding padding, Digest digest);
+
+/**
+ * Generates the DER representation of the given signed X509 certificate structure.
+ * @param certificate
+ * @return std::vector<uint8_t> with the DER encoded certificate on success. An error code
+ *         otherwise.
+ */
+std::variant<CertUtilsError, std::vector<uint8_t>> encodeCert(X509* certificate);
+
+}  // namespace keystore
diff --git a/keystore2/src/crypto/lib.rs b/keystore2/src/crypto/lib.rs
new file mode 100644
index 0000000..db23d1f
--- /dev/null
+++ b/keystore2/src/crypto/lib.rs
@@ -0,0 +1,568 @@
+// Copyright 2020, 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.
+
+//! This module implements safe wrappers for some crypto operations required by
+//! Keystore 2.0.
+
+mod error;
+mod zvec;
+pub use error::Error;
+use keystore2_crypto_bindgen::{
+    extractSubjectFromCertificate, generateKeyFromPassword, randomBytes, AES_gcm_decrypt,
+    AES_gcm_encrypt, ECDHComputeKey, ECKEYGenerateKey, ECKEYMarshalPrivateKey,
+    ECKEYParsePrivateKey, 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;
+
+/// Length of the expected initialization vector.
+pub const GCM_IV_LENGTH: usize = 12;
+/// Length of the expected AEAD TAG.
+pub const TAG_LENGTH: usize = 16;
+/// Length of an AES 256 key in bytes.
+pub const AES_256_KEY_LENGTH: usize = 32;
+/// Length of an AES 128 key in bytes.
+pub const AES_128_KEY_LENGTH: usize = 16;
+/// Length of the expected salt for key from password generation.
+pub const SALT_LENGTH: usize = 16;
+
+/// Older versions of keystore produced IVs with four extra
+/// ignored zero bytes at the end; recognise and trim those.
+pub const LEGACY_IV_LENGTH: usize = 16;
+
+/// Generate an AES256 key, essentially 32 random bytes from the underlying
+/// boringssl library discretely stuffed into a ZVec.
+pub fn generate_aes256_key() -> Result<ZVec, Error> {
+    // Safety: key has the same length as the requested number of random bytes.
+    let mut key = ZVec::new(AES_256_KEY_LENGTH)?;
+    if unsafe { randomBytes(key.as_mut_ptr(), AES_256_KEY_LENGTH) } {
+        Ok(key)
+    } else {
+        Err(Error::RandomNumberGenerationFailed)
+    }
+}
+
+/// Generate a salt.
+pub fn generate_salt() -> Result<Vec<u8>, Error> {
+    generate_random_data(SALT_LENGTH)
+}
+
+/// Generate random data of the given size.
+pub fn generate_random_data(size: usize) -> Result<Vec<u8>, Error> {
+    // Safety: data has the same length as the requested number of random bytes.
+    let mut data = vec![0; size];
+    if unsafe { randomBytes(data.as_mut_ptr(), size) } {
+        Ok(data)
+    } else {
+        Err(Error::RandomNumberGenerationFailed)
+    }
+}
+
+/// Uses AES GCM to decipher a message given an initialization vector, aead tag, and key.
+/// This function accepts 128 and 256-bit keys and uses AES128 and AES256 respectively based
+/// on the key length.
+/// This function returns the plaintext message in a ZVec because it is assumed that
+/// it contains sensitive information that should be zeroed from memory before its buffer is
+/// freed. Input key is taken as a slice for flexibility, but it is recommended that it is held
+/// in a ZVec as well.
+pub fn aes_gcm_decrypt(data: &[u8], iv: &[u8], tag: &[u8], key: &[u8]) -> Result<ZVec, Error> {
+    // Old versions of aes_gcm_encrypt produced 16 byte IVs, but the last four bytes were ignored
+    // so trim these to the correct size.
+    let iv = match iv.len() {
+        GCM_IV_LENGTH => iv,
+        LEGACY_IV_LENGTH => &iv[..GCM_IV_LENGTH],
+        _ => return Err(Error::InvalidIvLength),
+    };
+    if tag.len() != TAG_LENGTH {
+        return Err(Error::InvalidAeadTagLength);
+    }
+
+    match key.len() {
+        AES_128_KEY_LENGTH | AES_256_KEY_LENGTH => {}
+        _ => return Err(Error::InvalidKeyLength),
+    }
+
+    let mut result = ZVec::new(data.len())?;
+
+    // Safety: The first two arguments must point to buffers with a size given by the third
+    // argument. We pass the length of the key buffer along with the key.
+    // The `iv` buffer must be 12 bytes and the `tag` buffer 16, which we check above.
+    match unsafe {
+        AES_gcm_decrypt(
+            data.as_ptr(),
+            result.as_mut_ptr(),
+            data.len(),
+            key.as_ptr(),
+            key.len(),
+            iv.as_ptr(),
+            tag.as_ptr(),
+        )
+    } {
+        true => Ok(result),
+        false => Err(Error::DecryptionFailed),
+    }
+}
+
+/// Uses AES GCM to encrypt a message given a key.
+/// This function accepts 128 and 256-bit keys and uses AES128 and AES256 respectively based on
+/// the key length. The function generates an initialization vector. The return value is a tuple
+/// of `(ciphertext, iv, tag)`.
+pub fn aes_gcm_encrypt(plaintext: &[u8], key: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>), Error> {
+    let mut iv = vec![0; GCM_IV_LENGTH];
+    // Safety: iv is GCM_IV_LENGTH bytes long.
+    if !unsafe { randomBytes(iv.as_mut_ptr(), GCM_IV_LENGTH) } {
+        return Err(Error::RandomNumberGenerationFailed);
+    }
+
+    match key.len() {
+        AES_128_KEY_LENGTH | AES_256_KEY_LENGTH => {}
+        _ => return Err(Error::InvalidKeyLength),
+    }
+
+    let mut ciphertext: Vec<u8> = vec![0; plaintext.len()];
+    let mut tag: Vec<u8> = vec![0; TAG_LENGTH];
+    // Safety: The first two arguments must point to buffers with a size given by the third
+    // argument. We pass the length of the key buffer along with the key.
+    // The `iv` buffer must be 12 bytes and the `tag` buffer 16, which we check above.
+    if unsafe {
+        AES_gcm_encrypt(
+            plaintext.as_ptr(),
+            ciphertext.as_mut_ptr(),
+            plaintext.len(),
+            key.as_ptr(),
+            key.len(),
+            iv.as_ptr(),
+            tag.as_mut_ptr(),
+        )
+    } {
+        Ok((ciphertext, iv, tag))
+    } else {
+        Err(Error::EncryptionFailed)
+    }
+}
+
+/// Represents a "password" that can be used to key the PBKDF2 algorithm.
+pub enum Password<'a> {
+    /// Borrow an existing byte array
+    Ref(&'a [u8]),
+    /// Use an owned ZVec to store the key
+    Owned(ZVec),
+}
+
+impl<'a> From<&'a [u8]> for Password<'a> {
+    fn from(pw: &'a [u8]) -> Self {
+        Self::Ref(pw)
+    }
+}
+
+impl<'a> Password<'a> {
+    fn get_key(&'a self) -> &'a [u8] {
+        match self {
+            Self::Ref(b) => b,
+            Self::Owned(z) => &*z,
+        }
+    }
+
+    /// Generate a key from the given password and salt.
+    /// The salt must be exactly 16 bytes long.
+    /// Two key sizes are accepted: 16 and 32 bytes.
+    pub fn derive_key(&self, salt: Option<&[u8]>, key_length: usize) -> Result<ZVec, Error> {
+        let pw = self.get_key();
+
+        let salt: *const u8 = match salt {
+            Some(s) => {
+                if s.len() != SALT_LENGTH {
+                    return Err(Error::InvalidSaltLength);
+                }
+                s.as_ptr()
+            }
+            None => std::ptr::null(),
+        };
+
+        match key_length {
+            AES_128_KEY_LENGTH | AES_256_KEY_LENGTH => {}
+            _ => return Err(Error::InvalidKeyLength),
+        }
+
+        let mut result = ZVec::new(key_length)?;
+
+        unsafe {
+            generateKeyFromPassword(
+                result.as_mut_ptr(),
+                result.len(),
+                pw.as_ptr() as *const std::os::raw::c_char,
+                pw.len(),
+                salt,
+            )
+        };
+
+        Ok(result)
+    }
+
+    /// Try to make another Password object with the same data.
+    pub fn try_clone(&self) -> Result<Password<'static>, Error> {
+        Ok(Password::Owned(ZVec::try_from(self.get_key())?))
+    }
+}
+
+/// Calls the boringssl HKDF_extract function.
+pub fn hkdf_extract(secret: &[u8], salt: &[u8]) -> Result<ZVec, Error> {
+    let max_size: usize = EVP_MAX_MD_SIZE.try_into().unwrap();
+    let mut buf = ZVec::new(max_size)?;
+    let mut out_len = 0;
+    // Safety: HKDF_extract writes at most EVP_MAX_MD_SIZE bytes.
+    // Secret and salt point to valid buffers.
+    let result = unsafe {
+        HKDFExtract(
+            buf.as_mut_ptr(),
+            &mut out_len,
+            secret.as_ptr(),
+            secret.len(),
+            salt.as_ptr(),
+            salt.len(),
+        )
+    };
+    if !result {
+        return Err(Error::HKDFExtractFailed);
+    }
+    // According to the boringssl API, this should never happen.
+    if out_len > max_size {
+        return Err(Error::HKDFExtractFailed);
+    }
+    // HKDF_extract may write fewer than the maximum number of bytes, so we
+    // truncate the buffer.
+    buf.reduce_len(out_len);
+    Ok(buf)
+}
+
+/// Calls the boringssl HKDF_expand function.
+pub fn hkdf_expand(out_len: usize, prk: &[u8], info: &[u8]) -> Result<ZVec, Error> {
+    let mut buf = ZVec::new(out_len)?;
+    // Safety: HKDF_expand writes out_len bytes to the buffer.
+    // prk and info are valid buffers.
+    let result = unsafe {
+        HKDFExpand(buf.as_mut_ptr(), out_len, prk.as_ptr(), prk.len(), info.as_ptr(), info.len())
+    };
+    if !result {
+        return Err(Error::HKDFExpandFailed);
+    }
+    Ok(buf)
+}
+
+/// A wrapper around the boringssl EC_KEY type that frees it on drop.
+pub struct ECKey(*mut EC_KEY);
+
+impl Drop for ECKey {
+    fn drop(&mut self) {
+        // Safety: We only create ECKey objects for valid EC_KEYs
+        // and they are the sole owners of those keys.
+        unsafe { EC_KEY_free(self.0) };
+    }
+}
+
+// Wrappers around the boringssl EC_POINT type.
+// The EC_POINT can either be owned (and therefore mutable) or a pointer to an
+// EC_POINT owned by someone else (and thus immutable).  The former are freed
+// on drop.
+
+/// An owned EC_POINT object.
+pub struct OwnedECPoint(*mut EC_POINT);
+
+/// A pointer to an EC_POINT object.
+pub struct BorrowedECPoint<'a> {
+    data: *const EC_POINT,
+    phantom: PhantomData<&'a EC_POINT>,
+}
+
+impl OwnedECPoint {
+    /// Get the wrapped EC_POINT object.
+    pub fn get_point(&self) -> &EC_POINT {
+        // Safety: We only create OwnedECPoint objects for valid EC_POINTs.
+        unsafe { self.0.as_ref().unwrap() }
+    }
+}
+
+impl<'a> BorrowedECPoint<'a> {
+    /// Get the wrapped EC_POINT object.
+    pub fn get_point(&self) -> &EC_POINT {
+        // Safety: We only create BorrowedECPoint objects for valid EC_POINTs.
+        unsafe { self.data.as_ref().unwrap() }
+    }
+}
+
+impl Drop for OwnedECPoint {
+    fn drop(&mut self) {
+        // Safety: We only create OwnedECPoint objects for valid
+        // EC_POINTs and they are the sole owners of those points.
+        unsafe { EC_POINT_free(self.0) };
+    }
+}
+
+/// Calls the boringssl ECDH_compute_key function.
+pub fn ecdh_compute_key(pub_key: &EC_POINT, priv_key: &ECKey) -> Result<ZVec, Error> {
+    let mut buf = ZVec::new(EC_MAX_BYTES)?;
+    // Safety: Our ECDHComputeKey wrapper passes EC_MAX_BYES to ECDH_compute_key, which
+    // writes at most that many bytes to the output.
+    // The two keys are valid objects.
+    let result =
+        unsafe { ECDHComputeKey(buf.as_mut_ptr() as *mut std::ffi::c_void, pub_key, priv_key.0) };
+    if result == -1 {
+        return Err(Error::ECDHComputeKeyFailed);
+    }
+    let out_len = result.try_into().unwrap();
+    // According to the boringssl API, this should never happen.
+    if out_len > buf.len() {
+        return Err(Error::ECDHComputeKeyFailed);
+    }
+    // ECDH_compute_key may write fewer than the maximum number of bytes, so we
+    // truncate the buffer.
+    buf.reduce_len(out_len);
+    Ok(buf)
+}
+
+/// Calls the boringssl EC_KEY_generate_key function.
+pub fn ec_key_generate_key() -> Result<ECKey, Error> {
+    // Safety: Creates a new key on its own.
+    let key = unsafe { ECKEYGenerateKey() };
+    if key.is_null() {
+        return Err(Error::ECKEYGenerateKeyFailed);
+    }
+    Ok(ECKey(key))
+}
+
+/// Calls the boringssl EC_KEY_marshal_private_key function.
+pub fn ec_key_marshal_private_key(key: &ECKey) -> Result<ZVec, Error> {
+    let len = 39; // Empirically observed length of private key
+    let mut buf = ZVec::new(len)?;
+    // Safety: the key is valid.
+    // This will not write past the specified length of the buffer; if the
+    // len above is too short, it returns 0.
+    let written_len =
+        unsafe { ECKEYMarshalPrivateKey(key.0, buf.as_mut_ptr(), buf.len()) } as usize;
+    if written_len == len {
+        Ok(buf)
+    } else {
+        Err(Error::ECKEYMarshalPrivateKeyFailed)
+    }
+}
+
+/// Calls the boringssl EC_KEY_parse_private_key function.
+pub fn ec_key_parse_private_key(buf: &[u8]) -> Result<ECKey, Error> {
+    // Safety: this will not read past the specified length of the buffer.
+    // It fails if less than the whole buffer is consumed.
+    let key = unsafe { ECKEYParsePrivateKey(buf.as_ptr(), buf.len()) };
+    if key.is_null() {
+        Err(Error::ECKEYParsePrivateKeyFailed)
+    } else {
+        Ok(ECKey(key))
+    }
+}
+
+/// Calls the boringssl EC_KEY_get0_public_key function.
+pub fn ec_key_get0_public_key(key: &ECKey) -> BorrowedECPoint {
+    // Safety: The key is valid.
+    // This returns a pointer to a key, so we create an immutable variant.
+    BorrowedECPoint { data: unsafe { EC_KEY_get0_public_key(key.0) }, phantom: PhantomData }
+}
+
+/// Calls the boringssl EC_POINT_point2oct.
+pub fn ec_point_point_to_oct(point: &EC_POINT) -> Result<Vec<u8>, Error> {
+    // We fix the length to 65 (1 + 2 * field_elem_size), as we get an error if it's too small.
+    let len = 65;
+    let mut buf = vec![0; len];
+    // Safety: EC_POINT_point2oct writes at most len bytes. The point is valid.
+    let result = unsafe { ECPOINTPoint2Oct(point, buf.as_mut_ptr(), len) };
+    if result == 0 {
+        return Err(Error::ECPoint2OctFailed);
+    }
+    // According to the boringssl API, this should never happen.
+    if result > len {
+        return Err(Error::ECPoint2OctFailed);
+    }
+    buf.resize(result, 0);
+    Ok(buf)
+}
+
+/// Calls the boringssl EC_POINT_oct2point function.
+pub fn ec_point_oct_to_point(buf: &[u8]) -> Result<OwnedECPoint, Error> {
+    // Safety: The buffer is valid.
+    let result = unsafe { ECPOINTOct2Point(buf.as_ptr(), buf.len()) };
+    if result.is_null() {
+        return Err(Error::ECPoint2OctFailed);
+    }
+    // Our C wrapper creates a new EC_POINT, so we mark this mutable and free
+    // it on drop.
+    Ok(OwnedECPoint(result))
+}
+
+/// Uses BoringSSL to extract the DER-encoded subject from a DER-encoded X.509 certificate.
+pub fn parse_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];
+
+    // Safety: extractSubjectFromCertificate reads at most cert_buf.len() bytes from cert_buf and
+    // writes at most retval.len() bytes to retval.
+    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).map_err(|_e| Error::ExtractSubjectFailed)?;
+        retval = vec![0; negated_size];
+
+        // Safety: extractSubjectFromCertificate reads at most cert_buf.len() bytes from cert_buf
+        // and writes at most retval.len() bytes to retval.
+        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).map_err(|_e| Error::ExtractSubjectFailed)?;
+    retval.truncate(safe_size);
+
+    Ok(retval)
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use keystore2_crypto_bindgen::{
+        generateKeyFromPassword, AES_gcm_decrypt, AES_gcm_encrypt, CreateKeyId,
+    };
+
+    #[test]
+    fn test_wrapper_roundtrip() {
+        let key = generate_aes256_key().unwrap();
+        let message = b"totally awesome message";
+        let (cipher_text, iv, tag) = aes_gcm_encrypt(message, &key).unwrap();
+        let message2 = aes_gcm_decrypt(&cipher_text, &iv, &tag, &key).unwrap();
+        assert_eq!(message[..], message2[..])
+    }
+
+    #[test]
+    fn test_encrypt_decrypt() {
+        let input = vec![0; 16];
+        let mut out = vec![0; 16];
+        let mut out2 = vec![0; 16];
+        let key = vec![0; 16];
+        let iv = vec![0; 12];
+        let mut tag = vec![0; 16];
+        unsafe {
+            let res = AES_gcm_encrypt(
+                input.as_ptr(),
+                out.as_mut_ptr(),
+                16,
+                key.as_ptr(),
+                16,
+                iv.as_ptr(),
+                tag.as_mut_ptr(),
+            );
+            assert!(res);
+            assert_ne!(out, input);
+            assert_ne!(tag, input);
+            let res = AES_gcm_decrypt(
+                out.as_ptr(),
+                out2.as_mut_ptr(),
+                16,
+                key.as_ptr(),
+                16,
+                iv.as_ptr(),
+                tag.as_ptr(),
+            );
+            assert!(res);
+            assert_eq!(out2, input);
+        }
+    }
+
+    #[test]
+    fn test_create_key_id() {
+        let blob = vec![0; 16];
+        let mut out: u64 = 0;
+        unsafe {
+            let res = CreateKeyId(blob.as_ptr(), 16, &mut out);
+            assert!(res);
+            assert_ne!(out, 0);
+        }
+    }
+
+    #[test]
+    fn test_generate_key_from_password() {
+        let mut key = vec![0; 16];
+        let pw = vec![0; 16];
+        let mut salt = vec![0; 16];
+        unsafe {
+            generateKeyFromPassword(key.as_mut_ptr(), 16, pw.as_ptr(), 16, salt.as_mut_ptr());
+        }
+        assert_ne!(key, vec![0; 16]);
+    }
+
+    #[test]
+    fn test_hkdf() {
+        let result = hkdf_extract(&[0; 16], &[0; 16]);
+        assert!(result.is_ok());
+        for out_len in 4..=8 {
+            let result = hkdf_expand(out_len, &[0; 16], &[0; 16]);
+            assert!(result.is_ok());
+            assert_eq!(result.unwrap().len(), out_len);
+        }
+    }
+
+    #[test]
+    fn test_ec() -> Result<(), Error> {
+        let priv0 = ec_key_generate_key()?;
+        assert!(!priv0.0.is_null());
+        let pub0 = ec_key_get0_public_key(&priv0);
+
+        let priv1 = ec_key_generate_key()?;
+        let pub1 = ec_key_get0_public_key(&priv1);
+
+        let priv0s = ec_key_marshal_private_key(&priv0)?;
+        let pub0s = ec_point_point_to_oct(pub0.get_point())?;
+        let pub1s = ec_point_point_to_oct(pub1.get_point())?;
+
+        let priv0 = ec_key_parse_private_key(&priv0s)?;
+        let pub0 = ec_point_oct_to_point(&pub0s)?;
+        let pub1 = ec_point_oct_to_point(&pub1s)?;
+
+        let left_key = ecdh_compute_key(pub0.get_point(), &priv1)?;
+        let right_key = ecdh_compute_key(pub1.get_point(), &priv0)?;
+
+        assert_eq!(left_key, right_key);
+        Ok(())
+    }
+}
diff --git a/keystore2/src/crypto/tests/certificate_utils_test.cpp b/keystore2/src/crypto/tests/certificate_utils_test.cpp
new file mode 100644
index 0000000..119c3fa
--- /dev/null
+++ b/keystore2/src/crypto/tests/certificate_utils_test.cpp
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2020, 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 <gtest/gtest.h>
+
+#include "certificate_utils.h"
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <variant>
+
+#include "test_keys.h"
+
+using namespace keystore;
+
+// I leave these here in case they are needed for debugging.
+namespace debug_utils {
+
+void log_ssl_error() {
+    unsigned long error = ERR_peek_last_error();
+
+    char buf[128];
+    ERR_error_string_n(error, buf, sizeof(buf));
+    std::cout << "BoringSslError: " << buf << std::endl;
+}
+
+std::string hexdump(const std::vector<uint8_t>& data) {
+    std::stringstream s;
+    size_t column_count = 0;
+    for (auto& c : data) {
+        s << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)c;
+        if (++column_count % 40 == 0) s << "\n";
+    }
+    return s.str();
+}
+
+}  // namespace debug_utils
+
+constexpr uint64_t kValidity = 24 * 60 * 60 * 1000;  // 24 hours in milliseconds
+
+const EVP_MD* getMD(Digest digest) {
+    switch (digest) {
+    case Digest::SHA1:
+        return EVP_sha1();
+    case Digest::SHA224:
+        return EVP_sha224();
+    case Digest::SHA256:
+        return EVP_sha256();
+    case Digest::SHA384:
+        return EVP_sha384();
+    case Digest::SHA512:
+        return EVP_sha512();
+    }
+}
+
+std::array<Digest, 5> digests = {
+    Digest::SHA1, Digest::SHA224, Digest::SHA256, Digest::SHA384, Digest::SHA512,
+};
+
+static const char* toString(Digest d) {
+    switch (d) {
+    case Digest::SHA1:
+        return "SHA1";
+    case Digest::SHA224:
+        return "SHA224";
+    case Digest::SHA256:
+        return "SHA256";
+    case Digest::SHA384:
+        return "SHA384";
+    case Digest::SHA512:
+        return "SHA512";
+    }
+}
+
+std::array<Padding, 2> rsa_paddings = {
+    Padding::PSS,
+    Padding::PKCS1_5,
+};
+
+enum class EcCurve {
+    P224,
+    P256,
+    P384,
+    P521,
+};
+
+std::array<int, 4> ec_curves = {
+    NID_secp224r1,
+    NID_X9_62_prime256v1,
+    NID_secp384r1,
+    NID_secp521r1,
+};
+
+static const char* curveNidToString(int nid) {
+    switch (nid) {
+    case NID_secp224r1:
+        return "P224";
+    case NID_X9_62_prime256v1:
+        return "P256";
+    case NID_secp384r1:
+        return "P384";
+    case NID_secp521r1:
+        return "P521";
+    default:
+        return "Unknown";
+    }
+}
+
+std::array<long, 2> rsa_key_sizes = {
+    2048,
+    4096,
+};
+
+using EcParam = std::tuple<int /* EC curve NID */, Digest>;
+
+class CertificateUtilsWithEcCurve : public testing::TestWithParam<EcParam> {};
+
+static std::string paramToStringEc(testing::TestParamInfo<EcParam> param) {
+    std::stringstream s;
+    auto [curve_nid, digest] = param.param;
+    s << param.index << "_" << curveNidToString(curve_nid) << "_" << toString(digest);
+    return s.str();
+}
+
+INSTANTIATE_TEST_SUITE_P(CertSigningWithCallbackEC, CertificateUtilsWithEcCurve,
+                         testing::Combine(testing::ValuesIn(ec_curves), testing::ValuesIn(digests)),
+                         paramToStringEc);
+
+TEST_P(CertificateUtilsWithEcCurve, CertSigningWithCallbackEC) {
+    // Structured decomposition (e.g.: auto [a, b, c] = ...) does not work here because
+    // names bound this way cannot be captured in lambda expressions so we use std::tie instead.
+    int curve_nid;
+    Digest digest;
+    std::tie(curve_nid, digest) = GetParam();
+    EVP_PKEY_CTX_Ptr pkey_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL));
+    ASSERT_TRUE((bool)pkey_ctx);
+    ASSERT_TRUE(EVP_PKEY_keygen_init(pkey_ctx.get()));
+    ASSERT_TRUE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pkey_ctx.get(), curve_nid));
+
+    EVP_PKEY* pkey_ptr = nullptr;
+    ASSERT_TRUE(EVP_PKEY_keygen(pkey_ctx.get(), &pkey_ptr));
+    EVP_PKEY_Ptr pkey(pkey_ptr);
+    ASSERT_TRUE(pkey);
+
+    uint64_t now_ms = (uint64_t)time(nullptr) * 1000;
+
+    BasicConstraintsExtension bcons{
+        .isCa = true,
+        .pathLength = {},
+    };
+
+    KeyUsageExtension keyUsage{
+        .isSigningKey = true,
+        .isEncryptionKey = false,
+        .isCertificationKey = true,
+    };
+
+    auto certV = makeCert(pkey.get(), std::nullopt, std::nullopt, now_ms - kValidity,
+                          now_ms + kValidity, true /* subject key id extension */, keyUsage, bcons);
+    ASSERT_TRUE(std::holds_alternative<X509_Ptr>(certV));
+    auto& cert = std::get<X509_Ptr>(certV);
+    ASSERT_TRUE(!setIssuer(cert.get(), cert.get(), true));
+
+    ASSERT_TRUE(!signCertWith(
+        cert.get(),
+        [&](const uint8_t* data, size_t len) {
+            bssl::ScopedEVP_MD_CTX sign_ctx;
+            EXPECT_TRUE(
+                EVP_DigestSignInit(sign_ctx.get(), nullptr, getMD(digest), nullptr, pkey.get()));
+
+            std::vector<uint8_t> sig_buf(512);
+            size_t sig_len = 512;
+            EVP_DigestSign(sign_ctx.get(), sig_buf.data(), &sig_len, data, len);
+            sig_buf.resize(sig_len);
+            return sig_buf;
+        },
+        Algo::ECDSA, Padding::Ignored, digest));
+
+    auto encCertV = encodeCert(cert.get());
+    ASSERT_TRUE(std::holds_alternative<std::vector<uint8_t>>(encCertV));
+
+    auto& encCert = std::get<1>(encCertV);
+    // Uncomment the next line to dump the DER encoded signed certificate as hex string.
+    // You can pipe this dump into  "xxd -r -p | openssl x509 -inform der -text -noout"
+    // to inspect the certificate.
+    // std::cout << "DER encoded cert:\n" << debug_utils::hexdump(encCert) << std::endl;
+
+    const uint8_t* p = encCert.data();
+    X509_Ptr decoded_cert(d2i_X509(nullptr, &p, (long)encCert.size()));
+    EVP_PKEY_Ptr decoded_pkey(X509_get_pubkey(decoded_cert.get()));
+    ASSERT_TRUE(X509_verify(decoded_cert.get(), decoded_pkey.get()));
+}
+
+using RsaParams = std::tuple<long /* key size */, Padding, Digest>;
+
+class CertificateUtilsWithRsa : public testing::TestWithParam<RsaParams> {};
+
+static std::string paramsToStringRsa(testing::TestParamInfo<RsaParams> param) {
+    std::stringstream s;
+    auto [key_size, padding, digest] = param.param;
+    s << param.index << "_" << key_size << "_";
+    switch (padding) {
+    case Padding::PSS:
+        s << "PSS";
+        break;
+    case Padding::PKCS1_5:
+        s << "PKCS1_5";
+        break;
+    case Padding::Ignored:
+        s << "Ignored";
+    }
+    s << "_" << toString(digest);
+    return s.str();
+}
+
+INSTANTIATE_TEST_SUITE_P(CertSigningWithCallbackRsa, CertificateUtilsWithRsa,
+                         testing::Combine(testing::ValuesIn(rsa_key_sizes),
+                                          testing::ValuesIn(rsa_paddings),
+                                          testing::ValuesIn(digests)),
+                         paramsToStringRsa);
+
+TEST_P(CertificateUtilsWithRsa, CertSigningWithCallbackRsa) {
+    // Structured decomposition (e.g.: auto [a, b, c] = ...) does not work here because
+    // names bound this way cannot be captured in lambda expressions so we use std::tie instead.
+    long key_size;
+    Padding padding;
+    Digest digest;
+    std::tie(key_size, padding, digest) = GetParam();
+
+    CBS cbs;
+    switch (key_size) {
+    case 2048:
+        CBS_init(&cbs, rsa_key_2k, rsa_key_2k_len);
+        break;
+    case 4096:
+        CBS_init(&cbs, rsa_key_4k, rsa_key_4k_len);
+        break;
+    default:
+        FAIL();
+    }
+    EVP_PKEY_Ptr pkey(EVP_parse_private_key(&cbs));
+    ASSERT_TRUE(pkey);
+
+    uint64_t now_ms = (uint64_t)time(nullptr) * 1000;
+
+    BasicConstraintsExtension bcons{
+        .isCa = true,
+        .pathLength = 0,
+    };
+
+    KeyUsageExtension keyUsage{
+        .isSigningKey = true,
+        .isEncryptionKey = false,
+        .isCertificationKey = true,
+    };
+
+    auto certV = makeCert(pkey.get(), std::nullopt, std::nullopt, now_ms - kValidity,
+                          now_ms + kValidity, true /* subject key id extension */, keyUsage, bcons);
+    ASSERT_TRUE(std::holds_alternative<X509_Ptr>(certV));
+    auto& cert = std::get<X509_Ptr>(certV);
+    ASSERT_TRUE(!setIssuer(cert.get(), cert.get(), true));
+
+    ASSERT_TRUE(!signCertWith(
+        cert.get(),
+        [&](const uint8_t* data, size_t len) {
+            bssl::ScopedEVP_MD_CTX sign_ctx;
+            EVP_PKEY_CTX* pkey_sign_ctx_ptr;
+            EXPECT_TRUE(EVP_DigestSignInit(sign_ctx.get(), &pkey_sign_ctx_ptr, getMD(digest),
+                                           nullptr, pkey.get()));
+
+            if (padding == Padding::PSS) {
+                EXPECT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_sign_ctx_ptr, RSA_PKCS1_PSS_PADDING));
+                EXPECT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_sign_ctx_ptr, -1));
+            } else {
+                EXPECT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_sign_ctx_ptr, RSA_PKCS1_PADDING));
+            }
+
+            std::vector<uint8_t> sig_buf(1024);
+            size_t sig_len = 1024;
+            EVP_DigestSign(sign_ctx.get(), sig_buf.data(), &sig_len, data, len);
+            sig_buf.resize(sig_len);
+            return sig_buf;
+        },
+        Algo::RSA, padding, digest));
+
+    auto encCertV = encodeCert(cert.get());
+    ASSERT_TRUE(std::holds_alternative<std::vector<uint8_t>>(encCertV));
+
+    auto& encCert = std::get<1>(encCertV);
+    // Uncomment the next line to dump the DER encoded signed certificate as hex string.
+    // You can pipe this dump into  "xxd -r -p | openssl x509 -inform der -text -noout"
+    // to inspect the certificate.
+    // std::cout << "DER encoded cert:\n" << debug_utils::hexdump(encCert) << std::endl;
+
+    const uint8_t* p = encCert.data();
+    X509_Ptr decoded_cert(d2i_X509(nullptr, &p, (long)encCert.size()));
+    EVP_PKEY_Ptr decoded_pkey(X509_get_pubkey(decoded_cert.get()));
+    ASSERT_TRUE(X509_verify(decoded_cert.get(), decoded_pkey.get()));
+}
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/keystore2/src/crypto/tests/gtest_main.cpp
similarity index 74%
copy from keystore/binder/android/security/keymaster/OperationResult.aidl
copy to keystore2/src/crypto/tests/gtest_main.cpp
index db689d4..149cbbc 100644
--- a/keystore/binder/android/security/keymaster/OperationResult.aidl
+++ b/keystore2/src/crypto/tests/gtest_main.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-package android.security.keymaster;
-
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
+#include <gtest/gtest.h>
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/keystore2/src/crypto/tests/test_keys.h b/keystore2/src/crypto/tests/test_keys.h
new file mode 100644
index 0000000..d3b1175
--- /dev/null
+++ b/keystore2/src/crypto/tests/test_keys.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2020, 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.
+ */
+
+#pragma once
+
+constexpr const unsigned char rsa_key_4k[] = {
+    0x30, 0x82, 0x09, 0x41, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x09, 0x2b, 0x30, 0x82, 0x09, 0x27, 0x02, 0x01,
+    0x00, 0x02, 0x82, 0x02, 0x01, 0x00, 0xac, 0x07, 0x4e, 0xc6, 0x20, 0xb9, 0x78, 0x03, 0xd0, 0x53,
+    0x22, 0xa4, 0xef, 0x6d, 0xd1, 0x7a, 0x7e, 0x5e, 0x5e, 0x1d, 0xe7, 0x9b, 0x30, 0x31, 0x99, 0xe8,
+    0x1c, 0xdf, 0x32, 0x0c, 0xdb, 0xdb, 0xc2, 0x4c, 0x22, 0x10, 0x71, 0xd0, 0x76, 0x83, 0xb0, 0x50,
+    0x66, 0xa4, 0x43, 0x75, 0xe8, 0x46, 0xde, 0x58, 0x9e, 0x31, 0x82, 0x81, 0x8c, 0x36, 0x20, 0xbb,
+    0x42, 0xcd, 0xb9, 0x21, 0x29, 0x67, 0x39, 0x4d, 0x2a, 0x1c, 0xc2, 0x89, 0x48, 0x23, 0x5f, 0xdd,
+    0x60, 0xc4, 0x04, 0x42, 0xbe, 0x6f, 0x01, 0xa5, 0xf8, 0xac, 0xba, 0x27, 0xd1, 0x87, 0x08, 0x6b,
+    0xe6, 0x1b, 0xfc, 0xba, 0xff, 0x7e, 0xc9, 0xaf, 0x76, 0x28, 0xe8, 0x93, 0x2c, 0xbf, 0x6f, 0xed,
+    0xf3, 0x6f, 0x21, 0xc1, 0xe7, 0x56, 0xf5, 0x15, 0x56, 0xa8, 0xa1, 0xfd, 0xb7, 0xb3, 0x8c, 0x3d,
+    0x1f, 0xf3, 0x80, 0xea, 0x79, 0xff, 0x0c, 0xc6, 0xb6, 0x59, 0xa0, 0x3f, 0x13, 0xb0, 0x4f, 0xb3,
+    0x1c, 0xe1, 0x2a, 0xa5, 0x45, 0x02, 0x51, 0xa3, 0x74, 0x15, 0xee, 0xf0, 0xca, 0xba, 0x7d, 0xca,
+    0xc6, 0x87, 0xd6, 0x12, 0x9b, 0xbb, 0x4b, 0x86, 0xc7, 0xcb, 0x88, 0xc6, 0x10, 0xee, 0x34, 0x51,
+    0x4b, 0xe9, 0x9d, 0xbb, 0x59, 0x03, 0xff, 0xbf, 0x98, 0x0a, 0xfd, 0xf2, 0xd0, 0x06, 0x0e, 0x51,
+    0xd1, 0xbb, 0x8b, 0xbd, 0xca, 0x26, 0x4d, 0x05, 0x0e, 0xee, 0x82, 0x0f, 0xf6, 0x38, 0x46, 0x2a,
+    0x7f, 0xfd, 0x37, 0xe6, 0xcf, 0xaa, 0x6a, 0x84, 0xbc, 0xa7, 0xd2, 0x06, 0x29, 0x49, 0x4c, 0xd2,
+    0x28, 0xd4, 0x48, 0x09, 0xfc, 0x91, 0x1e, 0xb0, 0x06, 0xf9, 0x5b, 0xbe, 0xd9, 0xb8, 0x01, 0xec,
+    0x3a, 0xc3, 0xa2, 0x1d, 0x89, 0x0b, 0x22, 0xf8, 0xf0, 0x8e, 0x95, 0xe0, 0x3d, 0x5b, 0x80, 0x38,
+    0x21, 0x80, 0x10, 0x04, 0x54, 0xaa, 0xa5, 0x81, 0x8b, 0x47, 0x73, 0x54, 0xcb, 0x06, 0xa9, 0x01,
+    0xf5, 0x57, 0x72, 0xdd, 0x5f, 0x9f, 0xe1, 0x14, 0x1f, 0xc1, 0x3b, 0xda, 0xd1, 0xad, 0xc7, 0x9c,
+    0x70, 0x18, 0xfd, 0x07, 0x7e, 0x37, 0x0d, 0xb4, 0x30, 0xff, 0x6d, 0x4b, 0x99, 0xdb, 0x3f, 0x23,
+    0xd7, 0x15, 0x3d, 0x4c, 0x14, 0x63, 0x98, 0xf5, 0x03, 0x63, 0x4e, 0x63, 0x15, 0x6a, 0xce, 0x7f,
+    0xfc, 0x4f, 0xa0, 0x72, 0x49, 0x3f, 0xd9, 0xa2, 0xde, 0x65, 0xac, 0x35, 0x88, 0x03, 0x55, 0xf5,
+    0x27, 0x57, 0x4e, 0x4b, 0xef, 0x44, 0x1d, 0xd1, 0xe9, 0xaf, 0x89, 0x7e, 0x19, 0x2a, 0xc4, 0x48,
+    0x80, 0x8d, 0x22, 0xd6, 0x4f, 0x79, 0x39, 0x15, 0x00, 0xc0, 0xa8, 0x93, 0x5a, 0x05, 0xce, 0xc8,
+    0x3f, 0x27, 0x40, 0x09, 0x1f, 0x2a, 0x0c, 0x32, 0x6a, 0x2d, 0xef, 0x51, 0x79, 0x51, 0xf1, 0xfe,
+    0xdb, 0x2c, 0xb5, 0x2f, 0x4d, 0x94, 0x1d, 0xd2, 0xb8, 0xed, 0x53, 0x58, 0x3e, 0xb4, 0x65, 0xfb,
+    0xca, 0x9f, 0xfe, 0x5c, 0x68, 0x20, 0x58, 0xd9, 0xfd, 0xc7, 0x4d, 0x0f, 0x03, 0x37, 0x61, 0xaf,
+    0x2b, 0x90, 0xe1, 0xfc, 0x15, 0xa6, 0xf1, 0xac, 0x5d, 0xad, 0xb4, 0xbe, 0xf6, 0xb4, 0x7b, 0x42,
+    0xe6, 0x17, 0xe9, 0x79, 0xde, 0x65, 0x50, 0x70, 0x6b, 0x46, 0x24, 0x73, 0x4d, 0xa3, 0x54, 0x3a,
+    0x21, 0xc2, 0x1c, 0x80, 0x1d, 0xf6, 0xd4, 0x0e, 0x7a, 0xa5, 0x4e, 0x97, 0xc1, 0x15, 0x37, 0x02,
+    0xea, 0x55, 0xff, 0xad, 0x59, 0x95, 0xa0, 0x24, 0xd0, 0x58, 0x59, 0xf7, 0x9a, 0x4e, 0x2b, 0x78,
+    0x89, 0x91, 0x9c, 0x67, 0x14, 0xe4, 0x24, 0xc3, 0xb8, 0xd3, 0x7d, 0x06, 0xaf, 0x46, 0x8f, 0xe7,
+    0x07, 0x88, 0xf0, 0x4c, 0xf4, 0xb8, 0x3a, 0x2a, 0x9c, 0x89, 0x2f, 0x7c, 0x32, 0xfd, 0x52, 0x55,
+    0xd8, 0xe1, 0x58, 0x46, 0xe5, 0xc3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x02, 0x00, 0x08,
+    0x79, 0xcf, 0xb2, 0xc9, 0x57, 0xfa, 0x06, 0xce, 0x13, 0xda, 0x88, 0x1f, 0xd7, 0xdc, 0x53, 0x59,
+    0xb8, 0x92, 0x90, 0x8c, 0xa1, 0xc3, 0xcd, 0x1d, 0xd5, 0x26, 0xdf, 0x04, 0x5b, 0x47, 0xd5, 0xdb,
+    0x0b, 0xdf, 0x3d, 0xca, 0x2d, 0xc8, 0x39, 0x12, 0xcd, 0xd3, 0x50, 0xd2, 0x96, 0x13, 0x9c, 0xb2,
+    0x45, 0xd1, 0x7d, 0x84, 0xfd, 0x97, 0x07, 0xef, 0xb2, 0xea, 0x46, 0xb2, 0x91, 0x64, 0xb5, 0xd6,
+    0x47, 0xec, 0x04, 0x40, 0xbd, 0x7c, 0xd5, 0x69, 0x5a, 0xc1, 0xf2, 0xc6, 0x76, 0xf7, 0x65, 0x06,
+    0xc2, 0xc3, 0xae, 0xd6, 0xf9, 0x31, 0x44, 0xa2, 0xf0, 0x96, 0x04, 0xd8, 0xfd, 0xe9, 0xaa, 0xb8,
+    0x8b, 0x31, 0x9a, 0x30, 0x63, 0x57, 0xf8, 0x12, 0xae, 0xb9, 0xa8, 0xc7, 0x14, 0x03, 0xae, 0xf0,
+    0x22, 0x5e, 0x03, 0xae, 0xff, 0x8e, 0x36, 0x85, 0x79, 0x59, 0x82, 0xa8, 0xde, 0x64, 0xa6, 0x61,
+    0x5d, 0xc5, 0x0c, 0x43, 0x6d, 0xf8, 0x2d, 0x5e, 0xaf, 0xe7, 0x83, 0x5c, 0x93, 0x8a, 0x03, 0xe4,
+    0x3b, 0xd6, 0x73, 0x62, 0x33, 0x70, 0xf9, 0xa1, 0x4b, 0x05, 0x5f, 0x19, 0xf8, 0x0e, 0xbe, 0x3a,
+    0xa9, 0x68, 0x5c, 0xa9, 0xdf, 0x80, 0x64, 0x0c, 0x25, 0xd9, 0x44, 0xa8, 0x65, 0xdb, 0xab, 0xeb,
+    0xc4, 0xe7, 0xdb, 0xda, 0xc9, 0x44, 0xe0, 0x97, 0x82, 0x06, 0x80, 0x64, 0x11, 0x34, 0xcd, 0x90,
+    0x4b, 0xe8, 0x81, 0x6d, 0xdd, 0x15, 0x77, 0x8e, 0x55, 0x77, 0xba, 0xe5, 0x2f, 0x35, 0x1a, 0x23,
+    0x67, 0x68, 0xd8, 0x27, 0xeb, 0xef, 0xca, 0xd1, 0xc3, 0x25, 0x09, 0xd8, 0x86, 0xcd, 0x6f, 0xe5,
+    0x00, 0x2d, 0x47, 0xc9, 0xf2, 0x6c, 0x4d, 0xb9, 0xa2, 0x86, 0xfe, 0xae, 0x95, 0x1f, 0xf4, 0x71,
+    0x83, 0xac, 0x6e, 0x8a, 0x09, 0xe3, 0x5c, 0x07, 0xc4, 0x3c, 0x3a, 0x50, 0x0f, 0xb6, 0x90, 0x21,
+    0x25, 0xdf, 0x2d, 0x61, 0x89, 0xb6, 0x3c, 0xb3, 0xc3, 0xc0, 0xd9, 0x2e, 0x73, 0x76, 0xf6, 0x46,
+    0x46, 0xf8, 0x01, 0xbd, 0x0b, 0x94, 0x80, 0xf6, 0x94, 0x5b, 0x17, 0x9e, 0xbc, 0xdb, 0x9d, 0xfd,
+    0xc2, 0x3e, 0x56, 0xa1, 0xa0, 0x1a, 0xed, 0x82, 0xcb, 0xb0, 0xb3, 0xd4, 0x58, 0xb4, 0x91, 0x8e,
+    0xd9, 0x84, 0xb8, 0x94, 0xc2, 0x86, 0x42, 0xa6, 0x86, 0xf2, 0x9c, 0x1d, 0xc7, 0xc9, 0xed, 0x6d,
+    0x0d, 0x8d, 0x98, 0x08, 0xf3, 0x52, 0xe7, 0x7f, 0xfe, 0xe0, 0x9f, 0xdf, 0x43, 0x8e, 0xbc, 0x3f,
+    0x93, 0x41, 0x44, 0x7b, 0x26, 0x0e, 0x2e, 0xc1, 0xc2, 0x4e, 0xc7, 0xb4, 0x5c, 0xc5, 0x55, 0xae,
+    0xbb, 0xb4, 0x2f, 0xd5, 0x1f, 0x34, 0xce, 0x94, 0x66, 0x12, 0x41, 0x8a, 0x15, 0x8b, 0xcb, 0xdd,
+    0x00, 0xf9, 0xa0, 0x55, 0xa6, 0x8b, 0xe9, 0x13, 0x14, 0xc6, 0x0b, 0x98, 0x8f, 0xff, 0x2f, 0x9a,
+    0xe8, 0x78, 0x68, 0x94, 0xeb, 0x53, 0xeb, 0x4b, 0xed, 0x5a, 0x6d, 0x1c, 0xe2, 0xe5, 0xc7, 0xde,
+    0x13, 0xa9, 0xaf, 0xa3, 0xc7, 0x54, 0x26, 0xa0, 0x3f, 0x44, 0xdd, 0x9f, 0x14, 0xe2, 0xc4, 0x9a,
+    0xf5, 0x30, 0xea, 0x2e, 0x75, 0xc6, 0xd3, 0xf8, 0x5e, 0x9b, 0x02, 0x0d, 0xc8, 0x81, 0x6c, 0x13,
+    0x3b, 0x9c, 0x89, 0x54, 0x52, 0x41, 0x62, 0xad, 0xa0, 0x52, 0xaa, 0x2c, 0xc4, 0x2c, 0x63, 0x58,
+    0xf6, 0xb1, 0xfa, 0xdc, 0x77, 0xed, 0x3e, 0x8c, 0x12, 0x94, 0x09, 0x57, 0x18, 0xb3, 0x04, 0x53,
+    0x3c, 0xad, 0xa8, 0x45, 0x4b, 0x19, 0xa0, 0xcb, 0x8f, 0x6f, 0x5d, 0x2d, 0xcc, 0xe1, 0xfe, 0x4a,
+    0xe6, 0x20, 0xed, 0x9a, 0x76, 0x4f, 0x17, 0xfd, 0xed, 0x1e, 0x6e, 0x41, 0x21, 0x43, 0xe4, 0xe9,
+    0x47, 0x01, 0x1f, 0x76, 0x68, 0x4d, 0xbb, 0xd3, 0xba, 0x68, 0x34, 0x06, 0x6a, 0xf5, 0xe9, 0x02,
+    0x82, 0x01, 0x01, 0x00, 0xdb, 0xc5, 0x0d, 0x95, 0x88, 0x5f, 0x2c, 0xa9, 0x7c, 0xb7, 0x06, 0xd8,
+    0x20, 0x60, 0x72, 0x80, 0xec, 0xae, 0xf4, 0xdc, 0x48, 0x5d, 0x9d, 0x6d, 0x2a, 0x54, 0x36, 0xe1,
+    0x32, 0x25, 0x10, 0x4d, 0x56, 0x0f, 0x51, 0xe9, 0xbc, 0x95, 0x3f, 0x38, 0x43, 0xed, 0xc6, 0x6a,
+    0x16, 0xb0, 0x06, 0x90, 0x85, 0x51, 0x07, 0xea, 0x7b, 0x1d, 0x64, 0x12, 0x39, 0x7e, 0x32, 0x92,
+    0x3e, 0xcc, 0x97, 0x91, 0x02, 0x6c, 0xf8, 0x95, 0xc7, 0x39, 0xa1, 0x5c, 0xd3, 0x62, 0xcc, 0x29,
+    0x83, 0x27, 0xe6, 0x36, 0xba, 0xf6, 0x62, 0x80, 0xf6, 0x15, 0xda, 0x0f, 0xc4, 0x47, 0x81, 0x44,
+    0x96, 0xba, 0xec, 0x37, 0x8c, 0x95, 0xb2, 0x30, 0x12, 0xc0, 0x4d, 0x62, 0x88, 0x5e, 0x7d, 0x13,
+    0x6d, 0x83, 0x14, 0x1e, 0xd7, 0xc2, 0xeb, 0x9d, 0xbd, 0xa4, 0x70, 0x78, 0xf3, 0xb1, 0x6b, 0x6c,
+    0xe9, 0x37, 0x63, 0x47, 0x6f, 0xed, 0xea, 0xd6, 0x32, 0x80, 0x71, 0xa2, 0x7f, 0x38, 0x67, 0xb4,
+    0x1f, 0xf0, 0x7f, 0xb6, 0xb7, 0x56, 0xe7, 0x24, 0xaa, 0x2f, 0xb9, 0x93, 0xb8, 0xab, 0x2a, 0xec,
+    0xc4, 0x19, 0x9a, 0xea, 0x5d, 0x01, 0x1e, 0xdd, 0x5c, 0x05, 0x37, 0x12, 0x04, 0x32, 0xb2, 0x5d,
+    0x16, 0xdc, 0x88, 0x0c, 0xfe, 0x1e, 0xf6, 0x9f, 0x63, 0xbf, 0xb2, 0x00, 0x6b, 0x99, 0xbe, 0x42,
+    0x96, 0x41, 0xe0, 0x3d, 0xd1, 0x35, 0x6a, 0xf1, 0x81, 0x09, 0xd6, 0x4c, 0xdd, 0xc0, 0x20, 0x6e,
+    0x0d, 0xcb, 0x30, 0x11, 0x73, 0x11, 0x82, 0x5e, 0x1b, 0x9a, 0xa0, 0x57, 0xcd, 0xd7, 0xab, 0xa2,
+    0xe9, 0xed, 0xe7, 0x26, 0x8d, 0x30, 0x09, 0xe7, 0x5a, 0xa1, 0xd0, 0x62, 0xac, 0x7f, 0x15, 0xd1,
+    0x9a, 0x0a, 0x97, 0x5d, 0x8a, 0xc0, 0x47, 0xa4, 0xa8, 0x8b, 0x26, 0x75, 0x35, 0x5d, 0xa9, 0xf1,
+    0x1a, 0x61, 0xdc, 0xbf, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc8, 0x63, 0x6e, 0x9c, 0x88, 0xcd, 0x33,
+    0xef, 0x72, 0x80, 0x00, 0x6b, 0x8e, 0xb0, 0xd2, 0xa9, 0x5c, 0x78, 0xf7, 0x25, 0x8f, 0xba, 0x49,
+    0x60, 0xa3, 0x33, 0xf4, 0x16, 0x1c, 0x81, 0xad, 0x82, 0x39, 0xa5, 0xa8, 0x12, 0xc2, 0x7e, 0x05,
+    0x33, 0x9c, 0xd9, 0xa9, 0xa4, 0x02, 0xf8, 0x43, 0xdf, 0xa6, 0x39, 0xdb, 0xc0, 0x60, 0xdc, 0x53,
+    0x76, 0x7c, 0xef, 0xf0, 0x58, 0x44, 0x3d, 0xc7, 0x77, 0xe6, 0x6f, 0x2a, 0xbd, 0x89, 0x8b, 0x40,
+    0xe3, 0x02, 0x80, 0x8c, 0x46, 0x24, 0x4c, 0x63, 0xc4, 0x06, 0xb1, 0x48, 0x92, 0x0a, 0x86, 0x58,
+    0xe3, 0x08, 0x2a, 0x2e, 0x4b, 0xdd, 0xa6, 0x64, 0x68, 0xe9, 0xac, 0x07, 0x2b, 0x3d, 0x2f, 0x42,
+    0x68, 0x5a, 0x42, 0xdb, 0xb7, 0x5a, 0x67, 0xc4, 0x5f, 0x19, 0xba, 0xff, 0xed, 0x17, 0x0b, 0xf8,
+    0x26, 0x36, 0xd7, 0x9d, 0x3a, 0x3d, 0x0e, 0x5f, 0x31, 0x29, 0x3f, 0xf4, 0x24, 0x2f, 0x0a, 0xa2,
+    0x21, 0x0e, 0x6e, 0x86, 0xf5, 0x1e, 0xb7, 0xce, 0x81, 0x95, 0xd0, 0xcd, 0x97, 0xd1, 0x2c, 0xd4,
+    0x9f, 0x95, 0xd6, 0x7c, 0x68, 0x80, 0x4f, 0xe6, 0x5c, 0xab, 0xfe, 0x6b, 0xf9, 0x8b, 0x12, 0x99,
+    0xad, 0xc9, 0x64, 0x21, 0x99, 0xef, 0xfb, 0xd3, 0x16, 0x8b, 0x95, 0x93, 0xa7, 0xb7, 0x24, 0x36,
+    0x00, 0xb2, 0xa2, 0xbe, 0x79, 0x4e, 0x66, 0xbd, 0xe1, 0x2d, 0xd0, 0xa9, 0x76, 0xe1, 0x13, 0x0d,
+    0xb5, 0x4b, 0xc5, 0xe9, 0x63, 0x23, 0x45, 0xcf, 0x5f, 0x0d, 0x5c, 0xce, 0x93, 0x7f, 0xa9, 0x68,
+    0xf6, 0xfc, 0x2c, 0x54, 0x40, 0x43, 0xca, 0x9d, 0xfd, 0x43, 0x81, 0x4d, 0xbe, 0x98, 0x87, 0xca,
+    0x2c, 0x82, 0x32, 0xb7, 0xcf, 0xa1, 0xc5, 0xf8, 0x55, 0xea, 0x2b, 0x6d, 0xfc, 0xe7, 0x5d, 0xcf,
+    0xde, 0xf8, 0x15, 0xc2, 0xc3, 0xa2, 0xe6, 0x83, 0xfd, 0x02, 0x82, 0x01, 0x00, 0x2c, 0x83, 0x3a,
+    0xff, 0x20, 0x81, 0xf6, 0x6f, 0xd5, 0xbc, 0xd4, 0x7c, 0x0e, 0x02, 0xba, 0xee, 0x76, 0x01, 0xf1,
+    0xc2, 0x74, 0x3d, 0xd1, 0xd6, 0xfc, 0x8d, 0xd6, 0x17, 0xc2, 0xaa, 0x53, 0x24, 0xf6, 0xdb, 0x5f,
+    0x81, 0xf2, 0x1a, 0x60, 0x95, 0xaa, 0xdc, 0x8c, 0x25, 0x8c, 0xb6, 0xd6, 0x7d, 0x8b, 0x23, 0x20,
+    0x71, 0x53, 0xc2, 0x5e, 0x34, 0x7a, 0xc4, 0x9e, 0xc5, 0x94, 0x46, 0xa8, 0x24, 0x4c, 0xd3, 0x79,
+    0x7e, 0x0c, 0xbe, 0x15, 0x7a, 0xd1, 0xad, 0xdf, 0x20, 0x41, 0x5a, 0x61, 0x7c, 0x90, 0x5d, 0xbb,
+    0x11, 0xd7, 0xc6, 0x11, 0x46, 0xc4, 0x40, 0x9f, 0x64, 0x1f, 0x0b, 0x79, 0x30, 0xbf, 0x1e, 0xca,
+    0xda, 0x85, 0xd1, 0xc1, 0x5a, 0xc5, 0xb8, 0x2d, 0xa9, 0x33, 0xb3, 0x2a, 0xee, 0x1c, 0x51, 0x74,
+    0x9b, 0x9c, 0x7f, 0xa3, 0xf0, 0x3b, 0x9b, 0xa1, 0xe0, 0x8b, 0x54, 0x16, 0x9d, 0xaf, 0x84, 0x06,
+    0xde, 0x9f, 0x97, 0xf8, 0x6c, 0x2b, 0x4c, 0x67, 0x64, 0xca, 0x5b, 0x51, 0xe2, 0xd6, 0x3b, 0x99,
+    0xd1, 0x89, 0x4e, 0xe5, 0x4d, 0x90, 0x47, 0xcb, 0x07, 0xed, 0xa8, 0x2a, 0x02, 0x72, 0x17, 0xfa,
+    0x02, 0x67, 0xd2, 0xfe, 0x96, 0x7d, 0x97, 0x2f, 0x1d, 0x3f, 0xb6, 0x27, 0x30, 0x4a, 0x80, 0x46,
+    0xff, 0x7d, 0x9a, 0xa4, 0x19, 0x05, 0xb2, 0x3c, 0x21, 0x0c, 0x82, 0x07, 0x43, 0x3e, 0x0e, 0x8d,
+    0xbc, 0xa0, 0xa0, 0x37, 0x71, 0x96, 0x30, 0x85, 0xe1, 0x04, 0x96, 0x35, 0x04, 0x33, 0xc4, 0x46,
+    0x1d, 0x7d, 0x85, 0xd2, 0x18, 0x36, 0xaf, 0x0a, 0x2a, 0x93, 0x2b, 0x06, 0x78, 0x7e, 0x7c, 0x4e,
+    0x65, 0x37, 0xac, 0x32, 0xa2, 0xe9, 0xc1, 0x4b, 0xd0, 0x0a, 0x5d, 0x3e, 0xcf, 0x49, 0x7d, 0x2c,
+    0x85, 0xa3, 0x45, 0x9b, 0xe2, 0x7d, 0x8e, 0x9d, 0x0f, 0x22, 0x82, 0xd3, 0xcd, 0x02, 0x82, 0x01,
+    0x00, 0x46, 0xe8, 0x18, 0x3d, 0xbf, 0x92, 0x8c, 0xec, 0x0f, 0xa2, 0x07, 0x84, 0x07, 0xab, 0xbd,
+    0xff, 0x3b, 0xbf, 0x7a, 0x04, 0x8a, 0x85, 0x2a, 0x6d, 0xcd, 0x92, 0x16, 0xae, 0xb4, 0x4b, 0x96,
+    0xaf, 0xdb, 0xe2, 0x28, 0x44, 0xeb, 0x19, 0x58, 0x91, 0xd8, 0xd0, 0x94, 0x5c, 0x7a, 0xc8, 0x8a,
+    0x8b, 0xda, 0xef, 0xe2, 0x38, 0x82, 0x8d, 0xb3, 0xe2, 0xdb, 0x76, 0xb3, 0x9f, 0x28, 0x16, 0x8c,
+    0x3c, 0x7b, 0x07, 0x9f, 0x22, 0x0e, 0x47, 0x7e, 0x20, 0x55, 0xc4, 0x52, 0xde, 0x86, 0xfd, 0x98,
+    0xd7, 0xc6, 0x5e, 0x79, 0x05, 0x64, 0x40, 0x01, 0xb7, 0xe4, 0x2d, 0xb8, 0xd0, 0x13, 0x90, 0x4b,
+    0x3b, 0x6c, 0x63, 0xf8, 0xed, 0x6d, 0xeb, 0x09, 0x1e, 0x8f, 0xc1, 0xd4, 0xa9, 0x5e, 0x8e, 0x15,
+    0x48, 0x69, 0x7c, 0x68, 0x0e, 0xe6, 0xf6, 0xcf, 0x4a, 0x06, 0x61, 0xe9, 0x3a, 0xb0, 0x5c, 0x23,
+    0x86, 0xeb, 0xc7, 0xbb, 0x86, 0x0a, 0x37, 0x43, 0x03, 0x5b, 0x6d, 0xf4, 0xc7, 0x4b, 0xa5, 0x52,
+    0xa7, 0x3b, 0xf1, 0xf4, 0xad, 0xe1, 0xd0, 0x71, 0x34, 0x3e, 0xfa, 0xf4, 0x6e, 0xad, 0xe8, 0x97,
+    0xe4, 0xf6, 0xdf, 0x42, 0x29, 0xbc, 0xf2, 0x49, 0xfa, 0xda, 0xa6, 0x59, 0xd5, 0x74, 0xbb, 0xb1,
+    0x07, 0xeb, 0x40, 0x74, 0x4d, 0x06, 0x5b, 0x03, 0xd8, 0xdf, 0x5d, 0x02, 0xf5, 0x3d, 0xae, 0xd1,
+    0x45, 0x9a, 0xc6, 0x99, 0x10, 0x7d, 0xb8, 0x16, 0x43, 0xae, 0x9a, 0x4b, 0x69, 0x4f, 0x13, 0xe6,
+    0xbb, 0x05, 0xa9, 0x6f, 0x57, 0x75, 0xf6, 0xe6, 0x33, 0x6f, 0x2b, 0xe8, 0x6c, 0x0d, 0x10, 0xe7,
+    0x32, 0xb4, 0xee, 0x4e, 0x2a, 0x41, 0x22, 0xdb, 0x81, 0x40, 0x58, 0xdd, 0xfd, 0xd4, 0x8a, 0x8e,
+    0xc3, 0x27, 0xe7, 0x52, 0x36, 0x09, 0x50, 0x82, 0xbb, 0xad, 0x21, 0x56, 0x17, 0x8f, 0xce, 0xed,
+    0xa9, 0x02, 0x82, 0x01, 0x00, 0x78, 0x0c, 0x4f, 0x07, 0x4a, 0x2d, 0x91, 0xa3, 0xfd, 0x1c, 0xb3,
+    0xb5, 0xcb, 0x11, 0x1c, 0x04, 0xc9, 0x7f, 0xbf, 0x86, 0x7d, 0x5e, 0x2e, 0xf4, 0x2c, 0xad, 0x9e,
+    0x35, 0x74, 0x2e, 0x55, 0xc6, 0xaf, 0x1c, 0x76, 0xb9, 0x3d, 0x44, 0xe7, 0xdd, 0x5f, 0x32, 0x0e,
+    0xce, 0x4b, 0x43, 0x6d, 0x7c, 0x10, 0xd3, 0x01, 0x6f, 0x22, 0xa5, 0xb3, 0xaf, 0x40, 0x80, 0x57,
+    0xf0, 0x96, 0x7c, 0xb8, 0xae, 0xbc, 0x35, 0x8b, 0xa1, 0x59, 0xdc, 0xc4, 0xf7, 0x8b, 0xda, 0xe7,
+    0x91, 0x9b, 0xa7, 0x54, 0x61, 0xad, 0x9d, 0x0a, 0x68, 0xc3, 0xc5, 0x10, 0x9e, 0x39, 0x16, 0x9c,
+    0x3b, 0xf3, 0x3a, 0xdf, 0xb9, 0x72, 0xed, 0x4f, 0x56, 0x1e, 0x5c, 0x8b, 0x35, 0x0b, 0xa6, 0x08,
+    0x83, 0x96, 0xd4, 0x6d, 0x3f, 0xe3, 0x6a, 0x25, 0xa2, 0xe8, 0x0f, 0xce, 0x0c, 0x26, 0x85, 0x02,
+    0xba, 0xe1, 0xfc, 0xdc, 0xa0, 0x18, 0xfc, 0x7c, 0x87, 0xa6, 0x6b, 0xf5, 0x92, 0xa8, 0x83, 0x5f,
+    0xbf, 0xa5, 0xe3, 0x0e, 0x21, 0x10, 0xbf, 0x44, 0x49, 0xc7, 0x62, 0x36, 0x46, 0x0b, 0x97, 0xdc,
+    0xd4, 0x30, 0x02, 0xd4, 0x04, 0xcb, 0x8f, 0xfe, 0xde, 0x76, 0x44, 0x9f, 0xd6, 0x55, 0x8e, 0x45,
+    0xaa, 0x10, 0xd4, 0xa0, 0x2c, 0x49, 0x72, 0x6e, 0x5f, 0xf1, 0xd5, 0x0a, 0x1e, 0xba, 0xc6, 0xb4,
+    0xb6, 0x93, 0x9d, 0x6a, 0xe4, 0xaa, 0x61, 0x3a, 0xca, 0x77, 0xa4, 0x16, 0xa2, 0x4f, 0x2f, 0xad,
+    0xe6, 0xb5, 0x64, 0x93, 0x37, 0xf9, 0xdc, 0x28, 0x70, 0x54, 0x0b, 0xb2, 0x15, 0x96, 0x60, 0xbc,
+    0x86, 0x16, 0xfc, 0x5c, 0xf0, 0x75, 0xc2, 0x6f, 0x51, 0x4f, 0x71, 0xbb, 0x77, 0xed, 0xe8, 0x2b,
+    0xf2, 0xe3, 0x7d, 0x02, 0xa8, 0xfe, 0x26, 0x8a, 0x40, 0x63, 0x8f, 0x14, 0x84, 0xd2, 0x00, 0x70,
+    0x6a, 0xf3, 0xde, 0xf8, 0x66};
+constexpr const unsigned int rsa_key_4k_len = sizeof(rsa_key_4k);
+
+constexpr const unsigned char rsa_key_2k[] = {
+    0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01,
+    0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0x9d, 0xd0, 0xca, 0x63, 0xaa, 0x59, 0x73, 0x13, 0x55, 0x53,
+    0xdc, 0x5d, 0x4d, 0xf9, 0x5c, 0x4f, 0x31, 0xe3, 0x34, 0x45, 0xbf, 0xc5, 0x8b, 0x43, 0x8f, 0x10,
+    0xb6, 0x22, 0xaf, 0xe0, 0x12, 0xff, 0xf5, 0xa8, 0x71, 0x0a, 0xe9, 0x67, 0x8d, 0x05, 0xd2, 0x69,
+    0x35, 0x32, 0x8d, 0x94, 0x9f, 0x52, 0x63, 0x4e, 0x54, 0x0b, 0x29, 0x3d, 0x7b, 0x5e, 0xc0, 0x98,
+    0x94, 0x23, 0x43, 0x46, 0x39, 0xce, 0xc2, 0xe1, 0x2b, 0xcd, 0x00, 0x6c, 0x9d, 0xe7, 0x81, 0xb9,
+    0x6b, 0x97, 0xea, 0x3a, 0xe7, 0x09, 0x06, 0x6b, 0xf3, 0xe1, 0x7a, 0x03, 0xcd, 0x51, 0x2c, 0x16,
+    0x19, 0x6c, 0xdf, 0x2c, 0xd5, 0x96, 0x92, 0x19, 0xaa, 0x91, 0xe3, 0xa5, 0xc7, 0xe1, 0x0b, 0x07,
+    0xb6, 0x84, 0xd3, 0xa7, 0x1f, 0x0d, 0x22, 0xb9, 0xc1, 0x76, 0x16, 0x81, 0x53, 0x50, 0x7d, 0x54,
+    0x2a, 0x26, 0x9e, 0xfa, 0xb1, 0xb7, 0x83, 0x05, 0x24, 0x81, 0xea, 0x5a, 0x6c, 0xb5, 0x92, 0x69,
+    0x63, 0x35, 0xfa, 0x04, 0xae, 0xee, 0xc5, 0xdb, 0xf0, 0x9b, 0xfe, 0xe6, 0xc4, 0x73, 0x18, 0x3d,
+    0xd3, 0x01, 0xaf, 0x03, 0x43, 0x95, 0xca, 0xab, 0x43, 0x04, 0x64, 0x49, 0xe7, 0x47, 0xf8, 0x97,
+    0xe5, 0x63, 0xd1, 0x3d, 0x21, 0x9b, 0xd5, 0x13, 0x2a, 0xb0, 0xf1, 0xf9, 0xff, 0xd2, 0xb7, 0x12,
+    0xa8, 0xa0, 0x20, 0x38, 0xde, 0x41, 0x8e, 0xa3, 0xc7, 0xce, 0x5b, 0x9c, 0x30, 0x1a, 0xaf, 0x13,
+    0x11, 0xd1, 0xd0, 0x71, 0x7f, 0x1e, 0x47, 0xa8, 0x32, 0x3b, 0x4a, 0x36, 0xa8, 0x6d, 0x8c, 0xd7,
+    0x5f, 0x93, 0x95, 0xa8, 0xe0, 0xfa, 0x59, 0xb5, 0x6c, 0x1f, 0xfb, 0x01, 0x64, 0xf5, 0x5d, 0xf5,
+    0x17, 0x75, 0x53, 0xfb, 0xc3, 0x3f, 0xd7, 0xc5, 0x45, 0x53, 0xb4, 0xa2, 0xcf, 0xa5, 0x71, 0xf0,
+    0x7a, 0x8b, 0x66, 0x09, 0xfa, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x03,
+    0xe9, 0x06, 0x4d, 0x6a, 0xe2, 0xa0, 0x2b, 0x24, 0xa1, 0x99, 0x23, 0xb2, 0x08, 0xbc, 0x2f, 0x4a,
+    0xd2, 0xa6, 0x30, 0x6b, 0x91, 0xd6, 0xf8, 0xb1, 0x0f, 0x9e, 0x71, 0x04, 0x94, 0xe8, 0xe8, 0xf1,
+    0x00, 0x1f, 0xf0, 0xea, 0x70, 0x97, 0x8f, 0x6d, 0xde, 0x65, 0x24, 0x35, 0x5a, 0xd9, 0xdf, 0x13,
+    0x8e, 0x7f, 0x74, 0x44, 0x02, 0x28, 0x7a, 0x39, 0x61, 0x19, 0x1b, 0xe3, 0x3b, 0xac, 0x62, 0x01,
+    0x9f, 0xcc, 0xfd, 0xdd, 0x85, 0x53, 0x72, 0x46, 0xdb, 0x69, 0x1d, 0x90, 0xa9, 0xad, 0xf6, 0x22,
+    0x1e, 0x6e, 0xf8, 0x06, 0xc0, 0x6d, 0x08, 0x16, 0x5a, 0x0e, 0x7e, 0x37, 0xec, 0xbc, 0xa1, 0x68,
+    0x49, 0xa7, 0x84, 0x1e, 0xdf, 0xb4, 0x30, 0xa6, 0x1d, 0x26, 0x4f, 0x6b, 0x39, 0x1d, 0xad, 0x58,
+    0x7a, 0x16, 0xca, 0x38, 0xc0, 0xdd, 0x3c, 0xc6, 0x26, 0x32, 0xe1, 0xd5, 0xc2, 0xeb, 0x6a, 0xa6,
+    0x70, 0x1f, 0x50, 0x82, 0x2d, 0xf6, 0x09, 0x27, 0x56, 0x4f, 0xf1, 0xed, 0x62, 0x60, 0xe5, 0x55,
+    0x0f, 0x8d, 0xbe, 0xd7, 0x5a, 0xb7, 0x7c, 0x57, 0x25, 0xe5, 0xa3, 0x46, 0xb6, 0x97, 0xe0, 0x87,
+    0x43, 0x04, 0x46, 0xd8, 0x4f, 0xbe, 0x80, 0x75, 0x40, 0x48, 0x2d, 0xc0, 0x57, 0xf8, 0x76, 0xbd,
+    0xd8, 0x14, 0xa0, 0x7b, 0x39, 0x4f, 0xcf, 0xdc, 0x34, 0x5b, 0x1e, 0x91, 0xef, 0xa7, 0xc8, 0x82,
+    0x2c, 0xe8, 0xe4, 0x01, 0x2b, 0xa6, 0x92, 0x4e, 0x0b, 0xd1, 0x98, 0xdc, 0x45, 0x46, 0x3f, 0x89,
+    0xb1, 0x01, 0xb5, 0xa7, 0xeb, 0x71, 0x2f, 0x09, 0x10, 0x3c, 0x71, 0x14, 0xf3, 0x86, 0x18, 0xa8,
+    0x5a, 0x30, 0xef, 0xfe, 0x87, 0x65, 0xb1, 0xaf, 0x9c, 0x8d, 0x3e, 0xc8, 0x8d, 0x72, 0xf5, 0x16,
+    0xcb, 0x3a, 0xb8, 0xb1, 0x18, 0xa5, 0x43, 0x1d, 0x24, 0xa1, 0x1c, 0x2d, 0x2d, 0x87, 0xc1, 0x02,
+    0x81, 0x81, 0x00, 0xde, 0x87, 0xff, 0x74, 0x9d, 0x86, 0x9b, 0x0b, 0x18, 0xb7, 0xa4, 0x50, 0xda,
+    0x2d, 0x27, 0xff, 0x0e, 0x4d, 0xae, 0x40, 0x21, 0x92, 0x0b, 0x1d, 0x8b, 0xdd, 0x81, 0xdc, 0x40,
+    0x1c, 0xed, 0x7d, 0x39, 0xd6, 0x1d, 0xdd, 0x88, 0xd0, 0x92, 0xee, 0x74, 0xca, 0x96, 0xa7, 0x6a,
+    0x58, 0xd3, 0xc6, 0xf4, 0x3e, 0x93, 0x43, 0x54, 0x07, 0x72, 0x3a, 0x8d, 0x3b, 0x09, 0xe0, 0x16,
+    0x16, 0x71, 0xf1, 0xae, 0xc4, 0xc0, 0x46, 0xce, 0x40, 0x6d, 0xba, 0xf0, 0x4d, 0x1d, 0x04, 0x9a,
+    0x32, 0x31, 0xe1, 0x07, 0x9b, 0x90, 0x7c, 0xc2, 0xb2, 0xfc, 0x4e, 0xb9, 0x61, 0xd4, 0xdb, 0x4a,
+    0xa1, 0xb9, 0x78, 0x46, 0x98, 0xa9, 0xfb, 0x21, 0x60, 0xb8, 0x07, 0x6b, 0x24, 0x4d, 0x4d, 0x35,
+    0x83, 0x0b, 0x21, 0xac, 0xdf, 0x93, 0x2f, 0xb5, 0xec, 0xe5, 0x99, 0x1a, 0x59, 0xaa, 0xd3, 0xbb,
+    0x8f, 0xe9, 0xad, 0x02, 0x81, 0x81, 0x00, 0xb5, 0x8d, 0x14, 0x8e, 0x85, 0xd9, 0x7c, 0x9e, 0xfc,
+    0xa1, 0x1f, 0x1a, 0x84, 0x31, 0x07, 0x71, 0x1a, 0x72, 0x91, 0xc0, 0xc5, 0xac, 0x8f, 0xa7, 0x0f,
+    0x37, 0x48, 0x51, 0x12, 0xda, 0x0d, 0x30, 0x6d, 0x97, 0x21, 0x20, 0x90, 0x49, 0x4d, 0x2b, 0xc1,
+    0x89, 0x8e, 0x00, 0x66, 0x18, 0x47, 0xd5, 0x68, 0x62, 0xe7, 0x29, 0xf4, 0x95, 0x59, 0x5b, 0xba,
+    0x4b, 0xc2, 0x20, 0xda, 0xef, 0x4f, 0x33, 0x0e, 0x99, 0xfe, 0x6c, 0xec, 0xf9, 0xd8, 0x81, 0x3a,
+    0x46, 0x1a, 0xbd, 0xba, 0xf7, 0xfc, 0xd7, 0x19, 0xf8, 0x2d, 0xd1, 0x81, 0x88, 0xce, 0x55, 0x98,
+    0xe6, 0xbc, 0x25, 0x67, 0xa6, 0xbe, 0x2b, 0x0f, 0x1d, 0xb6, 0x0d, 0xea, 0xc6, 0xb6, 0x95, 0xee,
+    0x42, 0x3e, 0x1b, 0xf5, 0x8c, 0xf3, 0x19, 0x8e, 0x59, 0xfc, 0xe1, 0x42, 0x1b, 0x26, 0x20, 0x09,
+    0x8a, 0x1b, 0x57, 0x8e, 0xe1, 0xa7, 0x21, 0x02, 0x81, 0x80, 0x78, 0xc7, 0x33, 0x7d, 0x25, 0xaa,
+    0x53, 0x28, 0x38, 0xa8, 0x23, 0x84, 0xc6, 0x85, 0xcf, 0xb9, 0x7d, 0x17, 0xe8, 0x45, 0x62, 0x73,
+    0x13, 0x99, 0x5b, 0xba, 0x43, 0xab, 0x39, 0x18, 0xfa, 0x45, 0x07, 0x49, 0x11, 0x38, 0x95, 0xf3,
+    0x2e, 0x6c, 0x41, 0xf3, 0x5a, 0xc5, 0x4e, 0xd1, 0x1b, 0x50, 0x56, 0x6c, 0x48, 0x1d, 0x38, 0xd4,
+    0x39, 0xc9, 0x51, 0xb2, 0x03, 0x70, 0x1e, 0x4c, 0xdc, 0x57, 0x22, 0x56, 0x23, 0x4d, 0xca, 0xcf,
+    0xe9, 0x3e, 0x97, 0x02, 0x23, 0x87, 0xc5, 0xf1, 0x0c, 0x65, 0x68, 0x6d, 0xa4, 0x84, 0x32, 0x60,
+    0x56, 0xd4, 0x9b, 0x85, 0x5f, 0xb4, 0x0d, 0xd3, 0xad, 0x08, 0x7c, 0xb8, 0x8b, 0x39, 0x84, 0x2a,
+    0x2c, 0x77, 0xca, 0x4d, 0x0f, 0xaf, 0xa2, 0x25, 0x97, 0xbb, 0x15, 0x4a, 0xdb, 0x65, 0xff, 0xc5,
+    0xad, 0xef, 0xe4, 0xff, 0x59, 0xda, 0x45, 0x68, 0x9c, 0x99, 0x02, 0x81, 0x80, 0x16, 0x45, 0x0a,
+    0xfb, 0x7c, 0x91, 0xb4, 0x06, 0xb0, 0x88, 0x77, 0x0f, 0x42, 0x9d, 0xdd, 0x02, 0xd3, 0xb2, 0xb0,
+    0x0c, 0x4c, 0x73, 0x21, 0x5f, 0xe5, 0xae, 0xeb, 0x50, 0xfe, 0x95, 0xfe, 0xbe, 0x2d, 0x03, 0x37,
+    0xce, 0x0d, 0xc4, 0xe0, 0x11, 0x78, 0xf9, 0x0d, 0x91, 0x20, 0xf4, 0xe3, 0x82, 0xda, 0xfe, 0x1e,
+    0xca, 0xf7, 0xb4, 0x86, 0x34, 0x89, 0x42, 0x97, 0xba, 0x7e, 0x00, 0x92, 0xdf, 0x79, 0x70, 0x0c,
+    0x54, 0x82, 0x31, 0x17, 0x8c, 0xaa, 0x80, 0x44, 0xf1, 0x77, 0x08, 0xca, 0x5b, 0xfc, 0x54, 0x84,
+    0x12, 0x49, 0xe8, 0x65, 0x1e, 0xfc, 0xd5, 0x78, 0xc8, 0xc1, 0xd1, 0x23, 0x4c, 0x96, 0xdb, 0x17,
+    0x24, 0xd7, 0xe2, 0xae, 0x2c, 0xef, 0xff, 0xf2, 0x2c, 0x6d, 0xcf, 0x6f, 0x56, 0x78, 0x2e, 0xb3,
+    0xa5, 0x51, 0xfd, 0x90, 0x8c, 0xa7, 0x7e, 0xe8, 0x61, 0xb2, 0x26, 0x1d, 0xe1, 0x02, 0x81, 0x81,
+    0x00, 0x88, 0xf6, 0x9a, 0xec, 0xab, 0xb6, 0x25, 0x2c, 0x12, 0x4e, 0x90, 0x8f, 0xea, 0xa2, 0x7e,
+    0x62, 0x41, 0xd7, 0xfd, 0x7c, 0x5d, 0xaa, 0x83, 0xfa, 0xc7, 0x48, 0x51, 0x54, 0xed, 0x72, 0x59,
+    0x95, 0xc0, 0x61, 0xdc, 0xfa, 0xc6, 0xb8, 0xd5, 0x5f, 0x9a, 0xd0, 0x7e, 0xcb, 0x3f, 0xc4, 0xfd,
+    0xb4, 0x4d, 0x46, 0x74, 0xc4, 0xf0, 0x45, 0xd4, 0x62, 0xdc, 0x27, 0x37, 0x4a, 0x8a, 0xcf, 0x27,
+    0x1a, 0x6f, 0x00, 0x50, 0x12, 0x99, 0x8d, 0xd7, 0xa8, 0xdf, 0xf3, 0xa4, 0x61, 0x18, 0x4f, 0xed,
+    0x1d, 0xac, 0x51, 0xd4, 0x44, 0x2f, 0x73, 0xea, 0xe7, 0xd7, 0xd2, 0x81, 0xe1, 0xe8, 0x4e, 0x0a,
+    0xeb, 0xbd, 0x40, 0x2b, 0x62, 0xb3, 0x43, 0x60, 0x72, 0x73, 0x31, 0xc0, 0x7a, 0x16, 0x15, 0x83,
+    0x71, 0x2f, 0x2e, 0xb4, 0x17, 0x43, 0x12, 0x30, 0x08, 0xef, 0x72, 0xdb, 0xc9, 0x50, 0x28, 0x5a,
+    0xda};
+constexpr const unsigned int rsa_key_2k_len = sizeof(rsa_key_2k);
\ No newline at end of file
diff --git a/keystore2/src/crypto/zvec.rs b/keystore2/src/crypto/zvec.rs
new file mode 100644
index 0000000..78b474e
--- /dev/null
+++ b/keystore2/src/crypto/zvec.rs
@@ -0,0 +1,119 @@
+// Copyright 2020, 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.
+
+use crate::error::Error;
+use nix::sys::mman::{mlock, munlock};
+use std::convert::TryFrom;
+use std::fmt;
+use std::ops::{Deref, DerefMut};
+use std::ptr::write_volatile;
+
+/// A semi fixed size u8 vector that is zeroed when dropped.  It can shrink in
+/// size but cannot grow larger than the original size (and if it shrinks it
+/// still owns the entire buffer).  Also the data is pinned in memory with
+/// mlock.
+#[derive(Default, Eq, PartialEq)]
+pub struct ZVec {
+    elems: Box<[u8]>,
+    len: usize,
+}
+
+impl ZVec {
+    /// Create a ZVec with the given size.
+    pub fn new(size: usize) -> Result<Self, Error> {
+        let v: Vec<u8> = vec![0; size];
+        let b = v.into_boxed_slice();
+        if size > 0 {
+            unsafe { mlock(b.as_ptr() as *const std::ffi::c_void, b.len()) }?;
+        }
+        Ok(Self { elems: b, len: size })
+    }
+
+    /// Reduce the length to the given value.  Does nothing if that length is
+    /// greater than the length of the vector.  Note that it still owns the
+    /// original allocation even if the length is reduced.
+    pub fn reduce_len(&mut self, len: usize) {
+        if len <= self.elems.len() {
+            self.len = len;
+        }
+    }
+}
+
+impl Drop for ZVec {
+    fn drop(&mut self) {
+        for i in 0..self.elems.len() {
+            unsafe { write_volatile(self.elems.as_mut_ptr().add(i), 0) };
+        }
+        if !self.elems.is_empty() {
+            if let Err(e) =
+                unsafe { munlock(self.elems.as_ptr() as *const std::ffi::c_void, self.elems.len()) }
+            {
+                log::error!("In ZVec::drop: `munlock` failed: {:?}.", e);
+            }
+        }
+    }
+}
+
+impl Deref for ZVec {
+    type Target = [u8];
+
+    fn deref(&self) -> &Self::Target {
+        &self.elems[0..self.len]
+    }
+}
+
+impl DerefMut for ZVec {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.elems[0..self.len]
+    }
+}
+
+impl fmt::Debug for ZVec {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if self.elems.is_empty() {
+            write!(f, "Zvec empty")
+        } else {
+            write!(f, "Zvec size: {} [ Sensitive information redacted ]", self.len)
+        }
+    }
+}
+
+impl TryFrom<&[u8]> for ZVec {
+    type Error = Error;
+
+    fn try_from(v: &[u8]) -> Result<Self, Self::Error> {
+        let mut z = ZVec::new(v.len())?;
+        if !v.is_empty() {
+            z.clone_from_slice(v);
+        }
+        Ok(z)
+    }
+}
+
+impl TryFrom<Vec<u8>> for ZVec {
+    type Error = Error;
+
+    fn try_from(mut v: Vec<u8>) -> Result<Self, Self::Error> {
+        let len = v.len();
+        // into_boxed_slice calls shrink_to_fit, which may move the pointer.
+        // But sometimes the contents of the Vec are already sensitive and
+        // mustn't be copied. So ensure the shrink_to_fit call is a NOP.
+        v.resize(v.capacity(), 0);
+        let b = v.into_boxed_slice();
+        if !b.is_empty() {
+            unsafe { mlock(b.as_ptr() as *const std::ffi::c_void, b.len()) }?;
+        }
+        Ok(Self { elems: b, len })
+    }
+}
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
new file mode 100644
index 0000000..e1185f3
--- /dev/null
+++ b/keystore2/src/database.rs
@@ -0,0 +1,5593 @@
+// Copyright 2020, 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.
+
+//! This is the Keystore 2.0 database module.
+//! The database module provides a connection to the backing SQLite store.
+//! We have two databases one for persistent key blob storage and one for
+//! items that have a per boot life cycle.
+//!
+//! ## Persistent database
+//! The persistent database has tables for key blobs. They are organized
+//! as follows:
+//! The `keyentry` table is the primary table for key entries. It is
+//! accompanied by two tables for blobs and parameters.
+//! Each key entry occupies exactly one row in the `keyentry` table and
+//! zero or more rows in the tables `blobentry` and `keyparameter`.
+//!
+//! ## Per boot database
+//! The per boot database stores items with a per boot lifecycle.
+//! Currently, there is only the `grant` table in this database.
+//! Grants are references to a key that can be used to access a key by
+//! clients that don't own that key. Grants can only be created by the
+//! owner of a key. And only certain components can create grants.
+//! This is governed by SEPolicy.
+//!
+//! ## Access control
+//! Some database functions that load keys or create grants perform
+//! access control. This is because in some cases access control
+//! can only be performed after some information about the designated
+//! key was loaded from the database. To decouple the permission checks
+//! from the database module these functions take permission check
+//! callbacks.
+
+use crate::impl_metadata; // This is in db_utils.rs
+use crate::key_parameter::{KeyParameter, Tag};
+use crate::permission::KeyPermSet;
+use crate::utils::{get_current_time_in_seconds, watchdog as wd, AID_USER_OFFSET};
+use crate::{
+    db_utils::{self, SqlField},
+    gc::Gc,
+    super_key::USER_SUPER_KEY,
+};
+use crate::{
+    error::{Error as KsError, ErrorCode, ResponseCode},
+    super_key::SuperKeyType,
+};
+use anyhow::{anyhow, Context, Result};
+use std::{convert::TryFrom, convert::TryInto, ops::Deref, time::SystemTimeError};
+
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    HardwareAuthToken::HardwareAuthToken,
+    HardwareAuthenticatorType::HardwareAuthenticatorType, SecurityLevel::SecurityLevel,
+};
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
+    Timestamp::Timestamp,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor,
+};
+use android_security_remoteprovisioning::aidl::android::security::remoteprovisioning::{
+    AttestationPoolStatus::AttestationPoolStatus,
+};
+use statslog_rust::keystore2_storage_stats::{
+	Keystore2StorageStats, StorageType as StatsdStorageType,
+};
+
+use keystore2_crypto::ZVec;
+use lazy_static::lazy_static;
+use log::error;
+#[cfg(not(test))]
+use rand::prelude::random;
+use rusqlite::{
+    params,
+    types::FromSql,
+    types::FromSqlResult,
+    types::ToSqlOutput,
+    types::{FromSqlError, Value, ValueRef},
+    Connection, OptionalExtension, ToSql, Transaction, TransactionBehavior, NO_PARAMS,
+};
+
+use std::{
+    collections::{HashMap, HashSet},
+    path::Path,
+    sync::{Arc, Condvar, Mutex},
+    time::{Duration, SystemTime},
+};
+
+#[cfg(test)]
+use tests::random;
+
+impl_metadata!(
+    /// A set of metadata for key entries.
+    #[derive(Debug, Default, Eq, PartialEq)]
+    pub struct KeyMetaData;
+    /// A metadata entry for key entries.
+    #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
+    pub enum KeyMetaEntry {
+        /// Date of the creation of the key entry.
+        CreationDate(DateTime) with accessor creation_date,
+        /// Expiration date for attestation keys.
+        AttestationExpirationDate(DateTime) with accessor attestation_expiration_date,
+        /// CBOR Blob that represents a COSE_Key and associated metadata needed for remote
+        /// provisioning
+        AttestationMacedPublicKey(Vec<u8>) with accessor attestation_maced_public_key,
+        /// Vector representing the raw public key so results from the server can be matched
+        /// to the right entry
+        AttestationRawPubKey(Vec<u8>) with accessor attestation_raw_pub_key,
+        /// SEC1 public key for ECDH encryption
+        Sec1PublicKey(Vec<u8>) with accessor sec1_public_key,
+        //  --- ADD NEW META DATA FIELDS HERE ---
+        // For backwards compatibility add new entries only to
+        // end of this list and above this comment.
+    };
+);
+
+impl KeyMetaData {
+    fn load_from_db(key_id: i64, tx: &Transaction) -> Result<Self> {
+        let mut stmt = tx
+            .prepare(
+                "SELECT tag, data from persistent.keymetadata
+                    WHERE keyentryid = ?;",
+            )
+            .context("In KeyMetaData::load_from_db: prepare statement failed.")?;
+
+        let mut metadata: HashMap<i64, KeyMetaEntry> = Default::default();
+
+        let mut rows =
+            stmt.query(params![key_id]).context("In KeyMetaData::load_from_db: query failed.")?;
+        db_utils::with_rows_extract_all(&mut rows, |row| {
+            let db_tag: i64 = row.get(0).context("Failed to read tag.")?;
+            metadata.insert(
+                db_tag,
+                KeyMetaEntry::new_from_sql(db_tag, &SqlField::new(1, &row))
+                    .context("Failed to read KeyMetaEntry.")?,
+            );
+            Ok(())
+        })
+        .context("In KeyMetaData::load_from_db.")?;
+
+        Ok(Self { data: metadata })
+    }
+
+    fn store_in_db(&self, key_id: i64, tx: &Transaction) -> Result<()> {
+        let mut stmt = tx
+            .prepare(
+                "INSERT or REPLACE INTO persistent.keymetadata (keyentryid, tag, data)
+                    VALUES (?, ?, ?);",
+            )
+            .context("In KeyMetaData::store_in_db: Failed to prepare statement.")?;
+
+        let iter = self.data.iter();
+        for (tag, entry) in iter {
+            stmt.insert(params![key_id, tag, entry,]).with_context(|| {
+                format!("In KeyMetaData::store_in_db: Failed to insert {:?}", entry)
+            })?;
+        }
+        Ok(())
+    }
+}
+
+impl_metadata!(
+    /// A set of metadata for key blobs.
+    #[derive(Debug, Default, Eq, PartialEq)]
+    pub struct BlobMetaData;
+    /// A metadata entry for key blobs.
+    #[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
+    pub enum BlobMetaEntry {
+        /// If present, indicates that the blob is encrypted with another key or a key derived
+        /// from a password.
+        EncryptedBy(EncryptedBy) with accessor encrypted_by,
+        /// If the blob is password encrypted this field is set to the
+        /// salt used for the key derivation.
+        Salt(Vec<u8>) with accessor salt,
+        /// If the blob is encrypted, this field is set to the initialization vector.
+        Iv(Vec<u8>) with accessor iv,
+        /// If the blob is encrypted, this field holds the AEAD TAG.
+        AeadTag(Vec<u8>) with accessor aead_tag,
+        /// The uuid of the owning KeyMint instance.
+        KmUuid(Uuid) with accessor km_uuid,
+        /// If the key is ECDH encrypted, this is the ephemeral public key
+        PublicKey(Vec<u8>) with accessor public_key,
+        /// If the key is encrypted with a MaxBootLevel key, this is the boot level
+        /// of that key
+        MaxBootLevel(i32) with accessor max_boot_level,
+        //  --- ADD NEW META DATA FIELDS HERE ---
+        // For backwards compatibility add new entries only to
+        // end of this list and above this comment.
+    };
+);
+
+impl BlobMetaData {
+    fn load_from_db(blob_id: i64, tx: &Transaction) -> Result<Self> {
+        let mut stmt = tx
+            .prepare(
+                "SELECT tag, data from persistent.blobmetadata
+                    WHERE blobentryid = ?;",
+            )
+            .context("In BlobMetaData::load_from_db: prepare statement failed.")?;
+
+        let mut metadata: HashMap<i64, BlobMetaEntry> = Default::default();
+
+        let mut rows =
+            stmt.query(params![blob_id]).context("In BlobMetaData::load_from_db: query failed.")?;
+        db_utils::with_rows_extract_all(&mut rows, |row| {
+            let db_tag: i64 = row.get(0).context("Failed to read tag.")?;
+            metadata.insert(
+                db_tag,
+                BlobMetaEntry::new_from_sql(db_tag, &SqlField::new(1, &row))
+                    .context("Failed to read BlobMetaEntry.")?,
+            );
+            Ok(())
+        })
+        .context("In BlobMetaData::load_from_db.")?;
+
+        Ok(Self { data: metadata })
+    }
+
+    fn store_in_db(&self, blob_id: i64, tx: &Transaction) -> Result<()> {
+        let mut stmt = tx
+            .prepare(
+                "INSERT or REPLACE INTO persistent.blobmetadata (blobentryid, tag, data)
+                    VALUES (?, ?, ?);",
+            )
+            .context("In BlobMetaData::store_in_db: Failed to prepare statement.")?;
+
+        let iter = self.data.iter();
+        for (tag, entry) in iter {
+            stmt.insert(params![blob_id, tag, entry,]).with_context(|| {
+                format!("In BlobMetaData::store_in_db: Failed to insert {:?}", entry)
+            })?;
+        }
+        Ok(())
+    }
+}
+
+/// Indicates the type of the keyentry.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
+pub enum KeyType {
+    /// This is a client key type. These keys are created or imported through the Keystore 2.0
+    /// AIDL interface android.system.keystore2.
+    Client,
+    /// This is a super key type. These keys are created by keystore itself and used to encrypt
+    /// other key blobs to provide LSKF binding.
+    Super,
+    /// This is an attestation key. These keys are created by the remote provisioning mechanism.
+    Attestation,
+}
+
+impl ToSql for KeyType {
+    fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
+        Ok(ToSqlOutput::Owned(Value::Integer(match self {
+            KeyType::Client => 0,
+            KeyType::Super => 1,
+            KeyType::Attestation => 2,
+        })))
+    }
+}
+
+impl FromSql for KeyType {
+    fn column_result(value: ValueRef) -> FromSqlResult<Self> {
+        match i64::column_result(value)? {
+            0 => Ok(KeyType::Client),
+            1 => Ok(KeyType::Super),
+            2 => Ok(KeyType::Attestation),
+            v => Err(FromSqlError::OutOfRange(v)),
+        }
+    }
+}
+
+/// Uuid representation that can be stored in the database.
+/// Right now it can only be initialized from SecurityLevel.
+/// Once KeyMint provides a UUID type a corresponding From impl shall be added.
+#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Uuid([u8; 16]);
+
+impl Deref for Uuid {
+    type Target = [u8; 16];
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl From<SecurityLevel> for Uuid {
+    fn from(sec_level: SecurityLevel) -> Self {
+        Self((sec_level.0 as u128).to_be_bytes())
+    }
+}
+
+impl ToSql for Uuid {
+    fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
+        self.0.to_sql()
+    }
+}
+
+impl FromSql for Uuid {
+    fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
+        let blob = Vec::<u8>::column_result(value)?;
+        if blob.len() != 16 {
+            return Err(FromSqlError::OutOfRange(blob.len() as i64));
+        }
+        let mut arr = [0u8; 16];
+        arr.copy_from_slice(&blob);
+        Ok(Self(arr))
+    }
+}
+
+/// Key entries that are not associated with any KeyMint instance, such as pure certificate
+/// entries are associated with this UUID.
+pub static KEYSTORE_UUID: Uuid = Uuid([
+    0x41, 0xe3, 0xb9, 0xce, 0x27, 0x58, 0x4e, 0x91, 0xbc, 0xfd, 0xa5, 0x5d, 0x91, 0x85, 0xab, 0x11,
+]);
+
+/// Indicates how the sensitive part of this key blob is encrypted.
+#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
+pub enum EncryptedBy {
+    /// The keyblob is encrypted by a user password.
+    /// In the database this variant is represented as NULL.
+    Password,
+    /// The keyblob is encrypted by another key with wrapped key id.
+    /// In the database this variant is represented as non NULL value
+    /// that is convertible to i64, typically NUMERIC.
+    KeyId(i64),
+}
+
+impl ToSql for EncryptedBy {
+    fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
+        match self {
+            Self::Password => Ok(ToSqlOutput::Owned(Value::Null)),
+            Self::KeyId(id) => id.to_sql(),
+        }
+    }
+}
+
+impl FromSql for EncryptedBy {
+    fn column_result(value: ValueRef) -> FromSqlResult<Self> {
+        match value {
+            ValueRef::Null => Ok(Self::Password),
+            _ => Ok(Self::KeyId(i64::column_result(value)?)),
+        }
+    }
+}
+
+/// A database representation of wall clock time. DateTime stores unix epoch time as
+/// i64 in milliseconds.
+#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)]
+pub struct DateTime(i64);
+
+/// Error type returned when creating DateTime or converting it from and to
+/// SystemTime.
+#[derive(thiserror::Error, Debug)]
+pub enum DateTimeError {
+    /// This is returned when SystemTime and Duration computations fail.
+    #[error(transparent)]
+    SystemTimeError(#[from] SystemTimeError),
+
+    /// This is returned when type conversions fail.
+    #[error(transparent)]
+    TypeConversion(#[from] std::num::TryFromIntError),
+
+    /// This is returned when checked time arithmetic failed.
+    #[error("Time arithmetic failed.")]
+    TimeArithmetic,
+}
+
+impl DateTime {
+    /// Constructs a new DateTime object denoting the current time. This may fail during
+    /// conversion to unix epoch time and during conversion to the internal i64 representation.
+    pub fn now() -> Result<Self, DateTimeError> {
+        Ok(Self(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis().try_into()?))
+    }
+
+    /// Constructs a new DateTime object from milliseconds.
+    pub fn from_millis_epoch(millis: i64) -> Self {
+        Self(millis)
+    }
+
+    /// Returns unix epoch time in milliseconds.
+    pub fn to_millis_epoch(&self) -> i64 {
+        self.0
+    }
+
+    /// Returns unix epoch time in seconds.
+    pub fn to_secs_epoch(&self) -> i64 {
+        self.0 / 1000
+    }
+}
+
+impl ToSql for DateTime {
+    fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
+        Ok(ToSqlOutput::Owned(Value::Integer(self.0)))
+    }
+}
+
+impl FromSql for DateTime {
+    fn column_result(value: ValueRef) -> FromSqlResult<Self> {
+        Ok(Self(i64::column_result(value)?))
+    }
+}
+
+impl TryInto<SystemTime> for DateTime {
+    type Error = DateTimeError;
+
+    fn try_into(self) -> Result<SystemTime, Self::Error> {
+        // We want to construct a SystemTime representation equivalent to self, denoting
+        // a point in time THEN, but we cannot set the time directly. We can only construct
+        // a SystemTime denoting NOW, and we can get the duration between EPOCH and NOW,
+        // and between EPOCH and THEN. With this common reference we can construct the
+        // duration between NOW and THEN which we can add to our SystemTime representation
+        // of NOW to get a SystemTime representation of THEN.
+        // Durations can only be positive, thus the if statement below.
+        let now = SystemTime::now();
+        let now_epoch = now.duration_since(SystemTime::UNIX_EPOCH)?;
+        let then_epoch = Duration::from_millis(self.0.try_into()?);
+        Ok(if now_epoch > then_epoch {
+            // then = now - (now_epoch - then_epoch)
+            now_epoch
+                .checked_sub(then_epoch)
+                .and_then(|d| now.checked_sub(d))
+                .ok_or(DateTimeError::TimeArithmetic)?
+        } else {
+            // then = now + (then_epoch - now_epoch)
+            then_epoch
+                .checked_sub(now_epoch)
+                .and_then(|d| now.checked_add(d))
+                .ok_or(DateTimeError::TimeArithmetic)?
+        })
+    }
+}
+
+impl TryFrom<SystemTime> for DateTime {
+    type Error = DateTimeError;
+
+    fn try_from(t: SystemTime) -> Result<Self, Self::Error> {
+        Ok(Self(t.duration_since(SystemTime::UNIX_EPOCH)?.as_millis().try_into()?))
+    }
+}
+
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
+enum KeyLifeCycle {
+    /// Existing keys have a key ID but are not fully populated yet.
+    /// This is a transient state. If Keystore finds any such keys when it starts up, it must move
+    /// them to Unreferenced for garbage collection.
+    Existing,
+    /// A live key is fully populated and usable by clients.
+    Live,
+    /// An unreferenced key is scheduled for garbage collection.
+    Unreferenced,
+}
+
+impl ToSql for KeyLifeCycle {
+    fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
+        match self {
+            Self::Existing => Ok(ToSqlOutput::Owned(Value::Integer(0))),
+            Self::Live => Ok(ToSqlOutput::Owned(Value::Integer(1))),
+            Self::Unreferenced => Ok(ToSqlOutput::Owned(Value::Integer(2))),
+        }
+    }
+}
+
+impl FromSql for KeyLifeCycle {
+    fn column_result(value: ValueRef) -> FromSqlResult<Self> {
+        match i64::column_result(value)? {
+            0 => Ok(KeyLifeCycle::Existing),
+            1 => Ok(KeyLifeCycle::Live),
+            2 => Ok(KeyLifeCycle::Unreferenced),
+            v => Err(FromSqlError::OutOfRange(v)),
+        }
+    }
+}
+
+/// Keys have a KeyMint blob component and optional public certificate and
+/// certificate chain components.
+/// KeyEntryLoadBits is a bitmap that indicates to `KeystoreDB::load_key_entry`
+/// which components shall be loaded from the database if present.
+#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
+pub struct KeyEntryLoadBits(u32);
+
+impl KeyEntryLoadBits {
+    /// Indicate to `KeystoreDB::load_key_entry` that no component shall be loaded.
+    pub const NONE: KeyEntryLoadBits = Self(0);
+    /// Indicate to `KeystoreDB::load_key_entry` that the KeyMint component shall be loaded.
+    pub const KM: KeyEntryLoadBits = Self(1);
+    /// Indicate to `KeystoreDB::load_key_entry` that the Public components shall be loaded.
+    pub const PUBLIC: KeyEntryLoadBits = Self(2);
+    /// Indicate to `KeystoreDB::load_key_entry` that both components shall be loaded.
+    pub const BOTH: KeyEntryLoadBits = Self(3);
+
+    /// Returns true if this object indicates that the public components shall be loaded.
+    pub const fn load_public(&self) -> bool {
+        self.0 & Self::PUBLIC.0 != 0
+    }
+
+    /// Returns true if the object indicates that the KeyMint component shall be loaded.
+    pub const fn load_km(&self) -> bool {
+        self.0 & Self::KM.0 != 0
+    }
+}
+
+lazy_static! {
+    static ref KEY_ID_LOCK: KeyIdLockDb = KeyIdLockDb::new();
+}
+
+struct KeyIdLockDb {
+    locked_keys: Mutex<HashSet<i64>>,
+    cond_var: Condvar,
+}
+
+/// A locked key. While a guard exists for a given key id, the same key cannot be loaded
+/// from the database a second time. Most functions manipulating the key blob database
+/// require a KeyIdGuard.
+#[derive(Debug)]
+pub struct KeyIdGuard(i64);
+
+impl KeyIdLockDb {
+    fn new() -> Self {
+        Self { locked_keys: Mutex::new(HashSet::new()), cond_var: Condvar::new() }
+    }
+
+    /// This function blocks until an exclusive lock for the given key entry id can
+    /// be acquired. It returns a guard object, that represents the lifecycle of the
+    /// acquired lock.
+    pub fn get(&self, key_id: i64) -> KeyIdGuard {
+        let mut locked_keys = self.locked_keys.lock().unwrap();
+        while locked_keys.contains(&key_id) {
+            locked_keys = self.cond_var.wait(locked_keys).unwrap();
+        }
+        locked_keys.insert(key_id);
+        KeyIdGuard(key_id)
+    }
+
+    /// This function attempts to acquire an exclusive lock on a given key id. If the
+    /// given key id is already taken the function returns None immediately. If a lock
+    /// can be acquired this function returns a guard object, that represents the
+    /// lifecycle of the acquired lock.
+    pub fn try_get(&self, key_id: i64) -> Option<KeyIdGuard> {
+        let mut locked_keys = self.locked_keys.lock().unwrap();
+        if locked_keys.insert(key_id) {
+            Some(KeyIdGuard(key_id))
+        } else {
+            None
+        }
+    }
+}
+
+impl KeyIdGuard {
+    /// Get the numeric key id of the locked key.
+    pub fn id(&self) -> i64 {
+        self.0
+    }
+}
+
+impl Drop for KeyIdGuard {
+    fn drop(&mut self) {
+        let mut locked_keys = KEY_ID_LOCK.locked_keys.lock().unwrap();
+        locked_keys.remove(&self.0);
+        drop(locked_keys);
+        KEY_ID_LOCK.cond_var.notify_all();
+    }
+}
+
+/// This type represents a certificate and certificate chain entry for a key.
+#[derive(Debug, Default)]
+pub struct CertificateInfo {
+    cert: Option<Vec<u8>>,
+    cert_chain: Option<Vec<u8>>,
+}
+
+impl CertificateInfo {
+    /// Constructs a new CertificateInfo object from `cert` and `cert_chain`
+    pub fn new(cert: Option<Vec<u8>>, cert_chain: Option<Vec<u8>>) -> Self {
+        Self { cert, cert_chain }
+    }
+
+    /// Take the cert
+    pub fn take_cert(&mut self) -> Option<Vec<u8>> {
+        self.cert.take()
+    }
+
+    /// Take the cert chain
+    pub fn take_cert_chain(&mut self) -> Option<Vec<u8>> {
+        self.cert_chain.take()
+    }
+}
+
+/// This type represents a certificate chain with a private key corresponding to the leaf
+/// certificate. TODO(jbires): This will be used in a follow-on CL, for now it's used in the tests.
+pub struct CertificateChain {
+    /// A KM key blob
+    pub private_key: ZVec,
+    /// A batch cert for private_key
+    pub batch_cert: Vec<u8>,
+    /// A full certificate chain from root signing authority to private_key, including batch_cert
+    /// for convenience.
+    pub cert_chain: Vec<u8>,
+}
+
+/// This type represents a Keystore 2.0 key entry.
+/// An entry has a unique `id` by which it can be found in the database.
+/// It has a security level field, key parameters, and three optional fields
+/// for the KeyMint blob, public certificate and a public certificate chain.
+#[derive(Debug, Default, Eq, PartialEq)]
+pub struct KeyEntry {
+    id: i64,
+    key_blob_info: Option<(Vec<u8>, BlobMetaData)>,
+    cert: Option<Vec<u8>>,
+    cert_chain: Option<Vec<u8>>,
+    km_uuid: Uuid,
+    parameters: Vec<KeyParameter>,
+    metadata: KeyMetaData,
+    pure_cert: bool,
+}
+
+impl KeyEntry {
+    /// Returns the unique id of the Key entry.
+    pub fn id(&self) -> i64 {
+        self.id
+    }
+    /// Exposes the optional KeyMint blob.
+    pub fn key_blob_info(&self) -> &Option<(Vec<u8>, BlobMetaData)> {
+        &self.key_blob_info
+    }
+    /// Extracts the Optional KeyMint blob including its metadata.
+    pub fn take_key_blob_info(&mut self) -> Option<(Vec<u8>, BlobMetaData)> {
+        self.key_blob_info.take()
+    }
+    /// Exposes the optional public certificate.
+    pub fn cert(&self) -> &Option<Vec<u8>> {
+        &self.cert
+    }
+    /// Extracts the optional public certificate.
+    pub fn take_cert(&mut self) -> Option<Vec<u8>> {
+        self.cert.take()
+    }
+    /// Exposes the optional public certificate chain.
+    pub fn cert_chain(&self) -> &Option<Vec<u8>> {
+        &self.cert_chain
+    }
+    /// Extracts the optional public certificate_chain.
+    pub fn take_cert_chain(&mut self) -> Option<Vec<u8>> {
+        self.cert_chain.take()
+    }
+    /// Returns the uuid of the owning KeyMint instance.
+    pub fn km_uuid(&self) -> &Uuid {
+        &self.km_uuid
+    }
+    /// Exposes the key parameters of this key entry.
+    pub fn key_parameters(&self) -> &Vec<KeyParameter> {
+        &self.parameters
+    }
+    /// Consumes this key entry and extracts the keyparameters from it.
+    pub fn into_key_parameters(self) -> Vec<KeyParameter> {
+        self.parameters
+    }
+    /// Exposes the key metadata of this key entry.
+    pub fn metadata(&self) -> &KeyMetaData {
+        &self.metadata
+    }
+    /// This returns true if the entry is a pure certificate entry with no
+    /// private key component.
+    pub fn pure_cert(&self) -> bool {
+        self.pure_cert
+    }
+    /// Consumes this key entry and extracts the keyparameters and metadata from it.
+    pub fn into_key_parameters_and_metadata(self) -> (Vec<KeyParameter>, KeyMetaData) {
+        (self.parameters, self.metadata)
+    }
+}
+
+/// Indicates the sub component of a key entry for persistent storage.
+#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
+pub struct SubComponentType(u32);
+impl SubComponentType {
+    /// Persistent identifier for a key blob.
+    pub const KEY_BLOB: SubComponentType = Self(0);
+    /// Persistent identifier for a certificate blob.
+    pub const CERT: SubComponentType = Self(1);
+    /// Persistent identifier for a certificate chain blob.
+    pub const CERT_CHAIN: SubComponentType = Self(2);
+}
+
+impl ToSql for SubComponentType {
+    fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
+        self.0.to_sql()
+    }
+}
+
+impl FromSql for SubComponentType {
+    fn column_result(value: ValueRef) -> FromSqlResult<Self> {
+        Ok(Self(u32::column_result(value)?))
+    }
+}
+
+/// This trait is private to the database module. It is used to convey whether or not the garbage
+/// collector shall be invoked after a database access. All closures passed to
+/// `KeystoreDB::with_transaction` return a tuple (bool, T) where the bool indicates if the
+/// gc needs to be triggered. This convenience function allows to turn any anyhow::Result<T>
+/// into anyhow::Result<(bool, T)> by simply appending one of `.do_gc(bool)`, `.no_gc()`, or
+/// `.need_gc()`.
+trait DoGc<T> {
+    fn do_gc(self, need_gc: bool) -> Result<(bool, T)>;
+
+    fn no_gc(self) -> Result<(bool, T)>;
+
+    fn need_gc(self) -> Result<(bool, T)>;
+}
+
+impl<T> DoGc<T> for Result<T> {
+    fn do_gc(self, need_gc: bool) -> Result<(bool, T)> {
+        self.map(|r| (need_gc, r))
+    }
+
+    fn no_gc(self) -> Result<(bool, T)> {
+        self.do_gc(false)
+    }
+
+    fn need_gc(self) -> Result<(bool, T)> {
+        self.do_gc(true)
+    }
+}
+
+/// KeystoreDB wraps a connection to an SQLite database and tracks its
+/// ownership. It also implements all of Keystore 2.0's database functionality.
+pub struct KeystoreDB {
+    conn: Connection,
+    gc: Option<Arc<Gc>>,
+}
+
+/// Database representation of the monotonic time retrieved from the system call clock_gettime with
+/// CLOCK_MONOTONIC_RAW. Stores monotonic time as i64 in seconds.
+#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd)]
+pub struct MonotonicRawTime(i64);
+
+impl MonotonicRawTime {
+    /// Constructs a new MonotonicRawTime
+    pub fn now() -> Self {
+        Self(get_current_time_in_seconds())
+    }
+
+    /// Constructs a new MonotonicRawTime from a given number of seconds.
+    pub fn from_secs(val: i64) -> Self {
+        Self(val)
+    }
+
+    /// Returns the integer value of MonotonicRawTime as i64
+    pub fn seconds(&self) -> i64 {
+        self.0
+    }
+
+    /// Returns the value of MonotonicRawTime in milli seconds as i64
+    pub fn milli_seconds(&self) -> i64 {
+        self.0 * 1000
+    }
+
+    /// Like i64::checked_sub.
+    pub fn checked_sub(&self, other: &Self) -> Option<Self> {
+        self.0.checked_sub(other.0).map(Self)
+    }
+}
+
+impl ToSql for MonotonicRawTime {
+    fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
+        Ok(ToSqlOutput::Owned(Value::Integer(self.0)))
+    }
+}
+
+impl FromSql for MonotonicRawTime {
+    fn column_result(value: ValueRef) -> FromSqlResult<Self> {
+        Ok(Self(i64::column_result(value)?))
+    }
+}
+
+/// This struct encapsulates the information to be stored in the database about the auth tokens
+/// received by keystore.
+pub struct AuthTokenEntry {
+    auth_token: HardwareAuthToken,
+    time_received: MonotonicRawTime,
+}
+
+impl AuthTokenEntry {
+    fn new(auth_token: HardwareAuthToken, time_received: MonotonicRawTime) -> Self {
+        AuthTokenEntry { auth_token, time_received }
+    }
+
+    /// Checks if this auth token satisfies the given authentication information.
+    pub fn satisfies(&self, user_secure_ids: &[i64], auth_type: HardwareAuthenticatorType) -> bool {
+        user_secure_ids.iter().any(|&sid| {
+            (sid == self.auth_token.userId || sid == self.auth_token.authenticatorId)
+                && (((auth_type.0 as i32) & (self.auth_token.authenticatorType.0 as i32)) != 0)
+        })
+    }
+
+    /// Returns the auth token wrapped by the AuthTokenEntry
+    pub fn auth_token(&self) -> &HardwareAuthToken {
+        &self.auth_token
+    }
+
+    /// Returns the auth token wrapped by the AuthTokenEntry
+    pub fn take_auth_token(self) -> HardwareAuthToken {
+        self.auth_token
+    }
+
+    /// Returns the time that this auth token was received.
+    pub fn time_received(&self) -> MonotonicRawTime {
+        self.time_received
+    }
+
+    /// Returns the challenge value of the auth token.
+    pub fn challenge(&self) -> i64 {
+        self.auth_token.challenge
+    }
+}
+
+/// Shared in-memory databases get destroyed as soon as the last connection to them gets closed.
+/// This object does not allow access to the database connection. But it keeps a database
+/// connection alive in order to keep the in memory per boot database alive.
+pub struct PerBootDbKeepAlive(Connection);
+
+impl KeystoreDB {
+    const UNASSIGNED_KEY_ID: i64 = -1i64;
+    const PERBOOT_DB_FILE_NAME: &'static str = &"file:perboot.sqlite?mode=memory&cache=shared";
+
+    /// Name of the file that holds the cross-boot persistent database.
+    pub const PERSISTENT_DB_FILENAME: &'static str = &"persistent.sqlite";
+
+    /// This creates a PerBootDbKeepAlive object to keep the per boot database alive.
+    pub fn keep_perboot_db_alive() -> Result<PerBootDbKeepAlive> {
+        let conn = Connection::open_in_memory()
+            .context("In keep_perboot_db_alive: Failed to initialize SQLite connection.")?;
+
+        conn.execute("ATTACH DATABASE ? as perboot;", params![Self::PERBOOT_DB_FILE_NAME])
+            .context("In keep_perboot_db_alive: Failed to attach database perboot.")?;
+        Ok(PerBootDbKeepAlive(conn))
+    }
+
+    /// This will create a new database connection connecting the two
+    /// files persistent.sqlite and perboot.sqlite in the given directory.
+    /// It also attempts to initialize all of the tables.
+    /// KeystoreDB cannot be used by multiple threads.
+    /// Each thread should open their own connection using `thread_local!`.
+    pub fn new(db_root: &Path, gc: Option<Arc<Gc>>) -> Result<Self> {
+        let _wp = wd::watch_millis("KeystoreDB::new", 500);
+
+        // Build the path to the sqlite file.
+        let mut persistent_path = db_root.to_path_buf();
+        persistent_path.push(Self::PERSISTENT_DB_FILENAME);
+
+        // Now convert them to strings prefixed with "file:"
+        let mut persistent_path_str = "file:".to_owned();
+        persistent_path_str.push_str(&persistent_path.to_string_lossy());
+
+        let conn = Self::make_connection(&persistent_path_str, &Self::PERBOOT_DB_FILE_NAME)?;
+
+        // On busy fail Immediately. It is unlikely to succeed given a bug in sqlite.
+        conn.busy_handler(None).context("In KeystoreDB::new: Failed to set busy handler.")?;
+
+        let mut db = Self { conn, gc };
+        db.with_transaction(TransactionBehavior::Immediate, |tx| {
+            Self::init_tables(tx).context("Trying to initialize tables.").no_gc()
+        })?;
+        Ok(db)
+    }
+
+    fn init_tables(tx: &Transaction) -> Result<()> {
+        tx.execute(
+            "CREATE TABLE IF NOT EXISTS persistent.keyentry (
+                     id INTEGER UNIQUE,
+                     key_type INTEGER,
+                     domain INTEGER,
+                     namespace INTEGER,
+                     alias BLOB,
+                     state INTEGER,
+                     km_uuid BLOB);",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"keyentry\" table.")?;
+
+        tx.execute(
+            "CREATE INDEX IF NOT EXISTS persistent.keyentry_id_index
+            ON keyentry(id);",
+            NO_PARAMS,
+        )
+        .context("Failed to create index keyentry_id_index.")?;
+
+        tx.execute(
+            "CREATE INDEX IF NOT EXISTS persistent.keyentry_domain_namespace_index
+            ON keyentry(domain, namespace, alias);",
+            NO_PARAMS,
+        )
+        .context("Failed to create index keyentry_domain_namespace_index.")?;
+
+        tx.execute(
+            "CREATE TABLE IF NOT EXISTS persistent.blobentry (
+                    id INTEGER PRIMARY KEY,
+                    subcomponent_type INTEGER,
+                    keyentryid INTEGER,
+                    blob BLOB);",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"blobentry\" table.")?;
+
+        tx.execute(
+            "CREATE INDEX IF NOT EXISTS persistent.blobentry_keyentryid_index
+            ON blobentry(keyentryid);",
+            NO_PARAMS,
+        )
+        .context("Failed to create index blobentry_keyentryid_index.")?;
+
+        tx.execute(
+            "CREATE TABLE IF NOT EXISTS persistent.blobmetadata (
+                     id INTEGER PRIMARY KEY,
+                     blobentryid INTEGER,
+                     tag INTEGER,
+                     data ANY,
+                     UNIQUE (blobentryid, tag));",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"blobmetadata\" table.")?;
+
+        tx.execute(
+            "CREATE INDEX IF NOT EXISTS persistent.blobmetadata_blobentryid_index
+            ON blobmetadata(blobentryid);",
+            NO_PARAMS,
+        )
+        .context("Failed to create index blobmetadata_blobentryid_index.")?;
+
+        tx.execute(
+            "CREATE TABLE IF NOT EXISTS persistent.keyparameter (
+                     keyentryid INTEGER,
+                     tag INTEGER,
+                     data ANY,
+                     security_level INTEGER);",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"keyparameter\" table.")?;
+
+        tx.execute(
+            "CREATE INDEX IF NOT EXISTS persistent.keyparameter_keyentryid_index
+            ON keyparameter(keyentryid);",
+            NO_PARAMS,
+        )
+        .context("Failed to create index keyparameter_keyentryid_index.")?;
+
+        tx.execute(
+            "CREATE TABLE IF NOT EXISTS persistent.keymetadata (
+                     keyentryid INTEGER,
+                     tag INTEGER,
+                     data ANY,
+                     UNIQUE (keyentryid, tag));",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"keymetadata\" table.")?;
+
+        tx.execute(
+            "CREATE INDEX IF NOT EXISTS persistent.keymetadata_keyentryid_index
+            ON keymetadata(keyentryid);",
+            NO_PARAMS,
+        )
+        .context("Failed to create index keymetadata_keyentryid_index.")?;
+
+        tx.execute(
+            "CREATE TABLE IF NOT EXISTS persistent.grant (
+                    id INTEGER UNIQUE,
+                    grantee INTEGER,
+                    keyentryid INTEGER,
+                    access_vector INTEGER);",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"grant\" table.")?;
+
+        //TODO: only drop the following two perboot tables if this is the first start up
+        //during the boot (b/175716626).
+        // tx.execute("DROP TABLE IF EXISTS perboot.authtoken;", NO_PARAMS)
+        //     .context("Failed to drop perboot.authtoken table")?;
+        tx.execute(
+            "CREATE TABLE IF NOT EXISTS perboot.authtoken (
+                        id INTEGER PRIMARY KEY,
+                        challenge INTEGER,
+                        user_id INTEGER,
+                        auth_id INTEGER,
+                        authenticator_type INTEGER,
+                        timestamp INTEGER,
+                        mac BLOB,
+                        time_received INTEGER,
+                        UNIQUE(user_id, auth_id, authenticator_type));",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"authtoken\" table.")?;
+
+        // tx.execute("DROP TABLE IF EXISTS perboot.metadata;", NO_PARAMS)
+        //     .context("Failed to drop perboot.metadata table")?;
+        // metadata table stores certain miscellaneous information required for keystore functioning
+        // during a boot cycle, as key-value pairs.
+        tx.execute(
+            "CREATE TABLE IF NOT EXISTS perboot.metadata (
+                        key TEXT,
+                        value BLOB,
+                        UNIQUE(key));",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"metadata\" table.")?;
+        Ok(())
+    }
+
+    fn make_connection(persistent_file: &str, perboot_file: &str) -> Result<Connection> {
+        let conn =
+            Connection::open_in_memory().context("Failed to initialize SQLite connection.")?;
+
+        loop {
+            if let Err(e) = conn
+                .execute("ATTACH DATABASE ? as persistent;", params![persistent_file])
+                .context("Failed to attach database persistent.")
+            {
+                if Self::is_locked_error(&e) {
+                    std::thread::sleep(std::time::Duration::from_micros(500));
+                    continue;
+                } else {
+                    return Err(e);
+                }
+            }
+            break;
+        }
+        loop {
+            if let Err(e) = conn
+                .execute("ATTACH DATABASE ? as perboot;", params![perboot_file])
+                .context("Failed to attach database perboot.")
+            {
+                if Self::is_locked_error(&e) {
+                    std::thread::sleep(std::time::Duration::from_micros(500));
+                    continue;
+                } else {
+                    return Err(e);
+                }
+            }
+            break;
+        }
+
+        Ok(conn)
+    }
+
+    fn do_table_size_query(
+        &mut self,
+        storage_type: StatsdStorageType,
+        query: &str,
+        params: &[&str],
+    ) -> Result<Keystore2StorageStats> {
+        let (total, unused) = self.with_transaction(TransactionBehavior::Deferred, |tx| {
+            tx.query_row(query, params, |row| Ok((row.get(0)?, row.get(1)?)))
+                .with_context(|| {
+                    format!("get_storage_stat: Error size of storage type {}", storage_type as i32)
+                })
+                .no_gc()
+        })?;
+        Ok(Keystore2StorageStats { storage_type, size: total, unused_size: unused })
+    }
+
+    fn get_total_size(&mut self) -> Result<Keystore2StorageStats> {
+        self.do_table_size_query(
+            StatsdStorageType::Database,
+            "SELECT page_count * page_size, freelist_count * page_size
+             FROM pragma_page_count('persistent'),
+                  pragma_page_size('persistent'),
+                  persistent.pragma_freelist_count();",
+            &[],
+        )
+    }
+
+    fn get_table_size(
+        &mut self,
+        storage_type: StatsdStorageType,
+        schema: &str,
+        table: &str,
+    ) -> Result<Keystore2StorageStats> {
+        self.do_table_size_query(
+            storage_type,
+            "SELECT pgsize,unused FROM dbstat(?1)
+             WHERE name=?2 AND aggregate=TRUE;",
+            &[schema, table],
+        )
+    }
+
+    /// Fetches a storage statisitics atom for a given storage type. For storage
+    /// types that map to a table, information about the table's storage is
+    /// returned. Requests for storage types that are not DB tables return None.
+    pub fn get_storage_stat(
+        &mut self,
+        storage_type: StatsdStorageType,
+    ) -> Result<Keystore2StorageStats> {
+        let _wp = wd::watch_millis("KeystoreDB::get_storage_stat", 500);
+
+        match storage_type {
+            StatsdStorageType::Database => self.get_total_size(),
+            StatsdStorageType::KeyEntry => {
+                self.get_table_size(storage_type, "persistent", "keyentry")
+            }
+            StatsdStorageType::KeyEntryIdIndex => {
+                self.get_table_size(storage_type, "persistent", "keyentry_id_index")
+            }
+            StatsdStorageType::KeyEntryDomainNamespaceIndex => {
+                self.get_table_size(storage_type, "persistent", "keyentry_domain_namespace_index")
+            }
+            StatsdStorageType::BlobEntry => {
+                self.get_table_size(storage_type, "persistent", "blobentry")
+            }
+            StatsdStorageType::BlobEntryKeyEntryIdIndex => {
+                self.get_table_size(storage_type, "persistent", "blobentry_keyentryid_index")
+            }
+            StatsdStorageType::KeyParameter => {
+                self.get_table_size(storage_type, "persistent", "keyparameter")
+            }
+            StatsdStorageType::KeyParameterKeyEntryIdIndex => {
+                self.get_table_size(storage_type, "persistent", "keyparameter_keyentryid_index")
+            }
+            StatsdStorageType::KeyMetadata => {
+                self.get_table_size(storage_type, "persistent", "keymetadata")
+            }
+            StatsdStorageType::KeyMetadataKeyEntryIdIndex => {
+                self.get_table_size(storage_type, "persistent", "keymetadata_keyentryid_index")
+            }
+            StatsdStorageType::Grant => self.get_table_size(storage_type, "persistent", "grant"),
+            StatsdStorageType::AuthToken => {
+                self.get_table_size(storage_type, "perboot", "authtoken")
+            }
+            StatsdStorageType::BlobMetadata => {
+                self.get_table_size(storage_type, "persistent", "blobmetadata")
+            }
+            StatsdStorageType::BlobMetadataBlobEntryIdIndex => {
+                self.get_table_size(storage_type, "persistent", "blobmetadata_blobentryid_index")
+            }
+            _ => Err(anyhow::Error::msg(format!(
+                "Unsupported storage type: {}",
+                storage_type as i32
+            ))),
+        }
+    }
+
+    /// This function is intended to be used by the garbage collector.
+    /// It deletes the blobs given by `blob_ids_to_delete`. It then tries to find up to `max_blobs`
+    /// superseded key blobs that might need special handling by the garbage collector.
+    /// If no further superseded blobs can be found it deletes all other superseded blobs that don't
+    /// need special handling and returns None.
+    pub fn handle_next_superseded_blobs(
+        &mut self,
+        blob_ids_to_delete: &[i64],
+        max_blobs: usize,
+    ) -> Result<Vec<(i64, Vec<u8>, BlobMetaData)>> {
+        let _wp = wd::watch_millis("KeystoreDB::handle_next_superseded_blob", 500);
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            // Delete the given blobs.
+            for blob_id in blob_ids_to_delete {
+                tx.execute(
+                    "DELETE FROM persistent.blobmetadata WHERE blobentryid = ?;",
+                    params![blob_id],
+                )
+                .context("Trying to delete blob metadata.")?;
+                tx.execute("DELETE FROM persistent.blobentry WHERE id = ?;", params![blob_id])
+                    .context("Trying to blob.")?;
+            }
+
+            Self::cleanup_unreferenced(tx).context("Trying to cleanup unreferenced.")?;
+
+            // Find up to max_blobx more superseded key blobs, load their metadata and return it.
+            let result: Vec<(i64, Vec<u8>)> = {
+                let mut stmt = tx
+                    .prepare(
+                        "SELECT id, blob FROM persistent.blobentry
+                        WHERE subcomponent_type = ?
+                        AND (
+                            id NOT IN (
+                                SELECT MAX(id) FROM persistent.blobentry
+                                WHERE subcomponent_type = ?
+                                GROUP BY keyentryid, subcomponent_type
+                            )
+                        OR keyentryid NOT IN (SELECT id FROM persistent.keyentry)
+                    ) LIMIT ?;",
+                    )
+                    .context("Trying to prepare query for superseded blobs.")?;
+
+                let rows = stmt
+                    .query_map(
+                        params![
+                            SubComponentType::KEY_BLOB,
+                            SubComponentType::KEY_BLOB,
+                            max_blobs as i64,
+                        ],
+                        |row| Ok((row.get(0)?, row.get(1)?)),
+                    )
+                    .context("Trying to query superseded blob.")?;
+
+                rows.collect::<Result<Vec<(i64, Vec<u8>)>, rusqlite::Error>>()
+                    .context("Trying to extract superseded blobs.")?
+            };
+
+            let result = result
+                .into_iter()
+                .map(|(blob_id, blob)| {
+                    Ok((blob_id, blob, BlobMetaData::load_from_db(blob_id, tx)?))
+                })
+                .collect::<Result<Vec<(i64, Vec<u8>, BlobMetaData)>>>()
+                .context("Trying to load blob metadata.")?;
+            if !result.is_empty() {
+                return Ok(result).no_gc();
+            }
+
+            // We did not find any superseded key blob, so let's remove other superseded blob in
+            // one transaction.
+            tx.execute(
+                "DELETE FROM persistent.blobentry
+                 WHERE NOT subcomponent_type = ?
+                 AND (
+                     id NOT IN (
+                        SELECT MAX(id) FROM persistent.blobentry
+                        WHERE NOT subcomponent_type = ?
+                        GROUP BY keyentryid, subcomponent_type
+                     ) OR keyentryid NOT IN (SELECT id FROM persistent.keyentry)
+                 );",
+                params![SubComponentType::KEY_BLOB, SubComponentType::KEY_BLOB],
+            )
+            .context("Trying to purge superseded blobs.")?;
+
+            Ok(vec![]).no_gc()
+        })
+        .context("In handle_next_superseded_blobs.")
+    }
+
+    /// This maintenance function should be called only once before the database is used for the
+    /// first time. It restores the invariant that `KeyLifeCycle::Existing` is a transient state.
+    /// The function transitions all key entries from Existing to Unreferenced unconditionally and
+    /// returns the number of rows affected. If this returns a value greater than 0, it means that
+    /// Keystore crashed at some point during key generation. Callers may want to log such
+    /// occurrences.
+    /// Unlike with `mark_unreferenced`, we don't need to purge grants, because only keys that made
+    /// it to `KeyLifeCycle::Live` may have grants.
+    pub fn cleanup_leftovers(&mut self) -> Result<usize> {
+        let _wp = wd::watch_millis("KeystoreDB::cleanup_leftovers", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "UPDATE persistent.keyentry SET state = ? WHERE state = ?;",
+                params![KeyLifeCycle::Unreferenced, KeyLifeCycle::Existing],
+            )
+            .context("Failed to execute query.")
+            .need_gc()
+        })
+        .context("In cleanup_leftovers.")
+    }
+
+    /// Checks if a key exists with given key type and key descriptor properties.
+    pub fn key_exists(
+        &mut self,
+        domain: Domain,
+        nspace: i64,
+        alias: &str,
+        key_type: KeyType,
+    ) -> Result<bool> {
+        let _wp = wd::watch_millis("KeystoreDB::key_exists", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let key_descriptor =
+                KeyDescriptor { domain, nspace, alias: Some(alias.to_string()), blob: None };
+            let result = Self::load_key_entry_id(&tx, &key_descriptor, key_type);
+            match result {
+                Ok(_) => Ok(true),
+                Err(error) => match error.root_cause().downcast_ref::<KsError>() {
+                    Some(KsError::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(false),
+                    _ => Err(error).context("In key_exists: Failed to find if the key exists."),
+                },
+            }
+            .no_gc()
+        })
+        .context("In key_exists.")
+    }
+
+    /// Stores a super key in the database.
+    pub fn store_super_key(
+        &mut self,
+        user_id: u32,
+        key_type: &SuperKeyType,
+        blob: &[u8],
+        blob_metadata: &BlobMetaData,
+        key_metadata: &KeyMetaData,
+    ) -> Result<KeyEntry> {
+        let _wp = wd::watch_millis("KeystoreDB::store_super_key", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let key_id = Self::insert_with_retry(|id| {
+                tx.execute(
+                    "INSERT into persistent.keyentry
+                            (id, key_type, domain, namespace, alias, state, km_uuid)
+                            VALUES(?, ?, ?, ?, ?, ?, ?);",
+                    params![
+                        id,
+                        KeyType::Super,
+                        Domain::APP.0,
+                        user_id as i64,
+                        key_type.alias,
+                        KeyLifeCycle::Live,
+                        &KEYSTORE_UUID,
+                    ],
+                )
+            })
+            .context("Failed to insert into keyentry table.")?;
+
+            key_metadata.store_in_db(key_id, tx).context("KeyMetaData::store_in_db failed")?;
+
+            Self::set_blob_internal(
+                &tx,
+                key_id,
+                SubComponentType::KEY_BLOB,
+                Some(blob),
+                Some(blob_metadata),
+            )
+            .context("Failed to store key blob.")?;
+
+            Self::load_key_components(tx, KeyEntryLoadBits::KM, key_id)
+                .context("Trying to load key components.")
+                .no_gc()
+        })
+        .context("In store_super_key.")
+    }
+
+    /// Loads super key of a given user, if exists
+    pub fn load_super_key(
+        &mut self,
+        key_type: &SuperKeyType,
+        user_id: u32,
+    ) -> Result<Option<(KeyIdGuard, KeyEntry)>> {
+        let _wp = wd::watch_millis("KeystoreDB::load_super_key", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let key_descriptor = KeyDescriptor {
+                domain: Domain::APP,
+                nspace: user_id as i64,
+                alias: Some(key_type.alias.into()),
+                blob: None,
+            };
+            let id = Self::load_key_entry_id(&tx, &key_descriptor, KeyType::Super);
+            match id {
+                Ok(id) => {
+                    let key_entry = Self::load_key_components(&tx, KeyEntryLoadBits::KM, id)
+                        .context("In load_super_key. Failed to load key entry.")?;
+                    Ok(Some((KEY_ID_LOCK.get(id), key_entry)))
+                }
+                Err(error) => match error.root_cause().downcast_ref::<KsError>() {
+                    Some(KsError::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None),
+                    _ => Err(error).context("In load_super_key."),
+                },
+            }
+            .no_gc()
+        })
+        .context("In load_super_key.")
+    }
+
+    /// Atomically loads a key entry and associated metadata or creates it using the
+    /// callback create_new_key callback. The callback is called during a database
+    /// transaction. This means that implementers should be mindful about using
+    /// blocking operations such as IPC or grabbing mutexes.
+    pub fn get_or_create_key_with<F>(
+        &mut self,
+        domain: Domain,
+        namespace: i64,
+        alias: &str,
+        km_uuid: Uuid,
+        create_new_key: F,
+    ) -> Result<(KeyIdGuard, KeyEntry)>
+    where
+        F: Fn() -> Result<(Vec<u8>, BlobMetaData)>,
+    {
+        let _wp = wd::watch_millis("KeystoreDB::get_or_create_key_with", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let id = {
+                let mut stmt = tx
+                    .prepare(
+                        "SELECT id FROM persistent.keyentry
+                    WHERE
+                    key_type = ?
+                    AND domain = ?
+                    AND namespace = ?
+                    AND alias = ?
+                    AND state = ?;",
+                    )
+                    .context("In get_or_create_key_with: Failed to select from keyentry table.")?;
+                let mut rows = stmt
+                    .query(params![KeyType::Super, domain.0, namespace, alias, KeyLifeCycle::Live])
+                    .context("In get_or_create_key_with: Failed to query from keyentry table.")?;
+
+                db_utils::with_rows_extract_one(&mut rows, |row| {
+                    Ok(match row {
+                        Some(r) => r.get(0).context("Failed to unpack id.")?,
+                        None => None,
+                    })
+                })
+                .context("In get_or_create_key_with.")?
+            };
+
+            let (id, entry) = match id {
+                Some(id) => (
+                    id,
+                    Self::load_key_components(&tx, KeyEntryLoadBits::KM, id)
+                        .context("In get_or_create_key_with.")?,
+                ),
+
+                None => {
+                    let id = Self::insert_with_retry(|id| {
+                        tx.execute(
+                            "INSERT into persistent.keyentry
+                        (id, key_type, domain, namespace, alias, state, km_uuid)
+                        VALUES(?, ?, ?, ?, ?, ?, ?);",
+                            params![
+                                id,
+                                KeyType::Super,
+                                domain.0,
+                                namespace,
+                                alias,
+                                KeyLifeCycle::Live,
+                                km_uuid,
+                            ],
+                        )
+                    })
+                    .context("In get_or_create_key_with.")?;
+
+                    let (blob, metadata) =
+                        create_new_key().context("In get_or_create_key_with.")?;
+                    Self::set_blob_internal(
+                        &tx,
+                        id,
+                        SubComponentType::KEY_BLOB,
+                        Some(&blob),
+                        Some(&metadata),
+                    )
+                    .context("In get_or_create_key_with.")?;
+                    (
+                        id,
+                        KeyEntry {
+                            id,
+                            key_blob_info: Some((blob, metadata)),
+                            pure_cert: false,
+                            ..Default::default()
+                        },
+                    )
+                }
+            };
+            Ok((KEY_ID_LOCK.get(id), entry)).no_gc()
+        })
+        .context("In get_or_create_key_with.")
+    }
+
+    /// SQLite3 seems to hold a shared mutex while running the busy handler when
+    /// waiting for the database file to become available. This makes it
+    /// impossible to successfully recover from a locked database when the
+    /// transaction holding the device busy is in the same process on a
+    /// different connection. As a result the busy handler has to time out and
+    /// fail in order to make progress.
+    ///
+    /// Instead, we set the busy handler to None (return immediately). And catch
+    /// Busy and Locked errors (the latter occur on in memory databases with
+    /// shared cache, e.g., the per-boot database.) and restart the transaction
+    /// after a grace period of half a millisecond.
+    ///
+    /// Creates a transaction with the given behavior and executes f with the new transaction.
+    /// The transaction is committed only if f returns Ok and retried if DatabaseBusy
+    /// or DatabaseLocked is encountered.
+    fn with_transaction<T, F>(&mut self, behavior: TransactionBehavior, f: F) -> Result<T>
+    where
+        F: Fn(&Transaction) -> Result<(bool, T)>,
+    {
+        loop {
+            match self
+                .conn
+                .transaction_with_behavior(behavior)
+                .context("In with_transaction.")
+                .and_then(|tx| f(&tx).map(|result| (result, tx)))
+                .and_then(|(result, tx)| {
+                    tx.commit().context("In with_transaction: Failed to commit transaction.")?;
+                    Ok(result)
+                }) {
+                Ok(result) => break Ok(result),
+                Err(e) => {
+                    if Self::is_locked_error(&e) {
+                        std::thread::sleep(std::time::Duration::from_micros(500));
+                        continue;
+                    } else {
+                        return Err(e).context("In with_transaction.");
+                    }
+                }
+            }
+        }
+        .map(|(need_gc, result)| {
+            if need_gc {
+                if let Some(ref gc) = self.gc {
+                    gc.notify_gc();
+                }
+            }
+            result
+        })
+    }
+
+    fn is_locked_error(e: &anyhow::Error) -> bool {
+        matches!(
+            e.root_cause().downcast_ref::<rusqlite::ffi::Error>(),
+            Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. })
+                | Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseLocked, .. })
+        )
+    }
+
+    /// Creates a new key entry and allocates a new randomized id for the new key.
+    /// The key id gets associated with a domain and namespace but not with an alias.
+    /// To complete key generation `rebind_alias` should be called after all of the
+    /// key artifacts, i.e., blobs and parameters have been associated with the new
+    /// key id. Finalizing with `rebind_alias` makes the creation of a new key entry
+    /// atomic even if key generation is not.
+    pub fn create_key_entry(
+        &mut self,
+        domain: &Domain,
+        namespace: &i64,
+        km_uuid: &Uuid,
+    ) -> Result<KeyIdGuard> {
+        let _wp = wd::watch_millis("KeystoreDB::create_key_entry", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            Self::create_key_entry_internal(tx, domain, namespace, km_uuid).no_gc()
+        })
+        .context("In create_key_entry.")
+    }
+
+    fn create_key_entry_internal(
+        tx: &Transaction,
+        domain: &Domain,
+        namespace: &i64,
+        km_uuid: &Uuid,
+    ) -> Result<KeyIdGuard> {
+        match *domain {
+            Domain::APP | Domain::SELINUX => {}
+            _ => {
+                return Err(KsError::sys())
+                    .context(format!("Domain {:?} must be either App or SELinux.", domain));
+            }
+        }
+        Ok(KEY_ID_LOCK.get(
+            Self::insert_with_retry(|id| {
+                tx.execute(
+                    "INSERT into persistent.keyentry
+                     (id, key_type, domain, namespace, alias, state, km_uuid)
+                     VALUES(?, ?, ?, ?, NULL, ?, ?);",
+                    params![
+                        id,
+                        KeyType::Client,
+                        domain.0 as u32,
+                        *namespace,
+                        KeyLifeCycle::Existing,
+                        km_uuid,
+                    ],
+                )
+            })
+            .context("In create_key_entry_internal")?,
+        ))
+    }
+
+    /// Creates a new attestation key entry and allocates a new randomized id for the new key.
+    /// The key id gets associated with a domain and namespace later but not with an alias. The
+    /// alias will be used to denote if a key has been signed as each key can only be bound to one
+    /// domain and namespace pairing so there is no need to use them as a value for indexing into
+    /// a key.
+    pub fn create_attestation_key_entry(
+        &mut self,
+        maced_public_key: &[u8],
+        raw_public_key: &[u8],
+        private_key: &[u8],
+        km_uuid: &Uuid,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::create_attestation_key_entry", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let key_id = KEY_ID_LOCK.get(
+                Self::insert_with_retry(|id| {
+                    tx.execute(
+                        "INSERT into persistent.keyentry
+                            (id, key_type, domain, namespace, alias, state, km_uuid)
+                            VALUES(?, ?, NULL, NULL, NULL, ?, ?);",
+                        params![id, KeyType::Attestation, KeyLifeCycle::Live, km_uuid],
+                    )
+                })
+                .context("In create_key_entry")?,
+            );
+            Self::set_blob_internal(
+                &tx,
+                key_id.0,
+                SubComponentType::KEY_BLOB,
+                Some(private_key),
+                None,
+            )?;
+            let mut metadata = KeyMetaData::new();
+            metadata.add(KeyMetaEntry::AttestationMacedPublicKey(maced_public_key.to_vec()));
+            metadata.add(KeyMetaEntry::AttestationRawPubKey(raw_public_key.to_vec()));
+            metadata.store_in_db(key_id.0, &tx)?;
+            Ok(()).no_gc()
+        })
+        .context("In create_attestation_key_entry")
+    }
+
+    /// Set a new blob and associates it with the given key id. Each blob
+    /// has a sub component type.
+    /// Each key can have one of each sub component type associated. If more
+    /// are added only the most recent can be retrieved, and superseded blobs
+    /// will get garbage collected.
+    /// Components SubComponentType::CERT and SubComponentType::CERT_CHAIN can be
+    /// removed by setting blob to None.
+    pub fn set_blob(
+        &mut self,
+        key_id: &KeyIdGuard,
+        sc_type: SubComponentType,
+        blob: Option<&[u8]>,
+        blob_metadata: Option<&BlobMetaData>,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::set_blob", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            Self::set_blob_internal(&tx, key_id.0, sc_type, blob, blob_metadata).need_gc()
+        })
+        .context("In set_blob.")
+    }
+
+    /// Why would we insert a deleted blob? This weird function is for the purpose of legacy
+    /// key migration in the case where we bulk delete all the keys of an app or even a user.
+    /// We use this to insert key blobs into the database which can then be garbage collected
+    /// lazily by the key garbage collector.
+    pub fn set_deleted_blob(&mut self, blob: &[u8], blob_metadata: &BlobMetaData) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::set_deleted_blob", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            Self::set_blob_internal(
+                &tx,
+                Self::UNASSIGNED_KEY_ID,
+                SubComponentType::KEY_BLOB,
+                Some(blob),
+                Some(blob_metadata),
+            )
+            .need_gc()
+        })
+        .context("In set_deleted_blob.")
+    }
+
+    fn set_blob_internal(
+        tx: &Transaction,
+        key_id: i64,
+        sc_type: SubComponentType,
+        blob: Option<&[u8]>,
+        blob_metadata: Option<&BlobMetaData>,
+    ) -> Result<()> {
+        match (blob, sc_type) {
+            (Some(blob), _) => {
+                tx.execute(
+                    "INSERT INTO persistent.blobentry
+                     (subcomponent_type, keyentryid, blob) VALUES (?, ?, ?);",
+                    params![sc_type, key_id, blob],
+                )
+                .context("In set_blob_internal: Failed to insert blob.")?;
+                if let Some(blob_metadata) = blob_metadata {
+                    let blob_id = tx
+                        .query_row("SELECT MAX(id) FROM persistent.blobentry;", NO_PARAMS, |row| {
+                            row.get(0)
+                        })
+                        .context("In set_blob_internal: Failed to get new blob id.")?;
+                    blob_metadata
+                        .store_in_db(blob_id, tx)
+                        .context("In set_blob_internal: Trying to store blob metadata.")?;
+                }
+            }
+            (None, SubComponentType::CERT) | (None, SubComponentType::CERT_CHAIN) => {
+                tx.execute(
+                    "DELETE FROM persistent.blobentry
+                    WHERE subcomponent_type = ? AND keyentryid = ?;",
+                    params![sc_type, key_id],
+                )
+                .context("In set_blob_internal: Failed to delete blob.")?;
+            }
+            (None, _) => {
+                return Err(KsError::sys())
+                    .context("In set_blob_internal: Other blobs cannot be deleted in this way.");
+            }
+        }
+        Ok(())
+    }
+
+    /// Inserts a collection of key parameters into the `persistent.keyparameter` table
+    /// and associates them with the given `key_id`.
+    #[cfg(test)]
+    fn insert_keyparameter(&mut self, key_id: &KeyIdGuard, params: &[KeyParameter]) -> Result<()> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            Self::insert_keyparameter_internal(tx, key_id, params).no_gc()
+        })
+        .context("In insert_keyparameter.")
+    }
+
+    fn insert_keyparameter_internal(
+        tx: &Transaction,
+        key_id: &KeyIdGuard,
+        params: &[KeyParameter],
+    ) -> Result<()> {
+        let mut stmt = tx
+            .prepare(
+                "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
+                VALUES (?, ?, ?, ?);",
+            )
+            .context("In insert_keyparameter_internal: Failed to prepare statement.")?;
+
+        for p in params.iter() {
+            stmt.insert(params![
+                key_id.0,
+                p.get_tag().0,
+                p.key_parameter_value(),
+                p.security_level().0
+            ])
+            .with_context(|| {
+                format!("In insert_keyparameter_internal: Failed to insert {:?}", p)
+            })?;
+        }
+        Ok(())
+    }
+
+    /// Insert a set of key entry specific metadata into the database.
+    #[cfg(test)]
+    fn insert_key_metadata(&mut self, key_id: &KeyIdGuard, metadata: &KeyMetaData) -> Result<()> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            metadata.store_in_db(key_id.0, &tx).no_gc()
+        })
+        .context("In insert_key_metadata.")
+    }
+
+    /// Stores a signed certificate chain signed by a remote provisioning server, keyed
+    /// on the public key.
+    pub fn store_signed_attestation_certificate_chain(
+        &mut self,
+        raw_public_key: &[u8],
+        batch_cert: &[u8],
+        cert_chain: &[u8],
+        expiration_date: i64,
+        km_uuid: &Uuid,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::store_signed_attestation_certificate_chain", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let mut stmt = tx
+                .prepare(
+                    "SELECT keyentryid
+                    FROM persistent.keymetadata
+                    WHERE tag = ? AND data = ? AND keyentryid IN
+                    (SELECT id
+                     FROM persistent.keyentry
+                     WHERE
+                        alias IS NULL AND
+                        domain IS NULL AND
+                        namespace IS NULL AND
+                        key_type = ? AND
+                        km_uuid = ?);",
+                )
+                .context("Failed to store attestation certificate chain.")?;
+            let mut rows = stmt
+                .query(params![
+                    KeyMetaData::AttestationRawPubKey,
+                    raw_public_key,
+                    KeyType::Attestation,
+                    km_uuid
+                ])
+                .context("Failed to fetch keyid")?;
+            let key_id = db_utils::with_rows_extract_one(&mut rows, |row| {
+                row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?
+                    .get(0)
+                    .context("Failed to unpack id.")
+            })
+            .context("Failed to get key_id.")?;
+            let num_updated = tx
+                .execute(
+                    "UPDATE persistent.keyentry
+                    SET alias = ?
+                    WHERE id = ?;",
+                    params!["signed", key_id],
+                )
+                .context("Failed to update alias.")?;
+            if num_updated != 1 {
+                return Err(KsError::sys()).context("Alias not updated for the key.");
+            }
+            let mut metadata = KeyMetaData::new();
+            metadata.add(KeyMetaEntry::AttestationExpirationDate(DateTime::from_millis_epoch(
+                expiration_date,
+            )));
+            metadata.store_in_db(key_id, &tx).context("Failed to insert key metadata.")?;
+            Self::set_blob_internal(
+                &tx,
+                key_id,
+                SubComponentType::CERT_CHAIN,
+                Some(cert_chain),
+                None,
+            )
+            .context("Failed to insert cert chain")?;
+            Self::set_blob_internal(&tx, key_id, SubComponentType::CERT, Some(batch_cert), None)
+                .context("Failed to insert cert")?;
+            Ok(()).no_gc()
+        })
+        .context("In store_signed_attestation_certificate_chain: ")
+    }
+
+    /// Assigns the next unassigned attestation key to a domain/namespace combo that does not
+    /// currently have a key assigned to it.
+    pub fn assign_attestation_key(
+        &mut self,
+        domain: Domain,
+        namespace: i64,
+        km_uuid: &Uuid,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::assign_attestation_key", 500);
+
+        match domain {
+            Domain::APP | Domain::SELINUX => {}
+            _ => {
+                return Err(KsError::sys()).context(format!(
+                    concat!(
+                        "In assign_attestation_key: Domain {:?} ",
+                        "must be either App or SELinux.",
+                    ),
+                    domain
+                ));
+            }
+        }
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let result = tx
+                .execute(
+                    "UPDATE persistent.keyentry
+                        SET domain=?1, namespace=?2
+                        WHERE
+                            id =
+                                (SELECT MIN(id)
+                                FROM persistent.keyentry
+                                WHERE ALIAS IS NOT NULL
+                                    AND domain IS NULL
+                                    AND key_type IS ?3
+                                    AND state IS ?4
+                                    AND km_uuid IS ?5)
+                            AND
+                                (SELECT COUNT(*)
+                                FROM persistent.keyentry
+                                WHERE domain=?1
+                                    AND namespace=?2
+                                    AND key_type IS ?3
+                                    AND state IS ?4
+                                    AND km_uuid IS ?5) = 0;",
+                    params![
+                        domain.0 as u32,
+                        namespace,
+                        KeyType::Attestation,
+                        KeyLifeCycle::Live,
+                        km_uuid,
+                    ],
+                )
+                .context("Failed to assign attestation key")?;
+            if result == 0 {
+                return Err(KsError::Rc(ResponseCode::OUT_OF_KEYS)).context("Out of keys.");
+            } else if result > 1 {
+                return Err(KsError::sys())
+                    .context(format!("Expected to update 1 entry, instead updated {}", result));
+            }
+            Ok(()).no_gc()
+        })
+        .context("In assign_attestation_key: ")
+    }
+
+    /// Retrieves num_keys number of attestation keys that have not yet been signed by a remote
+    /// provisioning server, or the maximum number available if there are not num_keys number of
+    /// entries in the table.
+    pub fn fetch_unsigned_attestation_keys(
+        &mut self,
+        num_keys: i32,
+        km_uuid: &Uuid,
+    ) -> Result<Vec<Vec<u8>>> {
+        let _wp = wd::watch_millis("KeystoreDB::fetch_unsigned_attestation_keys", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let mut stmt = tx
+                .prepare(
+                    "SELECT data
+                    FROM persistent.keymetadata
+                    WHERE tag = ? AND keyentryid IN
+                        (SELECT id
+                        FROM persistent.keyentry
+                        WHERE
+                            alias IS NULL AND
+                            domain IS NULL AND
+                            namespace IS NULL AND
+                            key_type = ? AND
+                            km_uuid = ?
+                        LIMIT ?);",
+                )
+                .context("Failed to prepare statement")?;
+            let rows = stmt
+                .query_map(
+                    params![
+                        KeyMetaData::AttestationMacedPublicKey,
+                        KeyType::Attestation,
+                        km_uuid,
+                        num_keys
+                    ],
+                    |row| row.get(0),
+                )?
+                .collect::<rusqlite::Result<Vec<Vec<u8>>>>()
+                .context("Failed to execute statement")?;
+            Ok(rows).no_gc()
+        })
+        .context("In fetch_unsigned_attestation_keys")
+    }
+
+    /// Removes any keys that have expired as of the current time. Returns the number of keys
+    /// marked unreferenced that are bound to be garbage collected.
+    pub fn delete_expired_attestation_keys(&mut self) -> Result<i32> {
+        let _wp = wd::watch_millis("KeystoreDB::delete_expired_attestation_keys", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let mut stmt = tx
+                .prepare(
+                    "SELECT keyentryid, data
+                     FROM persistent.keymetadata
+                     WHERE tag = ? AND keyentryid IN
+                         (SELECT id
+                         FROM persistent.keyentry
+                         WHERE key_type = ?);",
+                )
+                .context("Failed to prepare query")?;
+            let key_ids_to_check = stmt
+                .query_map(
+                    params![KeyMetaData::AttestationExpirationDate, KeyType::Attestation],
+                    |row| Ok((row.get(0)?, row.get(1)?)),
+                )?
+                .collect::<rusqlite::Result<Vec<(i64, DateTime)>>>()
+                .context("Failed to get date metadata")?;
+            let curr_time = DateTime::from_millis_epoch(
+                SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64,
+            );
+            let mut num_deleted = 0;
+            for id in key_ids_to_check.iter().filter(|kt| kt.1 < curr_time).map(|kt| kt.0) {
+                if Self::mark_unreferenced(&tx, id)? {
+                    num_deleted += 1;
+                }
+            }
+            Ok(num_deleted).do_gc(num_deleted != 0)
+        })
+        .context("In delete_expired_attestation_keys: ")
+    }
+
+    /// Deletes all remotely provisioned attestation keys in the system, regardless of the state
+    /// they are in. This is useful primarily as a testing mechanism.
+    pub fn delete_all_attestation_keys(&mut self) -> Result<i64> {
+        let _wp = wd::watch_millis("KeystoreDB::delete_all_attestation_keys", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let mut stmt = tx
+                .prepare(
+                    "SELECT id FROM persistent.keyentry
+                    WHERE key_type IS ?;",
+                )
+                .context("Failed to prepare statement")?;
+            let keys_to_delete = stmt
+                .query_map(params![KeyType::Attestation], |row| row.get(0))?
+                .collect::<rusqlite::Result<Vec<i64>>>()
+                .context("Failed to execute statement")?;
+            let num_deleted = keys_to_delete
+                .iter()
+                .map(|id| Self::mark_unreferenced(&tx, *id))
+                .collect::<Result<Vec<bool>>>()
+                .context("Failed to execute mark_unreferenced on a keyid")?
+                .into_iter()
+                .filter(|result| *result)
+                .count() as i64;
+            Ok(num_deleted).do_gc(num_deleted != 0)
+        })
+        .context("In delete_all_attestation_keys: ")
+    }
+
+    /// Counts the number of keys that will expire by the provided epoch date and the number of
+    /// keys not currently assigned to a domain.
+    pub fn get_attestation_pool_status(
+        &mut self,
+        date: i64,
+        km_uuid: &Uuid,
+    ) -> Result<AttestationPoolStatus> {
+        let _wp = wd::watch_millis("KeystoreDB::get_attestation_pool_status", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let mut stmt = tx.prepare(
+                "SELECT data
+                 FROM persistent.keymetadata
+                 WHERE tag = ? AND keyentryid IN
+                     (SELECT id
+                      FROM persistent.keyentry
+                      WHERE alias IS NOT NULL
+                            AND key_type = ?
+                            AND km_uuid = ?
+                            AND state = ?);",
+            )?;
+            let times = stmt
+                .query_map(
+                    params![
+                        KeyMetaData::AttestationExpirationDate,
+                        KeyType::Attestation,
+                        km_uuid,
+                        KeyLifeCycle::Live
+                    ],
+                    |row| row.get(0),
+                )?
+                .collect::<rusqlite::Result<Vec<DateTime>>>()
+                .context("Failed to execute metadata statement")?;
+            let expiring =
+                times.iter().filter(|time| time < &&DateTime::from_millis_epoch(date)).count()
+                    as i32;
+            stmt = tx.prepare(
+                "SELECT alias, domain
+                 FROM persistent.keyentry
+                 WHERE key_type = ? AND km_uuid = ? AND state = ?;",
+            )?;
+            let rows = stmt
+                .query_map(params![KeyType::Attestation, km_uuid, KeyLifeCycle::Live], |row| {
+                    Ok((row.get(0)?, row.get(1)?))
+                })?
+                .collect::<rusqlite::Result<Vec<(Option<String>, Option<u32>)>>>()
+                .context("Failed to execute keyentry statement")?;
+            let mut unassigned = 0i32;
+            let mut attested = 0i32;
+            let total = rows.len() as i32;
+            for (alias, domain) in rows {
+                match (alias, domain) {
+                    (Some(_alias), None) => {
+                        attested += 1;
+                        unassigned += 1;
+                    }
+                    (Some(_alias), Some(_domain)) => {
+                        attested += 1;
+                    }
+                    _ => {}
+                }
+            }
+            Ok(AttestationPoolStatus { expiring, unassigned, attested, total }).no_gc()
+        })
+        .context("In get_attestation_pool_status: ")
+    }
+
+    /// Fetches the private key and corresponding certificate chain assigned to a
+    /// domain/namespace pair. Will either return nothing if the domain/namespace is
+    /// not assigned, or one CertificateChain.
+    pub fn retrieve_attestation_key_and_cert_chain(
+        &mut self,
+        domain: Domain,
+        namespace: i64,
+        km_uuid: &Uuid,
+    ) -> Result<Option<CertificateChain>> {
+        let _wp = wd::watch_millis("KeystoreDB::retrieve_attestation_key_and_cert_chain", 500);
+
+        match domain {
+            Domain::APP | Domain::SELINUX => {}
+            _ => {
+                return Err(KsError::sys())
+                    .context(format!("Domain {:?} must be either App or SELinux.", domain));
+            }
+        }
+        self.with_transaction(TransactionBehavior::Deferred, |tx| {
+            let mut stmt = tx.prepare(
+                "SELECT subcomponent_type, blob
+             FROM persistent.blobentry
+             WHERE keyentryid IN
+                (SELECT id
+                 FROM persistent.keyentry
+                 WHERE key_type = ?
+                       AND domain = ?
+                       AND namespace = ?
+                       AND state = ?
+                       AND km_uuid = ?);",
+            )?;
+            let rows = stmt
+                .query_map(
+                    params![
+                        KeyType::Attestation,
+                        domain.0 as u32,
+                        namespace,
+                        KeyLifeCycle::Live,
+                        km_uuid
+                    ],
+                    |row| Ok((row.get(0)?, row.get(1)?)),
+                )?
+                .collect::<rusqlite::Result<Vec<(SubComponentType, Vec<u8>)>>>()
+                .context("query failed.")?;
+            if rows.is_empty() {
+                return Ok(None).no_gc();
+            } else if rows.len() != 3 {
+                return Err(KsError::sys()).context(format!(
+                    concat!(
+                        "Expected to get a single attestation",
+                        "key, cert, and cert chain for a total of 3 entries, but instead got {}."
+                    ),
+                    rows.len()
+                ));
+            }
+            let mut km_blob: Vec<u8> = Vec::new();
+            let mut cert_chain_blob: Vec<u8> = Vec::new();
+            let mut batch_cert_blob: Vec<u8> = Vec::new();
+            for row in rows {
+                let sub_type: SubComponentType = row.0;
+                match sub_type {
+                    SubComponentType::KEY_BLOB => {
+                        km_blob = row.1;
+                    }
+                    SubComponentType::CERT_CHAIN => {
+                        cert_chain_blob = row.1;
+                    }
+                    SubComponentType::CERT => {
+                        batch_cert_blob = row.1;
+                    }
+                    _ => Err(KsError::sys()).context("Unknown or incorrect subcomponent type.")?,
+                }
+            }
+            Ok(Some(CertificateChain {
+                private_key: ZVec::try_from(km_blob)?,
+                batch_cert: batch_cert_blob,
+                cert_chain: cert_chain_blob,
+            }))
+            .no_gc()
+        })
+        .context("In retrieve_attestation_key_and_cert_chain:")
+    }
+
+    /// Updates the alias column of the given key id `newid` with the given alias,
+    /// and atomically, removes the alias, domain, and namespace from another row
+    /// with the same alias-domain-namespace tuple if such row exits.
+    /// Returns Ok(true) if an old key was marked unreferenced as a hint to the garbage
+    /// collector.
+    fn rebind_alias(
+        tx: &Transaction,
+        newid: &KeyIdGuard,
+        alias: &str,
+        domain: &Domain,
+        namespace: &i64,
+    ) -> Result<bool> {
+        match *domain {
+            Domain::APP | Domain::SELINUX => {}
+            _ => {
+                return Err(KsError::sys()).context(format!(
+                    "In rebind_alias: Domain {:?} must be either App or SELinux.",
+                    domain
+                ));
+            }
+        }
+        let updated = tx
+            .execute(
+                "UPDATE persistent.keyentry
+                 SET alias = NULL, domain = NULL, namespace = NULL, state = ?
+                 WHERE alias = ? AND domain = ? AND namespace = ?;",
+                params![KeyLifeCycle::Unreferenced, alias, domain.0 as u32, namespace],
+            )
+            .context("In rebind_alias: Failed to rebind existing entry.")?;
+        let result = tx
+            .execute(
+                "UPDATE persistent.keyentry
+                    SET alias = ?, state = ?
+                    WHERE id = ? AND domain = ? AND namespace = ? AND state = ?;",
+                params![
+                    alias,
+                    KeyLifeCycle::Live,
+                    newid.0,
+                    domain.0 as u32,
+                    *namespace,
+                    KeyLifeCycle::Existing,
+                ],
+            )
+            .context("In rebind_alias: Failed to set alias.")?;
+        if result != 1 {
+            return Err(KsError::sys()).context(format!(
+                "In rebind_alias: Expected to update a single entry but instead updated {}.",
+                result
+            ));
+        }
+        Ok(updated != 0)
+    }
+
+    /// Moves the key given by KeyIdGuard to the new location at `destination`. If the destination
+    /// is already occupied by a key, this function fails with `ResponseCode::INVALID_ARGUMENT`.
+    pub fn migrate_key_namespace(
+        &mut self,
+        key_id_guard: KeyIdGuard,
+        destination: &KeyDescriptor,
+        caller_uid: u32,
+        check_permission: impl Fn(&KeyDescriptor) -> Result<()>,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::migrate_key_namespace", 500);
+
+        let destination = match destination.domain {
+            Domain::APP => KeyDescriptor { nspace: caller_uid as i64, ..(*destination).clone() },
+            Domain::SELINUX => (*destination).clone(),
+            domain => {
+                return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
+                    .context(format!("Domain {:?} must be either APP or SELINUX.", domain));
+            }
+        };
+
+        // Security critical: Must return immediately on failure. Do not remove the '?';
+        check_permission(&destination)
+            .context("In migrate_key_namespace: Trying to check permission.")?;
+
+        let alias = destination
+            .alias
+            .as_ref()
+            .ok_or(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
+            .context("In migrate_key_namespace: Alias must be specified.")?;
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            // Query the destination location. If there is a key, the migration request fails.
+            if tx
+                .query_row(
+                    "SELECT id FROM persistent.keyentry
+                     WHERE alias = ? AND domain = ? AND namespace = ?;",
+                    params![alias, destination.domain.0, destination.nspace],
+                    |_| Ok(()),
+                )
+                .optional()
+                .context("Failed to query destination.")?
+                .is_some()
+            {
+                return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
+                    .context("Target already exists.");
+            }
+
+            let updated = tx
+                .execute(
+                    "UPDATE persistent.keyentry
+                 SET alias = ?, domain = ?, namespace = ?
+                 WHERE id = ?;",
+                    params![alias, destination.domain.0, destination.nspace, key_id_guard.id()],
+                )
+                .context("Failed to update key entry.")?;
+
+            if updated != 1 {
+                return Err(KsError::sys())
+                    .context(format!("Update succeeded, but {} rows were updated.", updated));
+            }
+            Ok(()).no_gc()
+        })
+        .context("In migrate_key_namespace:")
+    }
+
+    /// Store a new key in a single transaction.
+    /// The function creates a new key entry, populates the blob, key parameter, and metadata
+    /// fields, and rebinds the given alias to the new key.
+    /// The boolean returned is a hint for the garbage collector. If true, a key was replaced,
+    /// is now unreferenced and needs to be collected.
+    pub fn store_new_key(
+        &mut self,
+        key: &KeyDescriptor,
+        params: &[KeyParameter],
+        blob_info: &(&[u8], &BlobMetaData),
+        cert_info: &CertificateInfo,
+        metadata: &KeyMetaData,
+        km_uuid: &Uuid,
+    ) -> Result<KeyIdGuard> {
+        let _wp = wd::watch_millis("KeystoreDB::store_new_key", 500);
+
+        let (alias, domain, namespace) = match key {
+            KeyDescriptor { alias: Some(alias), domain: Domain::APP, nspace, blob: None }
+            | KeyDescriptor { alias: Some(alias), domain: Domain::SELINUX, nspace, blob: None } => {
+                (alias, key.domain, nspace)
+            }
+            _ => {
+                return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
+                    .context("In store_new_key: Need alias and domain must be APP or SELINUX.")
+            }
+        };
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let key_id = Self::create_key_entry_internal(tx, &domain, namespace, km_uuid)
+                .context("Trying to create new key entry.")?;
+            let (blob, blob_metadata) = *blob_info;
+            Self::set_blob_internal(
+                tx,
+                key_id.id(),
+                SubComponentType::KEY_BLOB,
+                Some(blob),
+                Some(&blob_metadata),
+            )
+            .context("Trying to insert the key blob.")?;
+            if let Some(cert) = &cert_info.cert {
+                Self::set_blob_internal(tx, key_id.id(), SubComponentType::CERT, Some(&cert), None)
+                    .context("Trying to insert the certificate.")?;
+            }
+            if let Some(cert_chain) = &cert_info.cert_chain {
+                Self::set_blob_internal(
+                    tx,
+                    key_id.id(),
+                    SubComponentType::CERT_CHAIN,
+                    Some(&cert_chain),
+                    None,
+                )
+                .context("Trying to insert the certificate chain.")?;
+            }
+            Self::insert_keyparameter_internal(tx, &key_id, params)
+                .context("Trying to insert key parameters.")?;
+            metadata.store_in_db(key_id.id(), tx).context("Trying to insert key metadata.")?;
+            let need_gc = Self::rebind_alias(tx, &key_id, &alias, &domain, namespace)
+                .context("Trying to rebind alias.")?;
+            Ok(key_id).do_gc(need_gc)
+        })
+        .context("In store_new_key.")
+    }
+
+    /// Store a new certificate
+    /// The function creates a new key entry, populates the blob field and metadata, and rebinds
+    /// the given alias to the new cert.
+    pub fn store_new_certificate(
+        &mut self,
+        key: &KeyDescriptor,
+        cert: &[u8],
+        km_uuid: &Uuid,
+    ) -> Result<KeyIdGuard> {
+        let _wp = wd::watch_millis("KeystoreDB::store_new_certificate", 500);
+
+        let (alias, domain, namespace) = match key {
+            KeyDescriptor { alias: Some(alias), domain: Domain::APP, nspace, blob: None }
+            | KeyDescriptor { alias: Some(alias), domain: Domain::SELINUX, nspace, blob: None } => {
+                (alias, key.domain, nspace)
+            }
+            _ => {
+                return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT)).context(
+                    "In store_new_certificate: Need alias and domain must be APP or SELINUX.",
+                )
+            }
+        };
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let key_id = Self::create_key_entry_internal(tx, &domain, namespace, km_uuid)
+                .context("Trying to create new key entry.")?;
+
+            Self::set_blob_internal(
+                tx,
+                key_id.id(),
+                SubComponentType::CERT_CHAIN,
+                Some(cert),
+                None,
+            )
+            .context("Trying to insert certificate.")?;
+
+            let mut metadata = KeyMetaData::new();
+            metadata.add(KeyMetaEntry::CreationDate(
+                DateTime::now().context("Trying to make creation time.")?,
+            ));
+
+            metadata.store_in_db(key_id.id(), tx).context("Trying to insert key metadata.")?;
+
+            let need_gc = Self::rebind_alias(tx, &key_id, &alias, &domain, namespace)
+                .context("Trying to rebind alias.")?;
+            Ok(key_id).do_gc(need_gc)
+        })
+        .context("In store_new_certificate.")
+    }
+
+    // Helper function loading the key_id given the key descriptor
+    // tuple comprising domain, namespace, and alias.
+    // Requires a valid transaction.
+    fn load_key_entry_id(tx: &Transaction, key: &KeyDescriptor, key_type: KeyType) -> Result<i64> {
+        let alias = key
+            .alias
+            .as_ref()
+            .map_or_else(|| Err(KsError::sys()), Ok)
+            .context("In load_key_entry_id: Alias must be specified.")?;
+        let mut stmt = tx
+            .prepare(
+                "SELECT id FROM persistent.keyentry
+                    WHERE
+                    key_type = ?
+                    AND domain = ?
+                    AND namespace = ?
+                    AND alias = ?
+                    AND state = ?;",
+            )
+            .context("In load_key_entry_id: Failed to select from keyentry table.")?;
+        let mut rows = stmt
+            .query(params![key_type, key.domain.0 as u32, key.nspace, alias, KeyLifeCycle::Live])
+            .context("In load_key_entry_id: Failed to read from keyentry table.")?;
+        db_utils::with_rows_extract_one(&mut rows, |row| {
+            row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?
+                .get(0)
+                .context("Failed to unpack id.")
+        })
+        .context("In load_key_entry_id.")
+    }
+
+    /// This helper function completes the access tuple of a key, which is required
+    /// to perform access control. The strategy depends on the `domain` field in the
+    /// key descriptor.
+    /// * Domain::SELINUX: The access tuple is complete and this function only loads
+    ///       the key_id for further processing.
+    /// * Domain::APP: Like Domain::SELINUX, but the tuple is completed by `caller_uid`
+    ///       which serves as the namespace.
+    /// * Domain::GRANT: The grant table is queried for the `key_id` and the
+    ///       `access_vector`.
+    /// * Domain::KEY_ID: The keyentry table is queried for the owning `domain` and
+    ///       `namespace`.
+    /// In each case the information returned is sufficient to perform the access
+    /// check and the key id can be used to load further key artifacts.
+    fn load_access_tuple(
+        tx: &Transaction,
+        key: &KeyDescriptor,
+        key_type: KeyType,
+        caller_uid: u32,
+    ) -> Result<(i64, KeyDescriptor, Option<KeyPermSet>)> {
+        match key.domain {
+            // Domain App or SELinux. In this case we load the key_id from
+            // the keyentry database for further loading of key components.
+            // We already have the full access tuple to perform access control.
+            // The only distinction is that we use the caller_uid instead
+            // of the caller supplied namespace if the domain field is
+            // Domain::APP.
+            Domain::APP | Domain::SELINUX => {
+                let mut access_key = key.clone();
+                if access_key.domain == Domain::APP {
+                    access_key.nspace = caller_uid as i64;
+                }
+                let key_id = Self::load_key_entry_id(&tx, &access_key, key_type)
+                    .with_context(|| format!("With key.domain = {:?}.", access_key.domain))?;
+
+                Ok((key_id, access_key, None))
+            }
+
+            // Domain::GRANT. In this case we load the key_id and the access_vector
+            // from the grant table.
+            Domain::GRANT => {
+                let mut stmt = tx
+                    .prepare(
+                        "SELECT keyentryid, access_vector FROM persistent.grant
+                            WHERE grantee = ? AND id = ?;",
+                    )
+                    .context("Domain::GRANT prepare statement failed")?;
+                let mut rows = stmt
+                    .query(params![caller_uid as i64, key.nspace])
+                    .context("Domain:Grant: query failed.")?;
+                let (key_id, access_vector): (i64, i32) =
+                    db_utils::with_rows_extract_one(&mut rows, |row| {
+                        let r =
+                            row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?;
+                        Ok((
+                            r.get(0).context("Failed to unpack key_id.")?,
+                            r.get(1).context("Failed to unpack access_vector.")?,
+                        ))
+                    })
+                    .context("Domain::GRANT.")?;
+                Ok((key_id, key.clone(), Some(access_vector.into())))
+            }
+
+            // Domain::KEY_ID. In this case we load the domain and namespace from the
+            // keyentry database because we need them for access control.
+            Domain::KEY_ID => {
+                let (domain, namespace): (Domain, i64) = {
+                    let mut stmt = tx
+                        .prepare(
+                            "SELECT domain, namespace FROM persistent.keyentry
+                                WHERE
+                                id = ?
+                                AND state = ?;",
+                        )
+                        .context("Domain::KEY_ID: prepare statement failed")?;
+                    let mut rows = stmt
+                        .query(params![key.nspace, KeyLifeCycle::Live])
+                        .context("Domain::KEY_ID: query failed.")?;
+                    db_utils::with_rows_extract_one(&mut rows, |row| {
+                        let r =
+                            row.map_or_else(|| Err(KsError::Rc(ResponseCode::KEY_NOT_FOUND)), Ok)?;
+                        Ok((
+                            Domain(r.get(0).context("Failed to unpack domain.")?),
+                            r.get(1).context("Failed to unpack namespace.")?,
+                        ))
+                    })
+                    .context("Domain::KEY_ID.")?
+                };
+
+                // We may use a key by id after loading it by grant.
+                // In this case we have to check if the caller has a grant for this particular
+                // key. We can skip this if we already know that the caller is the owner.
+                // But we cannot know this if domain is anything but App. E.g. in the case
+                // of Domain::SELINUX we have to speculatively check for grants because we have to
+                // consult the SEPolicy before we know if the caller is the owner.
+                let access_vector: Option<KeyPermSet> =
+                    if domain != Domain::APP || namespace != caller_uid as i64 {
+                        let access_vector: Option<i32> = tx
+                            .query_row(
+                                "SELECT access_vector FROM persistent.grant
+                                WHERE grantee = ? AND keyentryid = ?;",
+                                params![caller_uid as i64, key.nspace],
+                                |row| row.get(0),
+                            )
+                            .optional()
+                            .context("Domain::KEY_ID: query grant failed.")?;
+                        access_vector.map(|p| p.into())
+                    } else {
+                        None
+                    };
+
+                let key_id = key.nspace;
+                let mut access_key: KeyDescriptor = key.clone();
+                access_key.domain = domain;
+                access_key.nspace = namespace;
+
+                Ok((key_id, access_key, access_vector))
+            }
+            _ => Err(anyhow!(KsError::sys())),
+        }
+    }
+
+    fn load_blob_components(
+        key_id: i64,
+        load_bits: KeyEntryLoadBits,
+        tx: &Transaction,
+    ) -> Result<(bool, Option<(Vec<u8>, BlobMetaData)>, Option<Vec<u8>>, Option<Vec<u8>>)> {
+        let mut stmt = tx
+            .prepare(
+                "SELECT MAX(id), subcomponent_type, blob FROM persistent.blobentry
+                    WHERE keyentryid = ? GROUP BY subcomponent_type;",
+            )
+            .context("In load_blob_components: prepare statement failed.")?;
+
+        let mut rows =
+            stmt.query(params![key_id]).context("In load_blob_components: query failed.")?;
+
+        let mut key_blob: Option<(i64, Vec<u8>)> = None;
+        let mut cert_blob: Option<Vec<u8>> = None;
+        let mut cert_chain_blob: Option<Vec<u8>> = None;
+        let mut has_km_blob: bool = false;
+        db_utils::with_rows_extract_all(&mut rows, |row| {
+            let sub_type: SubComponentType =
+                row.get(1).context("Failed to extract subcomponent_type.")?;
+            has_km_blob = has_km_blob || sub_type == SubComponentType::KEY_BLOB;
+            match (sub_type, load_bits.load_public(), load_bits.load_km()) {
+                (SubComponentType::KEY_BLOB, _, true) => {
+                    key_blob = Some((
+                        row.get(0).context("Failed to extract key blob id.")?,
+                        row.get(2).context("Failed to extract key blob.")?,
+                    ));
+                }
+                (SubComponentType::CERT, true, _) => {
+                    cert_blob =
+                        Some(row.get(2).context("Failed to extract public certificate blob.")?);
+                }
+                (SubComponentType::CERT_CHAIN, true, _) => {
+                    cert_chain_blob =
+                        Some(row.get(2).context("Failed to extract certificate chain blob.")?);
+                }
+                (SubComponentType::CERT, _, _)
+                | (SubComponentType::CERT_CHAIN, _, _)
+                | (SubComponentType::KEY_BLOB, _, _) => {}
+                _ => Err(KsError::sys()).context("Unknown subcomponent type.")?,
+            }
+            Ok(())
+        })
+        .context("In load_blob_components.")?;
+
+        let blob_info = key_blob.map_or::<Result<_>, _>(Ok(None), |(blob_id, blob)| {
+            Ok(Some((
+                blob,
+                BlobMetaData::load_from_db(blob_id, tx)
+                    .context("In load_blob_components: Trying to load blob_metadata.")?,
+            )))
+        })?;
+
+        Ok((has_km_blob, blob_info, cert_blob, cert_chain_blob))
+    }
+
+    fn load_key_parameters(key_id: i64, tx: &Transaction) -> Result<Vec<KeyParameter>> {
+        let mut stmt = tx
+            .prepare(
+                "SELECT tag, data, security_level from persistent.keyparameter
+                    WHERE keyentryid = ?;",
+            )
+            .context("In load_key_parameters: prepare statement failed.")?;
+
+        let mut parameters: Vec<KeyParameter> = Vec::new();
+
+        let mut rows =
+            stmt.query(params![key_id]).context("In load_key_parameters: query failed.")?;
+        db_utils::with_rows_extract_all(&mut rows, |row| {
+            let tag = Tag(row.get(0).context("Failed to read tag.")?);
+            let sec_level = SecurityLevel(row.get(2).context("Failed to read sec_level.")?);
+            parameters.push(
+                KeyParameter::new_from_sql(tag, &SqlField::new(1, &row), sec_level)
+                    .context("Failed to read KeyParameter.")?,
+            );
+            Ok(())
+        })
+        .context("In load_key_parameters.")?;
+
+        Ok(parameters)
+    }
+
+    /// Decrements the usage count of a limited use key. This function first checks whether the
+    /// usage has been exhausted, if not, decreases the usage count. If the usage count reaches
+    /// zero, the key also gets marked unreferenced and scheduled for deletion.
+    /// Returns Ok(true) if the key was marked unreferenced as a hint to the garbage collector.
+    pub fn check_and_update_key_usage_count(&mut self, key_id: i64) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::check_and_update_key_usage_count", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let limit: Option<i32> = tx
+                .query_row(
+                    "SELECT data FROM persistent.keyparameter WHERE keyentryid = ? AND tag = ?;",
+                    params![key_id, Tag::USAGE_COUNT_LIMIT.0],
+                    |row| row.get(0),
+                )
+                .optional()
+                .context("Trying to load usage count")?;
+
+            let limit = limit
+                .ok_or(KsError::Km(ErrorCode::INVALID_KEY_BLOB))
+                .context("The Key no longer exists. Key is exhausted.")?;
+
+            tx.execute(
+                "UPDATE persistent.keyparameter
+                 SET data = data - 1
+                 WHERE keyentryid = ? AND tag = ? AND data > 0;",
+                params![key_id, Tag::USAGE_COUNT_LIMIT.0],
+            )
+            .context("Failed to update key usage count.")?;
+
+            match limit {
+                1 => Self::mark_unreferenced(tx, key_id)
+                    .map(|need_gc| (need_gc, ()))
+                    .context("Trying to mark limited use key for deletion."),
+                0 => Err(KsError::Km(ErrorCode::INVALID_KEY_BLOB)).context("Key is exhausted."),
+                _ => Ok(()).no_gc(),
+            }
+        })
+        .context("In check_and_update_key_usage_count.")
+    }
+
+    /// Load a key entry by the given key descriptor.
+    /// It uses the `check_permission` callback to verify if the access is allowed
+    /// given the key access tuple read from the database using `load_access_tuple`.
+    /// With `load_bits` the caller may specify which blobs shall be loaded from
+    /// the blob database.
+    pub fn load_key_entry(
+        &mut self,
+        key: &KeyDescriptor,
+        key_type: KeyType,
+        load_bits: KeyEntryLoadBits,
+        caller_uid: u32,
+        check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>,
+    ) -> Result<(KeyIdGuard, KeyEntry)> {
+        let _wp = wd::watch_millis("KeystoreDB::load_key_entry", 500);
+
+        loop {
+            match self.load_key_entry_internal(
+                key,
+                key_type,
+                load_bits,
+                caller_uid,
+                &check_permission,
+            ) {
+                Ok(result) => break Ok(result),
+                Err(e) => {
+                    if Self::is_locked_error(&e) {
+                        std::thread::sleep(std::time::Duration::from_micros(500));
+                        continue;
+                    } else {
+                        return Err(e).context("In load_key_entry.");
+                    }
+                }
+            }
+        }
+    }
+
+    fn load_key_entry_internal(
+        &mut self,
+        key: &KeyDescriptor,
+        key_type: KeyType,
+        load_bits: KeyEntryLoadBits,
+        caller_uid: u32,
+        check_permission: &impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>,
+    ) -> Result<(KeyIdGuard, KeyEntry)> {
+        // KEY ID LOCK 1/2
+        // If we got a key descriptor with a key id we can get the lock right away.
+        // Otherwise we have to defer it until we know the key id.
+        let key_id_guard = match key.domain {
+            Domain::KEY_ID => Some(KEY_ID_LOCK.get(key.nspace)),
+            _ => None,
+        };
+
+        let tx = self
+            .conn
+            .unchecked_transaction()
+            .context("In load_key_entry: Failed to initialize transaction.")?;
+
+        // Load the key_id and complete the access control tuple.
+        let (key_id, access_key_descriptor, access_vector) =
+            Self::load_access_tuple(&tx, key, key_type, caller_uid)
+                .context("In load_key_entry.")?;
+
+        // Perform access control. It is vital that we return here if the permission is denied.
+        // So do not touch that '?' at the end.
+        check_permission(&access_key_descriptor, access_vector).context("In load_key_entry.")?;
+
+        // KEY ID LOCK 2/2
+        // If we did not get a key id lock by now, it was because we got a key descriptor
+        // without a key id. At this point we got the key id, so we can try and get a lock.
+        // However, we cannot block here, because we are in the middle of the transaction.
+        // So first we try to get the lock non blocking. If that fails, we roll back the
+        // transaction and block until we get the lock. After we successfully got the lock,
+        // we start a new transaction and load the access tuple again.
+        //
+        // We don't need to perform access control again, because we already established
+        // that the caller had access to the given key. But we need to make sure that the
+        // key id still exists. So we have to load the key entry by key id this time.
+        let (key_id_guard, tx) = match key_id_guard {
+            None => match KEY_ID_LOCK.try_get(key_id) {
+                None => {
+                    // Roll back the transaction.
+                    tx.rollback().context("In load_key_entry: Failed to roll back transaction.")?;
+
+                    // Block until we have a key id lock.
+                    let key_id_guard = KEY_ID_LOCK.get(key_id);
+
+                    // Create a new transaction.
+                    let tx = self
+                        .conn
+                        .unchecked_transaction()
+                        .context("In load_key_entry: Failed to initialize transaction.")?;
+
+                    Self::load_access_tuple(
+                        &tx,
+                        // This time we have to load the key by the retrieved key id, because the
+                        // alias may have been rebound after we rolled back the transaction.
+                        &KeyDescriptor {
+                            domain: Domain::KEY_ID,
+                            nspace: key_id,
+                            ..Default::default()
+                        },
+                        key_type,
+                        caller_uid,
+                    )
+                    .context("In load_key_entry. (deferred key lock)")?;
+                    (key_id_guard, tx)
+                }
+                Some(l) => (l, tx),
+            },
+            Some(key_id_guard) => (key_id_guard, tx),
+        };
+
+        let key_entry = Self::load_key_components(&tx, load_bits, key_id_guard.id())
+            .context("In load_key_entry.")?;
+
+        tx.commit().context("In load_key_entry: Failed to commit transaction.")?;
+
+        Ok((key_id_guard, key_entry))
+    }
+
+    fn mark_unreferenced(tx: &Transaction, key_id: i64) -> Result<bool> {
+        let updated = tx
+            .execute("DELETE FROM persistent.keyentry WHERE id = ?;", params![key_id])
+            .context("Trying to delete keyentry.")?;
+        tx.execute("DELETE FROM persistent.keymetadata WHERE keyentryid = ?;", params![key_id])
+            .context("Trying to delete keymetadata.")?;
+        tx.execute("DELETE FROM persistent.keyparameter WHERE keyentryid = ?;", params![key_id])
+            .context("Trying to delete keyparameters.")?;
+        tx.execute("DELETE FROM persistent.grant WHERE keyentryid = ?;", params![key_id])
+            .context("Trying to delete grants.")?;
+        Ok(updated != 0)
+    }
+
+    /// Marks the given key as unreferenced and removes all of the grants to this key.
+    /// Returns Ok(true) if a key was marked unreferenced as a hint for the garbage collector.
+    pub fn unbind_key(
+        &mut self,
+        key: &KeyDescriptor,
+        key_type: KeyType,
+        caller_uid: u32,
+        check_permission: impl Fn(&KeyDescriptor, Option<KeyPermSet>) -> Result<()>,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::unbind_key", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let (key_id, access_key_descriptor, access_vector) =
+                Self::load_access_tuple(tx, key, key_type, caller_uid)
+                    .context("Trying to get access tuple.")?;
+
+            // Perform access control. It is vital that we return here if the permission is denied.
+            // So do not touch that '?' at the end.
+            check_permission(&access_key_descriptor, access_vector)
+                .context("While checking permission.")?;
+
+            Self::mark_unreferenced(tx, key_id)
+                .map(|need_gc| (need_gc, ()))
+                .context("Trying to mark the key unreferenced.")
+        })
+        .context("In unbind_key.")
+    }
+
+    fn get_key_km_uuid(tx: &Transaction, key_id: i64) -> Result<Uuid> {
+        tx.query_row(
+            "SELECT km_uuid FROM persistent.keyentry WHERE id = ?",
+            params![key_id],
+            |row| row.get(0),
+        )
+        .context("In get_key_km_uuid.")
+    }
+
+    /// Delete all artifacts belonging to the namespace given by the domain-namespace tuple.
+    /// This leaves all of the blob entries orphaned for subsequent garbage collection.
+    pub fn unbind_keys_for_namespace(&mut self, domain: Domain, namespace: i64) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::unbind_keys_for_namespace", 500);
+
+        if !(domain == Domain::APP || domain == Domain::SELINUX) {
+            return Err(KsError::Rc(ResponseCode::INVALID_ARGUMENT))
+                .context("In unbind_keys_for_namespace.");
+        }
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "DELETE FROM persistent.keymetadata
+                WHERE keyentryid IN (
+                    SELECT id FROM persistent.keyentry
+                    WHERE domain = ? AND namespace = ? AND key_type = ?
+                );",
+                params![domain.0, namespace, KeyType::Client],
+            )
+            .context("Trying to delete keymetadata.")?;
+            tx.execute(
+                "DELETE FROM persistent.keyparameter
+                WHERE keyentryid IN (
+                    SELECT id FROM persistent.keyentry
+                    WHERE domain = ? AND namespace = ? AND key_type = ?
+                );",
+                params![domain.0, namespace, KeyType::Client],
+            )
+            .context("Trying to delete keyparameters.")?;
+            tx.execute(
+                "DELETE FROM persistent.grant
+                WHERE keyentryid IN (
+                    SELECT id FROM persistent.keyentry
+                    WHERE domain = ? AND namespace = ? AND key_type = ?
+                );",
+                params![domain.0, namespace, KeyType::Client],
+            )
+            .context("Trying to delete grants.")?;
+            tx.execute(
+                "DELETE FROM persistent.keyentry
+                 WHERE domain = ? AND namespace = ? AND key_type = ?;",
+                params![domain.0, namespace, KeyType::Client],
+            )
+            .context("Trying to delete keyentry.")?;
+            Ok(()).need_gc()
+        })
+        .context("In unbind_keys_for_namespace")
+    }
+
+    fn cleanup_unreferenced(tx: &Transaction) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::cleanup_unreferenced", 500);
+        {
+            tx.execute(
+                "DELETE FROM persistent.keymetadata
+            WHERE keyentryid IN (
+                SELECT id FROM persistent.keyentry
+                WHERE state = ?
+            );",
+                params![KeyLifeCycle::Unreferenced],
+            )
+            .context("Trying to delete keymetadata.")?;
+            tx.execute(
+                "DELETE FROM persistent.keyparameter
+            WHERE keyentryid IN (
+                SELECT id FROM persistent.keyentry
+                WHERE state = ?
+            );",
+                params![KeyLifeCycle::Unreferenced],
+            )
+            .context("Trying to delete keyparameters.")?;
+            tx.execute(
+                "DELETE FROM persistent.grant
+            WHERE keyentryid IN (
+                SELECT id FROM persistent.keyentry
+                WHERE state = ?
+            );",
+                params![KeyLifeCycle::Unreferenced],
+            )
+            .context("Trying to delete grants.")?;
+            tx.execute(
+                "DELETE FROM persistent.keyentry
+                WHERE state = ?;",
+                params![KeyLifeCycle::Unreferenced],
+            )
+            .context("Trying to delete keyentry.")?;
+            Result::<()>::Ok(())
+        }
+        .context("In cleanup_unreferenced")
+    }
+
+    /// Delete the keys created on behalf of the user, denoted by the user id.
+    /// Delete all the keys unless 'keep_non_super_encrypted_keys' set to true.
+    /// Returned boolean is to hint the garbage collector to delete the unbound keys.
+    /// The caller of this function should notify the gc if the returned value is true.
+    pub fn unbind_keys_for_user(
+        &mut self,
+        user_id: u32,
+        keep_non_super_encrypted_keys: bool,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::unbind_keys_for_user", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let mut stmt = tx
+                .prepare(&format!(
+                    "SELECT id from persistent.keyentry
+                     WHERE (
+                         key_type = ?
+                         AND domain = ?
+                         AND cast ( (namespace/{aid_user_offset}) as int) = ?
+                         AND state = ?
+                     ) OR (
+                         key_type = ?
+                         AND namespace = ?
+                         AND alias = ?
+                         AND state = ?
+                     );",
+                    aid_user_offset = AID_USER_OFFSET
+                ))
+                .context(concat!(
+                    "In unbind_keys_for_user. ",
+                    "Failed to prepare the query to find the keys created by apps."
+                ))?;
+
+            let mut rows = stmt
+                .query(params![
+                    // WHERE client key:
+                    KeyType::Client,
+                    Domain::APP.0 as u32,
+                    user_id,
+                    KeyLifeCycle::Live,
+                    // OR super key:
+                    KeyType::Super,
+                    user_id,
+                    USER_SUPER_KEY.alias,
+                    KeyLifeCycle::Live
+                ])
+                .context("In unbind_keys_for_user. Failed to query the keys created by apps.")?;
+
+            let mut key_ids: Vec<i64> = Vec::new();
+            db_utils::with_rows_extract_all(&mut rows, |row| {
+                key_ids
+                    .push(row.get(0).context("Failed to read key id of a key created by an app.")?);
+                Ok(())
+            })
+            .context("In unbind_keys_for_user.")?;
+
+            let mut notify_gc = false;
+            for key_id in key_ids {
+                if keep_non_super_encrypted_keys {
+                    // Load metadata and filter out non-super-encrypted keys.
+                    if let (_, Some((_, blob_metadata)), _, _) =
+                        Self::load_blob_components(key_id, KeyEntryLoadBits::KM, tx)
+                            .context("In unbind_keys_for_user: Trying to load blob info.")?
+                    {
+                        if blob_metadata.encrypted_by().is_none() {
+                            continue;
+                        }
+                    }
+                }
+                notify_gc = Self::mark_unreferenced(&tx, key_id)
+                    .context("In unbind_keys_for_user.")?
+                    || notify_gc;
+            }
+            Ok(()).do_gc(notify_gc)
+        })
+        .context("In unbind_keys_for_user.")
+    }
+
+    fn load_key_components(
+        tx: &Transaction,
+        load_bits: KeyEntryLoadBits,
+        key_id: i64,
+    ) -> Result<KeyEntry> {
+        let metadata = KeyMetaData::load_from_db(key_id, &tx).context("In load_key_components.")?;
+
+        let (has_km_blob, key_blob_info, cert_blob, cert_chain_blob) =
+            Self::load_blob_components(key_id, load_bits, &tx)
+                .context("In load_key_components.")?;
+
+        let parameters = Self::load_key_parameters(key_id, &tx)
+            .context("In load_key_components: Trying to load key parameters.")?;
+
+        let km_uuid = Self::get_key_km_uuid(&tx, key_id)
+            .context("In load_key_components: Trying to get KM uuid.")?;
+
+        Ok(KeyEntry {
+            id: key_id,
+            key_blob_info,
+            cert: cert_blob,
+            cert_chain: cert_chain_blob,
+            km_uuid,
+            parameters,
+            metadata,
+            pure_cert: !has_km_blob,
+        })
+    }
+
+    /// Returns a list of KeyDescriptors in the selected domain/namespace.
+    /// The key descriptors will have the domain, nspace, and alias field set.
+    /// Domain must be APP or SELINUX, the caller must make sure of that.
+    pub fn list(&mut self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
+        let _wp = wd::watch_millis("KeystoreDB::list", 500);
+
+        self.with_transaction(TransactionBehavior::Deferred, |tx| {
+            let mut stmt = tx
+                .prepare(
+                    "SELECT alias FROM persistent.keyentry
+             WHERE domain = ? AND namespace = ? AND alias IS NOT NULL AND state = ?;",
+                )
+                .context("In list: Failed to prepare.")?;
+
+            let mut rows = stmt
+                .query(params![domain.0 as u32, namespace, KeyLifeCycle::Live])
+                .context("In list: Failed to query.")?;
+
+            let mut descriptors: Vec<KeyDescriptor> = Vec::new();
+            db_utils::with_rows_extract_all(&mut rows, |row| {
+                descriptors.push(KeyDescriptor {
+                    domain,
+                    nspace: namespace,
+                    alias: Some(row.get(0).context("Trying to extract alias.")?),
+                    blob: None,
+                });
+                Ok(())
+            })
+            .context("In list: Failed to extract rows.")?;
+            Ok(descriptors).no_gc()
+        })
+    }
+
+    /// Adds a grant to the grant table.
+    /// Like `load_key_entry` this function loads the access tuple before
+    /// it uses the callback for a permission check. Upon success,
+    /// it inserts the `grantee_uid`, `key_id`, and `access_vector` into the
+    /// grant table. The new row will have a randomized id, which is used as
+    /// grant id in the namespace field of the resulting KeyDescriptor.
+    pub fn grant(
+        &mut self,
+        key: &KeyDescriptor,
+        caller_uid: u32,
+        grantee_uid: u32,
+        access_vector: KeyPermSet,
+        check_permission: impl Fn(&KeyDescriptor, &KeyPermSet) -> Result<()>,
+    ) -> Result<KeyDescriptor> {
+        let _wp = wd::watch_millis("KeystoreDB::grant", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            // Load the key_id and complete the access control tuple.
+            // We ignore the access vector here because grants cannot be granted.
+            // The access vector returned here expresses the permissions the
+            // grantee has if key.domain == Domain::GRANT. But this vector
+            // cannot include the grant permission by design, so there is no way the
+            // subsequent permission check can pass.
+            // We could check key.domain == Domain::GRANT and fail early.
+            // But even if we load the access tuple by grant here, the permission
+            // check denies the attempt to create a grant by grant descriptor.
+            let (key_id, access_key_descriptor, _) =
+                Self::load_access_tuple(&tx, key, KeyType::Client, caller_uid)
+                    .context("In grant")?;
+
+            // Perform access control. It is vital that we return here if the permission
+            // was denied. So do not touch that '?' at the end of the line.
+            // This permission check checks if the caller has the grant permission
+            // for the given key and in addition to all of the permissions
+            // expressed in `access_vector`.
+            check_permission(&access_key_descriptor, &access_vector)
+                .context("In grant: check_permission failed.")?;
+
+            let grant_id = if let Some(grant_id) = tx
+                .query_row(
+                    "SELECT id FROM persistent.grant
+                WHERE keyentryid = ? AND grantee = ?;",
+                    params![key_id, grantee_uid],
+                    |row| row.get(0),
+                )
+                .optional()
+                .context("In grant: Failed get optional existing grant id.")?
+            {
+                tx.execute(
+                    "UPDATE persistent.grant
+                    SET access_vector = ?
+                    WHERE id = ?;",
+                    params![i32::from(access_vector), grant_id],
+                )
+                .context("In grant: Failed to update existing grant.")?;
+                grant_id
+            } else {
+                Self::insert_with_retry(|id| {
+                    tx.execute(
+                        "INSERT INTO persistent.grant (id, grantee, keyentryid, access_vector)
+                        VALUES (?, ?, ?, ?);",
+                        params![id, grantee_uid, key_id, i32::from(access_vector)],
+                    )
+                })
+                .context("In grant")?
+            };
+
+            Ok(KeyDescriptor { domain: Domain::GRANT, nspace: grant_id, alias: None, blob: None })
+                .no_gc()
+        })
+    }
+
+    /// This function checks permissions like `grant` and `load_key_entry`
+    /// before removing a grant from the grant table.
+    pub fn ungrant(
+        &mut self,
+        key: &KeyDescriptor,
+        caller_uid: u32,
+        grantee_uid: u32,
+        check_permission: impl Fn(&KeyDescriptor) -> Result<()>,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::ungrant", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            // Load the key_id and complete the access control tuple.
+            // We ignore the access vector here because grants cannot be granted.
+            let (key_id, access_key_descriptor, _) =
+                Self::load_access_tuple(&tx, key, KeyType::Client, caller_uid)
+                    .context("In ungrant.")?;
+
+            // Perform access control. We must return here if the permission
+            // was denied. So do not touch the '?' at the end of this line.
+            check_permission(&access_key_descriptor)
+                .context("In grant: check_permission failed.")?;
+
+            tx.execute(
+                "DELETE FROM persistent.grant
+                WHERE keyentryid = ? AND grantee = ?;",
+                params![key_id, grantee_uid],
+            )
+            .context("Failed to delete grant.")?;
+
+            Ok(()).no_gc()
+        })
+    }
+
+    // Generates a random id and passes it to the given function, which will
+    // try to insert it into a database.  If that insertion fails, retry;
+    // otherwise return the id.
+    fn insert_with_retry(inserter: impl Fn(i64) -> rusqlite::Result<usize>) -> Result<i64> {
+        loop {
+            let newid: i64 = match random() {
+                Self::UNASSIGNED_KEY_ID => continue, // UNASSIGNED_KEY_ID cannot be assigned.
+                i => i,
+            };
+            match inserter(newid) {
+                // If the id already existed, try again.
+                Err(rusqlite::Error::SqliteFailure(
+                    libsqlite3_sys::Error {
+                        code: libsqlite3_sys::ErrorCode::ConstraintViolation,
+                        extended_code: libsqlite3_sys::SQLITE_CONSTRAINT_UNIQUE,
+                    },
+                    _,
+                )) => (),
+                Err(e) => {
+                    return Err(e).context("In insert_with_retry: failed to insert into database.")
+                }
+                _ => return Ok(newid),
+            }
+        }
+    }
+
+    /// Insert or replace the auth token based on the UNIQUE constraint of the auth token table
+    pub fn insert_auth_token(&mut self, auth_token: &HardwareAuthToken) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::insert_auth_token", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "INSERT OR REPLACE INTO perboot.authtoken (challenge, user_id, auth_id,
+            authenticator_type, timestamp, mac, time_received) VALUES(?, ?, ?, ?, ?, ?, ?);",
+                params![
+                    auth_token.challenge,
+                    auth_token.userId,
+                    auth_token.authenticatorId,
+                    auth_token.authenticatorType.0 as i32,
+                    auth_token.timestamp.milliSeconds as i64,
+                    auth_token.mac,
+                    MonotonicRawTime::now(),
+                ],
+            )
+            .context("In insert_auth_token: failed to insert auth token into the database")?;
+            Ok(()).no_gc()
+        })
+    }
+
+    /// Find the newest auth token matching the given predicate.
+    pub fn find_auth_token_entry<F>(
+        &mut self,
+        p: F,
+    ) -> Result<Option<(AuthTokenEntry, MonotonicRawTime)>>
+    where
+        F: Fn(&AuthTokenEntry) -> bool,
+    {
+        let _wp = wd::watch_millis("KeystoreDB::find_auth_token_entry", 500);
+
+        self.with_transaction(TransactionBehavior::Deferred, |tx| {
+            let mut stmt = tx
+                .prepare("SELECT * from perboot.authtoken ORDER BY time_received DESC;")
+                .context("Prepare statement failed.")?;
+
+            let mut rows = stmt.query(NO_PARAMS).context("Failed to query.")?;
+
+            while let Some(row) = rows.next().context("Failed to get next row.")? {
+                let entry = AuthTokenEntry::new(
+                    HardwareAuthToken {
+                        challenge: row.get(1)?,
+                        userId: row.get(2)?,
+                        authenticatorId: row.get(3)?,
+                        authenticatorType: HardwareAuthenticatorType(row.get(4)?),
+                        timestamp: Timestamp { milliSeconds: row.get(5)? },
+                        mac: row.get(6)?,
+                    },
+                    row.get(7)?,
+                );
+                if p(&entry) {
+                    return Ok(Some((
+                        entry,
+                        Self::get_last_off_body(tx)
+                            .context("In find_auth_token_entry: Trying to get last off body")?,
+                    )))
+                    .no_gc();
+                }
+            }
+            Ok(None).no_gc()
+        })
+        .context("In find_auth_token_entry.")
+    }
+
+    /// Insert last_off_body into the metadata table at the initialization of auth token table
+    pub fn insert_last_off_body(&mut self, last_off_body: MonotonicRawTime) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::insert_last_off_body", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "INSERT OR REPLACE INTO perboot.metadata (key, value) VALUES (?, ?);",
+                params!["last_off_body", last_off_body],
+            )
+            .context("In insert_last_off_body: failed to insert.")?;
+            Ok(()).no_gc()
+        })
+    }
+
+    /// Update last_off_body when on_device_off_body is called
+    pub fn update_last_off_body(&mut self, last_off_body: MonotonicRawTime) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::update_last_off_body", 500);
+
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "UPDATE perboot.metadata SET value = ? WHERE key = ?;",
+                params![last_off_body, "last_off_body"],
+            )
+            .context("In update_last_off_body: failed to update.")?;
+            Ok(()).no_gc()
+        })
+    }
+
+    /// Get last_off_body time when finding auth tokens
+    fn get_last_off_body(tx: &Transaction) -> Result<MonotonicRawTime> {
+        let _wp = wd::watch_millis("KeystoreDB::get_last_off_body", 500);
+
+        tx.query_row(
+            "SELECT value from perboot.metadata WHERE key = ?;",
+            params!["last_off_body"],
+            |row| row.get(0),
+        )
+        .context("In get_last_off_body: query_row failed.")
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use crate::key_parameter::{
+        Algorithm, BlockMode, Digest, EcCurve, HardwareAuthenticatorType, KeyOrigin, KeyParameter,
+        KeyParameterValue, KeyPurpose, PaddingMode, SecurityLevel,
+    };
+    use crate::key_perm_set;
+    use crate::permission::{KeyPerm, KeyPermSet};
+    use crate::super_key::SuperKeyManager;
+    use keystore2_test_utils::TempDir;
+    use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+        HardwareAuthToken::HardwareAuthToken,
+        HardwareAuthenticatorType::HardwareAuthenticatorType as kmhw_authenticator_type,
+    };
+    use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
+        Timestamp::Timestamp,
+    };
+    use rusqlite::NO_PARAMS;
+    use rusqlite::{Error, TransactionBehavior};
+    use std::cell::RefCell;
+    use std::collections::BTreeMap;
+    use std::fmt::Write;
+    use std::sync::atomic::{AtomicU8, Ordering};
+    use std::sync::Arc;
+    use std::thread;
+    use std::time::{Duration, SystemTime};
+    #[cfg(disabled)]
+    use std::time::Instant;
+
+    fn new_test_db() -> Result<KeystoreDB> {
+        let conn = KeystoreDB::make_connection("file::memory:", "file::memory:")?;
+
+        let mut db = KeystoreDB { conn, gc: None };
+        db.with_transaction(TransactionBehavior::Immediate, |tx| {
+            KeystoreDB::init_tables(tx).context("Failed to initialize tables.").no_gc()
+        })?;
+        Ok(db)
+    }
+
+    fn new_test_db_with_gc<F>(path: &Path, cb: F) -> Result<KeystoreDB>
+    where
+        F: Fn(&Uuid, &[u8]) -> Result<()> + Send + 'static,
+    {
+        let super_key: Arc<SuperKeyManager> = Default::default();
+
+        let gc_db = KeystoreDB::new(path, None).expect("Failed to open test gc db_connection.");
+        let gc = Gc::new_init_with(Default::default(), move || (Box::new(cb), gc_db, super_key));
+
+        KeystoreDB::new(path, Some(Arc::new(gc)))
+    }
+
+    fn rebind_alias(
+        db: &mut KeystoreDB,
+        newid: &KeyIdGuard,
+        alias: &str,
+        domain: Domain,
+        namespace: i64,
+    ) -> Result<bool> {
+        db.with_transaction(TransactionBehavior::Immediate, |tx| {
+            KeystoreDB::rebind_alias(tx, newid, alias, &domain, &namespace).no_gc()
+        })
+        .context("In rebind_alias.")
+    }
+
+    #[test]
+    fn datetime() -> Result<()> {
+        let conn = Connection::open_in_memory()?;
+        conn.execute("CREATE TABLE test (ts DATETIME);", NO_PARAMS)?;
+        let now = SystemTime::now();
+        let duration = Duration::from_secs(1000);
+        let then = now.checked_sub(duration).unwrap();
+        let soon = now.checked_add(duration).unwrap();
+        conn.execute(
+            "INSERT INTO test (ts) VALUES (?), (?), (?);",
+            params![DateTime::try_from(now)?, DateTime::try_from(then)?, DateTime::try_from(soon)?],
+        )?;
+        let mut stmt = conn.prepare("SELECT ts FROM test ORDER BY ts ASC;")?;
+        let mut rows = stmt.query(NO_PARAMS)?;
+        assert_eq!(DateTime::try_from(then)?, rows.next()?.unwrap().get(0)?);
+        assert_eq!(DateTime::try_from(now)?, rows.next()?.unwrap().get(0)?);
+        assert_eq!(DateTime::try_from(soon)?, rows.next()?.unwrap().get(0)?);
+        assert!(rows.next()?.is_none());
+        assert!(DateTime::try_from(then)? < DateTime::try_from(now)?);
+        assert!(DateTime::try_from(then)? < DateTime::try_from(soon)?);
+        assert!(DateTime::try_from(now)? < DateTime::try_from(soon)?);
+        Ok(())
+    }
+
+    // Ensure that we're using the "injected" random function, not the real one.
+    #[test]
+    fn test_mocked_random() {
+        let rand1 = random();
+        let rand2 = random();
+        let rand3 = random();
+        if rand1 == rand2 {
+            assert_eq!(rand2 + 1, rand3);
+        } else {
+            assert_eq!(rand1 + 1, rand2);
+            assert_eq!(rand2, rand3);
+        }
+    }
+
+    // Test that we have the correct tables.
+    #[test]
+    fn test_tables() -> Result<()> {
+        let db = new_test_db()?;
+        let tables = db
+            .conn
+            .prepare("SELECT name from persistent.sqlite_master WHERE type='table' ORDER BY name;")?
+            .query_map(params![], |row| row.get(0))?
+            .collect::<rusqlite::Result<Vec<String>>>()?;
+        assert_eq!(tables.len(), 6);
+        assert_eq!(tables[0], "blobentry");
+        assert_eq!(tables[1], "blobmetadata");
+        assert_eq!(tables[2], "grant");
+        assert_eq!(tables[3], "keyentry");
+        assert_eq!(tables[4], "keymetadata");
+        assert_eq!(tables[5], "keyparameter");
+        let tables = db
+            .conn
+            .prepare("SELECT name from perboot.sqlite_master WHERE type='table' ORDER BY name;")?
+            .query_map(params![], |row| row.get(0))?
+            .collect::<rusqlite::Result<Vec<String>>>()?;
+
+        assert_eq!(tables.len(), 2);
+        assert_eq!(tables[0], "authtoken");
+        assert_eq!(tables[1], "metadata");
+        Ok(())
+    }
+
+    #[test]
+    fn test_auth_token_table_invariant() -> Result<()> {
+        let mut db = new_test_db()?;
+        let auth_token1 = HardwareAuthToken {
+            challenge: i64::MAX,
+            userId: 200,
+            authenticatorId: 200,
+            authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
+            timestamp: Timestamp { milliSeconds: 500 },
+            mac: String::from("mac").into_bytes(),
+        };
+        db.insert_auth_token(&auth_token1)?;
+        let auth_tokens_returned = get_auth_tokens(&mut db)?;
+        assert_eq!(auth_tokens_returned.len(), 1);
+
+        // insert another auth token with the same values for the columns in the UNIQUE constraint
+        // of the auth token table and different value for timestamp
+        let auth_token2 = HardwareAuthToken {
+            challenge: i64::MAX,
+            userId: 200,
+            authenticatorId: 200,
+            authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
+            timestamp: Timestamp { milliSeconds: 600 },
+            mac: String::from("mac").into_bytes(),
+        };
+
+        db.insert_auth_token(&auth_token2)?;
+        let mut auth_tokens_returned = get_auth_tokens(&mut db)?;
+        assert_eq!(auth_tokens_returned.len(), 1);
+
+        if let Some(auth_token) = auth_tokens_returned.pop() {
+            assert_eq!(auth_token.auth_token.timestamp.milliSeconds, 600);
+        }
+
+        // insert another auth token with the different values for the columns in the UNIQUE
+        // constraint of the auth token table
+        let auth_token3 = HardwareAuthToken {
+            challenge: i64::MAX,
+            userId: 201,
+            authenticatorId: 200,
+            authenticatorType: kmhw_authenticator_type(kmhw_authenticator_type::PASSWORD.0),
+            timestamp: Timestamp { milliSeconds: 600 },
+            mac: String::from("mac").into_bytes(),
+        };
+
+        db.insert_auth_token(&auth_token3)?;
+        let auth_tokens_returned = get_auth_tokens(&mut db)?;
+        assert_eq!(auth_tokens_returned.len(), 2);
+
+        Ok(())
+    }
+
+    // utility function for test_auth_token_table_invariant()
+    fn get_auth_tokens(db: &mut KeystoreDB) -> Result<Vec<AuthTokenEntry>> {
+        let mut stmt = db.conn.prepare("SELECT * from perboot.authtoken;")?;
+
+        let auth_token_entries: Vec<AuthTokenEntry> = stmt
+            .query_map(NO_PARAMS, |row| {
+                Ok(AuthTokenEntry::new(
+                    HardwareAuthToken {
+                        challenge: row.get(1)?,
+                        userId: row.get(2)?,
+                        authenticatorId: row.get(3)?,
+                        authenticatorType: HardwareAuthenticatorType(row.get(4)?),
+                        timestamp: Timestamp { milliSeconds: row.get(5)? },
+                        mac: row.get(6)?,
+                    },
+                    row.get(7)?,
+                ))
+            })?
+            .collect::<Result<Vec<AuthTokenEntry>, Error>>()?;
+        Ok(auth_token_entries)
+    }
+
+    #[test]
+    fn test_persistence_for_files() -> Result<()> {
+        let temp_dir = TempDir::new("persistent_db_test")?;
+        let mut db = KeystoreDB::new(temp_dir.path(), None)?;
+
+        db.create_key_entry(&Domain::APP, &100, &KEYSTORE_UUID)?;
+        let entries = get_keyentry(&db)?;
+        assert_eq!(entries.len(), 1);
+
+        let db = KeystoreDB::new(temp_dir.path(), None)?;
+
+        let entries_new = get_keyentry(&db)?;
+        assert_eq!(entries, entries_new);
+        Ok(())
+    }
+
+    #[test]
+    fn test_create_key_entry() -> Result<()> {
+        fn extractor(ke: &KeyEntryRow) -> (Domain, i64, Option<&str>, Uuid) {
+            (ke.domain.unwrap(), ke.namespace.unwrap(), ke.alias.as_deref(), ke.km_uuid.unwrap())
+        }
+
+        let mut db = new_test_db()?;
+
+        db.create_key_entry(&Domain::APP, &100, &KEYSTORE_UUID)?;
+        db.create_key_entry(&Domain::SELINUX, &101, &KEYSTORE_UUID)?;
+
+        let entries = get_keyentry(&db)?;
+        assert_eq!(entries.len(), 2);
+        assert_eq!(extractor(&entries[0]), (Domain::APP, 100, None, KEYSTORE_UUID));
+        assert_eq!(extractor(&entries[1]), (Domain::SELINUX, 101, None, KEYSTORE_UUID));
+
+        // Test that we must pass in a valid Domain.
+        check_result_is_error_containing_string(
+            db.create_key_entry(&Domain::GRANT, &102, &KEYSTORE_UUID),
+            "Domain Domain(1) must be either App or SELinux.",
+        );
+        check_result_is_error_containing_string(
+            db.create_key_entry(&Domain::BLOB, &103, &KEYSTORE_UUID),
+            "Domain Domain(3) must be either App or SELinux.",
+        );
+        check_result_is_error_containing_string(
+            db.create_key_entry(&Domain::KEY_ID, &104, &KEYSTORE_UUID),
+            "Domain Domain(4) must be either App or SELinux.",
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_add_unsigned_key() -> Result<()> {
+        let mut db = new_test_db()?;
+        let public_key: Vec<u8> = vec![0x01, 0x02, 0x03];
+        let private_key: Vec<u8> = vec![0x04, 0x05, 0x06];
+        let raw_public_key: Vec<u8> = vec![0x07, 0x08, 0x09];
+        db.create_attestation_key_entry(
+            &public_key,
+            &raw_public_key,
+            &private_key,
+            &KEYSTORE_UUID,
+        )?;
+        let keys = db.fetch_unsigned_attestation_keys(5, &KEYSTORE_UUID)?;
+        assert_eq!(keys.len(), 1);
+        assert_eq!(keys[0], public_key);
+        Ok(())
+    }
+
+    #[test]
+    fn test_store_signed_attestation_certificate_chain() -> Result<()> {
+        let mut db = new_test_db()?;
+        let expiration_date: i64 = 20;
+        let namespace: i64 = 30;
+        let base_byte: u8 = 1;
+        let loaded_values =
+            load_attestation_key_pool(&mut db, expiration_date, namespace, base_byte)?;
+        let chain =
+            db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace, &KEYSTORE_UUID)?;
+        assert_eq!(true, chain.is_some());
+        let cert_chain = chain.unwrap();
+        assert_eq!(cert_chain.private_key.to_vec(), loaded_values.priv_key);
+        assert_eq!(cert_chain.batch_cert, loaded_values.batch_cert);
+        assert_eq!(cert_chain.cert_chain, loaded_values.cert_chain);
+        Ok(())
+    }
+
+    #[test]
+    fn test_get_attestation_pool_status() -> Result<()> {
+        let mut db = new_test_db()?;
+        let namespace: i64 = 30;
+        load_attestation_key_pool(
+            &mut db, 10, /* expiration */
+            namespace, 0x01, /* base_byte */
+        )?;
+        load_attestation_key_pool(&mut db, 20 /* expiration */, namespace + 1, 0x02)?;
+        load_attestation_key_pool(&mut db, 40 /* expiration */, namespace + 2, 0x03)?;
+        let mut status = db.get_attestation_pool_status(9 /* expiration */, &KEYSTORE_UUID)?;
+        assert_eq!(status.expiring, 0);
+        assert_eq!(status.attested, 3);
+        assert_eq!(status.unassigned, 0);
+        assert_eq!(status.total, 3);
+        assert_eq!(
+            db.get_attestation_pool_status(15 /* expiration */, &KEYSTORE_UUID)?.expiring,
+            1
+        );
+        assert_eq!(
+            db.get_attestation_pool_status(25 /* expiration */, &KEYSTORE_UUID)?.expiring,
+            2
+        );
+        assert_eq!(
+            db.get_attestation_pool_status(60 /* expiration */, &KEYSTORE_UUID)?.expiring,
+            3
+        );
+        let public_key: Vec<u8> = vec![0x01, 0x02, 0x03];
+        let private_key: Vec<u8> = vec![0x04, 0x05, 0x06];
+        let raw_public_key: Vec<u8> = vec![0x07, 0x08, 0x09];
+        let cert_chain: Vec<u8> = vec![0x0a, 0x0b, 0x0c];
+        let batch_cert: Vec<u8> = vec![0x0d, 0x0e, 0x0f];
+        db.create_attestation_key_entry(
+            &public_key,
+            &raw_public_key,
+            &private_key,
+            &KEYSTORE_UUID,
+        )?;
+        status = db.get_attestation_pool_status(0 /* expiration */, &KEYSTORE_UUID)?;
+        assert_eq!(status.attested, 3);
+        assert_eq!(status.unassigned, 0);
+        assert_eq!(status.total, 4);
+        db.store_signed_attestation_certificate_chain(
+            &raw_public_key,
+            &batch_cert,
+            &cert_chain,
+            20,
+            &KEYSTORE_UUID,
+        )?;
+        status = db.get_attestation_pool_status(0 /* expiration */, &KEYSTORE_UUID)?;
+        assert_eq!(status.attested, 4);
+        assert_eq!(status.unassigned, 1);
+        assert_eq!(status.total, 4);
+        Ok(())
+    }
+
+    #[test]
+    fn test_remove_expired_certs() -> Result<()> {
+        let temp_dir =
+            TempDir::new("test_remove_expired_certs_").expect("Failed to create temp dir.");
+        let mut db = new_test_db_with_gc(temp_dir.path(), |_, _| Ok(()))?;
+        let expiration_date: i64 =
+            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as i64 + 10000;
+        let namespace: i64 = 30;
+        let namespace_del1: i64 = 45;
+        let namespace_del2: i64 = 60;
+        let entry_values = load_attestation_key_pool(
+            &mut db,
+            expiration_date,
+            namespace,
+            0x01, /* base_byte */
+        )?;
+        load_attestation_key_pool(&mut db, 45, namespace_del1, 0x02)?;
+        load_attestation_key_pool(&mut db, 60, namespace_del2, 0x03)?;
+
+        let blob_entry_row_count: u32 = db
+            .conn
+            .query_row("SELECT COUNT(id) FROM persistent.blobentry;", NO_PARAMS, |row| row.get(0))
+            .expect("Failed to get blob entry row count.");
+        // We expect 9 rows here because there are three blobs per attestation key, i.e.,
+        // one key, one certificate chain, and one certificate.
+        assert_eq!(blob_entry_row_count, 9);
+
+        assert_eq!(db.delete_expired_attestation_keys()?, 2);
+
+        let mut cert_chain =
+            db.retrieve_attestation_key_and_cert_chain(Domain::APP, namespace, &KEYSTORE_UUID)?;
+        assert!(cert_chain.is_some());
+        let value = cert_chain.unwrap();
+        assert_eq!(entry_values.batch_cert, value.batch_cert);
+        assert_eq!(entry_values.cert_chain, value.cert_chain);
+        assert_eq!(entry_values.priv_key, value.private_key.to_vec());
+
+        cert_chain = db.retrieve_attestation_key_and_cert_chain(
+            Domain::APP,
+            namespace_del1,
+            &KEYSTORE_UUID,
+        )?;
+        assert!(!cert_chain.is_some());
+        cert_chain = db.retrieve_attestation_key_and_cert_chain(
+            Domain::APP,
+            namespace_del2,
+            &KEYSTORE_UUID,
+        )?;
+        assert!(!cert_chain.is_some());
+
+        // Give the garbage collector half a second to catch up.
+        std::thread::sleep(Duration::from_millis(500));
+
+        let blob_entry_row_count: u32 = db
+            .conn
+            .query_row("SELECT COUNT(id) FROM persistent.blobentry;", NO_PARAMS, |row| row.get(0))
+            .expect("Failed to get blob entry row count.");
+        // There shound be 3 blob entries left, because we deleted two of the attestation
+        // key entries with three blobs each.
+        assert_eq!(blob_entry_row_count, 3);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_delete_all_attestation_keys() -> Result<()> {
+        let mut db = new_test_db()?;
+        load_attestation_key_pool(&mut db, 45 /* expiration */, 1 /* namespace */, 0x02)?;
+        load_attestation_key_pool(&mut db, 80 /* expiration */, 2 /* namespace */, 0x03)?;
+        db.create_key_entry(&Domain::APP, &42, &KEYSTORE_UUID)?;
+        let result = db.delete_all_attestation_keys()?;
+
+        // Give the garbage collector half a second to catch up.
+        std::thread::sleep(Duration::from_millis(500));
+
+        // Attestation keys should be deleted, and the regular key should remain.
+        assert_eq!(result, 2);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_rebind_alias() -> Result<()> {
+        fn extractor(
+            ke: &KeyEntryRow,
+        ) -> (Option<Domain>, Option<i64>, Option<&str>, Option<Uuid>) {
+            (ke.domain, ke.namespace, ke.alias.as_deref(), ke.km_uuid)
+        }
+
+        let mut db = new_test_db()?;
+        db.create_key_entry(&Domain::APP, &42, &KEYSTORE_UUID)?;
+        db.create_key_entry(&Domain::APP, &42, &KEYSTORE_UUID)?;
+        let entries = get_keyentry(&db)?;
+        assert_eq!(entries.len(), 2);
+        assert_eq!(
+            extractor(&entries[0]),
+            (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
+        );
+        assert_eq!(
+            extractor(&entries[1]),
+            (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
+        );
+
+        // Test that the first call to rebind_alias sets the alias.
+        rebind_alias(&mut db, &KEY_ID_LOCK.get(entries[0].id), "foo", Domain::APP, 42)?;
+        let entries = get_keyentry(&db)?;
+        assert_eq!(entries.len(), 2);
+        assert_eq!(
+            extractor(&entries[0]),
+            (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
+        );
+        assert_eq!(
+            extractor(&entries[1]),
+            (Some(Domain::APP), Some(42), None, Some(KEYSTORE_UUID))
+        );
+
+        // Test that the second call to rebind_alias also empties the old one.
+        rebind_alias(&mut db, &KEY_ID_LOCK.get(entries[1].id), "foo", Domain::APP, 42)?;
+        let entries = get_keyentry(&db)?;
+        assert_eq!(entries.len(), 2);
+        assert_eq!(extractor(&entries[0]), (None, None, None, Some(KEYSTORE_UUID)));
+        assert_eq!(
+            extractor(&entries[1]),
+            (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
+        );
+
+        // Test that we must pass in a valid Domain.
+        check_result_is_error_containing_string(
+            rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::GRANT, 42),
+            "Domain Domain(1) must be either App or SELinux.",
+        );
+        check_result_is_error_containing_string(
+            rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::BLOB, 42),
+            "Domain Domain(3) must be either App or SELinux.",
+        );
+        check_result_is_error_containing_string(
+            rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::KEY_ID, 42),
+            "Domain Domain(4) must be either App or SELinux.",
+        );
+
+        // Test that we correctly handle setting an alias for something that does not exist.
+        check_result_is_error_containing_string(
+            rebind_alias(&mut db, &KEY_ID_LOCK.get(0), "foo", Domain::SELINUX, 42),
+            "Expected to update a single entry but instead updated 0",
+        );
+        // Test that we correctly abort the transaction in this case.
+        let entries = get_keyentry(&db)?;
+        assert_eq!(entries.len(), 2);
+        assert_eq!(extractor(&entries[0]), (None, None, None, Some(KEYSTORE_UUID)));
+        assert_eq!(
+            extractor(&entries[1]),
+            (Some(Domain::APP), Some(42), Some("foo"), Some(KEYSTORE_UUID))
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_grant_ungrant() -> Result<()> {
+        const CALLER_UID: u32 = 15;
+        const GRANTEE_UID: u32 = 12;
+        const SELINUX_NAMESPACE: i64 = 7;
+
+        let mut db = new_test_db()?;
+        db.conn.execute(
+            "INSERT INTO persistent.keyentry (id, key_type, domain, namespace, alias, state, km_uuid)
+                VALUES (1, 0, 0, 15, 'key', 1, ?), (2, 0, 2, 7, 'yek', 1, ?);",
+            params![KEYSTORE_UUID, KEYSTORE_UUID],
+        )?;
+        let app_key = KeyDescriptor {
+            domain: super::Domain::APP,
+            nspace: 0,
+            alias: Some("key".to_string()),
+            blob: None,
+        };
+        const PVEC1: KeyPermSet = key_perm_set![KeyPerm::use_(), KeyPerm::get_info()];
+        const PVEC2: KeyPermSet = key_perm_set![KeyPerm::use_()];
+
+        // Reset totally predictable random number generator in case we
+        // are not the first test running on this thread.
+        reset_random();
+        let next_random = 0i64;
+
+        let app_granted_key = db
+            .grant(&app_key, CALLER_UID, GRANTEE_UID, PVEC1, |k, a| {
+                assert_eq!(*a, PVEC1);
+                assert_eq!(
+                    *k,
+                    KeyDescriptor {
+                        domain: super::Domain::APP,
+                        // namespace must be set to the caller_uid.
+                        nspace: CALLER_UID as i64,
+                        alias: Some("key".to_string()),
+                        blob: None,
+                    }
+                );
+                Ok(())
+            })
+            .unwrap();
+
+        assert_eq!(
+            app_granted_key,
+            KeyDescriptor {
+                domain: super::Domain::GRANT,
+                // The grantid is next_random due to the mock random number generator.
+                nspace: next_random,
+                alias: None,
+                blob: None,
+            }
+        );
+
+        let selinux_key = KeyDescriptor {
+            domain: super::Domain::SELINUX,
+            nspace: SELINUX_NAMESPACE,
+            alias: Some("yek".to_string()),
+            blob: None,
+        };
+
+        let selinux_granted_key = db
+            .grant(&selinux_key, CALLER_UID, 12, PVEC1, |k, a| {
+                assert_eq!(*a, PVEC1);
+                assert_eq!(
+                    *k,
+                    KeyDescriptor {
+                        domain: super::Domain::SELINUX,
+                        // namespace must be the supplied SELinux
+                        // namespace.
+                        nspace: SELINUX_NAMESPACE,
+                        alias: Some("yek".to_string()),
+                        blob: None,
+                    }
+                );
+                Ok(())
+            })
+            .unwrap();
+
+        assert_eq!(
+            selinux_granted_key,
+            KeyDescriptor {
+                domain: super::Domain::GRANT,
+                // The grantid is next_random + 1 due to the mock random number generator.
+                nspace: next_random + 1,
+                alias: None,
+                blob: None,
+            }
+        );
+
+        // This should update the existing grant with PVEC2.
+        let selinux_granted_key = db
+            .grant(&selinux_key, CALLER_UID, 12, PVEC2, |k, a| {
+                assert_eq!(*a, PVEC2);
+                assert_eq!(
+                    *k,
+                    KeyDescriptor {
+                        domain: super::Domain::SELINUX,
+                        // namespace must be the supplied SELinux
+                        // namespace.
+                        nspace: SELINUX_NAMESPACE,
+                        alias: Some("yek".to_string()),
+                        blob: None,
+                    }
+                );
+                Ok(())
+            })
+            .unwrap();
+
+        assert_eq!(
+            selinux_granted_key,
+            KeyDescriptor {
+                domain: super::Domain::GRANT,
+                // Same grant id as before. The entry was only updated.
+                nspace: next_random + 1,
+                alias: None,
+                blob: None,
+            }
+        );
+
+        {
+            // Limiting scope of stmt, because it borrows db.
+            let mut stmt = db
+                .conn
+                .prepare("SELECT id, grantee, keyentryid, access_vector FROM persistent.grant;")?;
+            let mut rows =
+                stmt.query_map::<(i64, u32, i64, KeyPermSet), _, _>(NO_PARAMS, |row| {
+                    Ok((
+                        row.get(0)?,
+                        row.get(1)?,
+                        row.get(2)?,
+                        KeyPermSet::from(row.get::<_, i32>(3)?),
+                    ))
+                })?;
+
+            let r = rows.next().unwrap().unwrap();
+            assert_eq!(r, (next_random, GRANTEE_UID, 1, PVEC1));
+            let r = rows.next().unwrap().unwrap();
+            assert_eq!(r, (next_random + 1, GRANTEE_UID, 2, PVEC2));
+            assert!(rows.next().is_none());
+        }
+
+        debug_dump_keyentry_table(&mut db)?;
+        println!("app_key {:?}", app_key);
+        println!("selinux_key {:?}", selinux_key);
+
+        db.ungrant(&app_key, CALLER_UID, GRANTEE_UID, |_| Ok(()))?;
+        db.ungrant(&selinux_key, CALLER_UID, GRANTEE_UID, |_| Ok(()))?;
+
+        Ok(())
+    }
+
+    static TEST_KEY_BLOB: &[u8] = b"my test blob";
+    static TEST_CERT_BLOB: &[u8] = b"my test cert";
+    static TEST_CERT_CHAIN_BLOB: &[u8] = b"my test cert_chain";
+
+    #[test]
+    fn test_set_blob() -> Result<()> {
+        let key_id = KEY_ID_LOCK.get(3000);
+        let mut db = new_test_db()?;
+        let mut blob_metadata = BlobMetaData::new();
+        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
+        db.set_blob(
+            &key_id,
+            SubComponentType::KEY_BLOB,
+            Some(TEST_KEY_BLOB),
+            Some(&blob_metadata),
+        )?;
+        db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
+        db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
+        drop(key_id);
+
+        let mut stmt = db.conn.prepare(
+            "SELECT subcomponent_type, keyentryid, blob, id FROM persistent.blobentry
+                ORDER BY subcomponent_type ASC;",
+        )?;
+        let mut rows = stmt
+            .query_map::<((SubComponentType, i64, Vec<u8>), i64), _, _>(NO_PARAMS, |row| {
+                Ok(((row.get(0)?, row.get(1)?, row.get(2)?), row.get(3)?))
+            })?;
+        let (r, id) = rows.next().unwrap().unwrap();
+        assert_eq!(r, (SubComponentType::KEY_BLOB, 3000, TEST_KEY_BLOB.to_vec()));
+        let (r, _) = rows.next().unwrap().unwrap();
+        assert_eq!(r, (SubComponentType::CERT, 3000, TEST_CERT_BLOB.to_vec()));
+        let (r, _) = rows.next().unwrap().unwrap();
+        assert_eq!(r, (SubComponentType::CERT_CHAIN, 3000, TEST_CERT_CHAIN_BLOB.to_vec()));
+
+        drop(rows);
+        drop(stmt);
+
+        assert_eq!(
+            db.with_transaction(TransactionBehavior::Immediate, |tx| {
+                BlobMetaData::load_from_db(id, tx).no_gc()
+            })
+            .expect("Should find blob metadata."),
+            blob_metadata
+        );
+        Ok(())
+    }
+
+    static TEST_ALIAS: &str = "my super duper key";
+
+    #[test]
+    fn test_insert_and_load_full_keyentry_domain_app() -> Result<()> {
+        let mut db = new_test_db()?;
+        let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)
+            .context("test_insert_and_load_full_keyentry_domain_app")?
+            .0;
+        let (_key_guard, key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: 0,
+                    alias: Some(TEST_ALIAS.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                1,
+                |_k, _av| Ok(()),
+            )
+            .unwrap();
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+
+        db.unbind_key(
+            &KeyDescriptor {
+                domain: Domain::APP,
+                nspace: 0,
+                alias: Some(TEST_ALIAS.to_string()),
+                blob: None,
+            },
+            KeyType::Client,
+            1,
+            |_, _| Ok(()),
+        )
+        .unwrap();
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: 0,
+                    alias: Some(TEST_ALIAS.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::NONE,
+                1,
+                |_k, _av| Ok(()),
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_insert_and_load_certificate_entry_domain_app() -> Result<()> {
+        let mut db = new_test_db()?;
+
+        db.store_new_certificate(
+            &KeyDescriptor {
+                domain: Domain::APP,
+                nspace: 1,
+                alias: Some(TEST_ALIAS.to_string()),
+                blob: None,
+            },
+            TEST_CERT_BLOB,
+            &KEYSTORE_UUID,
+        )
+        .expect("Trying to insert cert.");
+
+        let (_key_guard, mut key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: 1,
+                    alias: Some(TEST_ALIAS.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::PUBLIC,
+                1,
+                |_k, _av| Ok(()),
+            )
+            .expect("Trying to read certificate entry.");
+
+        assert!(key_entry.pure_cert());
+        assert!(key_entry.cert().is_none());
+        assert_eq!(key_entry.take_cert_chain(), Some(TEST_CERT_BLOB.to_vec()));
+
+        db.unbind_key(
+            &KeyDescriptor {
+                domain: Domain::APP,
+                nspace: 1,
+                alias: Some(TEST_ALIAS.to_string()),
+                blob: None,
+            },
+            KeyType::Client,
+            1,
+            |_, _| Ok(()),
+        )
+        .unwrap();
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: 1,
+                    alias: Some(TEST_ALIAS.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::NONE,
+                1,
+                |_k, _av| Ok(()),
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_insert_and_load_full_keyentry_domain_selinux() -> Result<()> {
+        let mut db = new_test_db()?;
+        let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, None)
+            .context("test_insert_and_load_full_keyentry_domain_selinux")?
+            .0;
+        let (_key_guard, key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::SELINUX,
+                    nspace: 1,
+                    alias: Some(TEST_ALIAS.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                1,
+                |_k, _av| Ok(()),
+            )
+            .unwrap();
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+
+        db.unbind_key(
+            &KeyDescriptor {
+                domain: Domain::SELINUX,
+                nspace: 1,
+                alias: Some(TEST_ALIAS.to_string()),
+                blob: None,
+            },
+            KeyType::Client,
+            1,
+            |_, _| Ok(()),
+        )
+        .unwrap();
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::SELINUX,
+                    nspace: 1,
+                    alias: Some(TEST_ALIAS.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::NONE,
+                1,
+                |_k, _av| Ok(()),
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_insert_and_load_full_keyentry_domain_key_id() -> Result<()> {
+        let mut db = new_test_db()?;
+        let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, None)
+            .context("test_insert_and_load_full_keyentry_domain_key_id")?
+            .0;
+        let (_, key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                1,
+                |_k, _av| Ok(()),
+            )
+            .unwrap();
+
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+
+        db.unbind_key(
+            &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
+            KeyType::Client,
+            1,
+            |_, _| Ok(()),
+        )
+        .unwrap();
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
+                KeyType::Client,
+                KeyEntryLoadBits::NONE,
+                1,
+                |_k, _av| Ok(()),
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_check_and_update_key_usage_count_with_limited_use_key() -> Result<()> {
+        let mut db = new_test_db()?;
+        let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, Some(123))
+            .context("test_check_and_update_key_usage_count_with_limited_use_key")?
+            .0;
+        // Update the usage count of the limited use key.
+        db.check_and_update_key_usage_count(key_id)?;
+
+        let (_key_guard, key_entry) = db.load_key_entry(
+            &KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, alias: None, blob: None },
+            KeyType::Client,
+            KeyEntryLoadBits::BOTH,
+            1,
+            |_k, _av| Ok(()),
+        )?;
+
+        // The usage count is decremented now.
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, Some(122)));
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_check_and_update_key_usage_count_with_exhausted_limited_use_key() -> Result<()> {
+        let mut db = new_test_db()?;
+        let key_id = make_test_key_entry(&mut db, Domain::SELINUX, 1, TEST_ALIAS, Some(1))
+            .context("test_check_and_update_key_usage_count_with_exhausted_limited_use_key")?
+            .0;
+        // Update the usage count of the limited use key.
+        db.check_and_update_key_usage_count(key_id).expect(concat!(
+            "In test_check_and_update_key_usage_count_with_exhausted_limited_use_key: ",
+            "This should succeed."
+        ));
+
+        // Try to update the exhausted limited use key.
+        let e = db.check_and_update_key_usage_count(key_id).expect_err(concat!(
+            "In test_check_and_update_key_usage_count_with_exhausted_limited_use_key: ",
+            "This should fail."
+        ));
+        assert_eq!(
+            &KsError::Km(ErrorCode::INVALID_KEY_BLOB),
+            e.root_cause().downcast_ref::<KsError>().unwrap()
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_insert_and_load_full_keyentry_from_grant() -> Result<()> {
+        let mut db = new_test_db()?;
+        let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)
+            .context("test_insert_and_load_full_keyentry_from_grant")?
+            .0;
+
+        let granted_key = db
+            .grant(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: 0,
+                    alias: Some(TEST_ALIAS.to_string()),
+                    blob: None,
+                },
+                1,
+                2,
+                key_perm_set![KeyPerm::use_()],
+                |_k, _av| Ok(()),
+            )
+            .unwrap();
+
+        debug_dump_grant_table(&mut db)?;
+
+        let (_key_guard, key_entry) = db
+            .load_key_entry(&granted_key, KeyType::Client, KeyEntryLoadBits::BOTH, 2, |k, av| {
+                assert_eq!(Domain::GRANT, k.domain);
+                assert!(av.unwrap().includes(KeyPerm::use_()));
+                Ok(())
+            })
+            .unwrap();
+
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+
+        db.unbind_key(&granted_key, KeyType::Client, 2, |_, _| Ok(())).unwrap();
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &granted_key,
+                KeyType::Client,
+                KeyEntryLoadBits::NONE,
+                2,
+                |_k, _av| Ok(()),
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    // This test attempts to load a key by key id while the caller is not the owner
+    // but a grant exists for the given key and the caller.
+    #[test]
+    fn test_insert_and_load_full_keyentry_from_grant_by_key_id() -> Result<()> {
+        let mut db = new_test_db()?;
+        const OWNER_UID: u32 = 1u32;
+        const GRANTEE_UID: u32 = 2u32;
+        const SOMEONE_ELSE_UID: u32 = 3u32;
+        let key_id = make_test_key_entry(&mut db, Domain::APP, OWNER_UID as i64, TEST_ALIAS, None)
+            .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?
+            .0;
+
+        db.grant(
+            &KeyDescriptor {
+                domain: Domain::APP,
+                nspace: 0,
+                alias: Some(TEST_ALIAS.to_string()),
+                blob: None,
+            },
+            OWNER_UID,
+            GRANTEE_UID,
+            key_perm_set![KeyPerm::use_()],
+            |_k, _av| Ok(()),
+        )
+        .unwrap();
+
+        debug_dump_grant_table(&mut db)?;
+
+        let id_descriptor =
+            KeyDescriptor { domain: Domain::KEY_ID, nspace: key_id, ..Default::default() };
+
+        let (_, key_entry) = db
+            .load_key_entry(
+                &id_descriptor,
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                GRANTEE_UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(OWNER_UID as i64, k.nspace);
+                    assert!(av.unwrap().includes(KeyPerm::use_()));
+                    Ok(())
+                },
+            )
+            .unwrap();
+
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+
+        let (_, key_entry) = db
+            .load_key_entry(
+                &id_descriptor,
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                SOMEONE_ELSE_UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(OWNER_UID as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap();
+
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+
+        db.unbind_key(&id_descriptor, KeyType::Client, OWNER_UID, |_, _| Ok(())).unwrap();
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &id_descriptor,
+                KeyType::Client,
+                KeyEntryLoadBits::NONE,
+                GRANTEE_UID,
+                |_k, _av| Ok(()),
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    // Creates a key migrates it to a different location and then tries to access it by the old
+    // and new location.
+    #[test]
+    fn test_migrate_key_app_to_app() -> Result<()> {
+        let mut db = new_test_db()?;
+        const SOURCE_UID: u32 = 1u32;
+        const DESTINATION_UID: u32 = 2u32;
+        static SOURCE_ALIAS: &str = &"SOURCE_ALIAS";
+        static DESTINATION_ALIAS: &str = &"DESTINATION_ALIAS";
+        let key_id_guard =
+            make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
+                .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
+
+        let source_descriptor: KeyDescriptor = KeyDescriptor {
+            domain: Domain::APP,
+            nspace: -1,
+            alias: Some(SOURCE_ALIAS.to_string()),
+            blob: None,
+        };
+
+        let destination_descriptor: KeyDescriptor = KeyDescriptor {
+            domain: Domain::APP,
+            nspace: -1,
+            alias: Some(DESTINATION_ALIAS.to_string()),
+            blob: None,
+        };
+
+        let key_id = key_id_guard.id();
+
+        db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| {
+            Ok(())
+        })
+        .unwrap();
+
+        let (_, key_entry) = db
+            .load_key_entry(
+                &destination_descriptor,
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                DESTINATION_UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(DESTINATION_UID as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap();
+
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &source_descriptor,
+                KeyType::Client,
+                KeyEntryLoadBits::NONE,
+                SOURCE_UID,
+                |_k, _av| Ok(()),
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    // Creates a key migrates it to a different location and then tries to access it by the old
+    // and new location.
+    #[test]
+    fn test_migrate_key_app_to_selinux() -> Result<()> {
+        let mut db = new_test_db()?;
+        const SOURCE_UID: u32 = 1u32;
+        const DESTINATION_UID: u32 = 2u32;
+        const DESTINATION_NAMESPACE: i64 = 1000i64;
+        static SOURCE_ALIAS: &str = &"SOURCE_ALIAS";
+        static DESTINATION_ALIAS: &str = &"DESTINATION_ALIAS";
+        let key_id_guard =
+            make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
+                .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
+
+        let source_descriptor: KeyDescriptor = KeyDescriptor {
+            domain: Domain::APP,
+            nspace: -1,
+            alias: Some(SOURCE_ALIAS.to_string()),
+            blob: None,
+        };
+
+        let destination_descriptor: KeyDescriptor = KeyDescriptor {
+            domain: Domain::SELINUX,
+            nspace: DESTINATION_NAMESPACE,
+            alias: Some(DESTINATION_ALIAS.to_string()),
+            blob: None,
+        };
+
+        let key_id = key_id_guard.id();
+
+        db.migrate_key_namespace(key_id_guard, &destination_descriptor, DESTINATION_UID, |_k| {
+            Ok(())
+        })
+        .unwrap();
+
+        let (_, key_entry) = db
+            .load_key_entry(
+                &destination_descriptor,
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                DESTINATION_UID,
+                |k, av| {
+                    assert_eq!(Domain::SELINUX, k.domain);
+                    assert_eq!(DESTINATION_NAMESPACE as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap();
+
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &source_descriptor,
+                KeyType::Client,
+                KeyEntryLoadBits::NONE,
+                SOURCE_UID,
+                |_k, _av| Ok(()),
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    // Creates two keys and tries to migrate the first to the location of the second which
+    // is expected to fail.
+    #[test]
+    fn test_migrate_key_destination_occupied() -> Result<()> {
+        let mut db = new_test_db()?;
+        const SOURCE_UID: u32 = 1u32;
+        const DESTINATION_UID: u32 = 2u32;
+        static SOURCE_ALIAS: &str = &"SOURCE_ALIAS";
+        static DESTINATION_ALIAS: &str = &"DESTINATION_ALIAS";
+        let key_id_guard =
+            make_test_key_entry(&mut db, Domain::APP, SOURCE_UID as i64, SOURCE_ALIAS, None)
+                .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
+        make_test_key_entry(&mut db, Domain::APP, DESTINATION_UID as i64, DESTINATION_ALIAS, None)
+            .context("test_insert_and_load_full_keyentry_from_grant_by_key_id")?;
+
+        let destination_descriptor: KeyDescriptor = KeyDescriptor {
+            domain: Domain::APP,
+            nspace: -1,
+            alias: Some(DESTINATION_ALIAS.to_string()),
+            blob: None,
+        };
+
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::INVALID_ARGUMENT)),
+            db.migrate_key_namespace(
+                key_id_guard,
+                &destination_descriptor,
+                DESTINATION_UID,
+                |_k| Ok(())
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+
+        Ok(())
+    }
+
+    static KEY_LOCK_TEST_ALIAS: &str = "my super duper locked key";
+
+    #[test]
+    fn test_insert_and_load_full_keyentry_domain_app_concurrently() -> Result<()> {
+        let handle = {
+            let temp_dir = Arc::new(TempDir::new("id_lock_test")?);
+            let temp_dir_clone = temp_dir.clone();
+            let mut db = KeystoreDB::new(temp_dir.path(), None)?;
+            let key_id = make_test_key_entry(&mut db, Domain::APP, 33, KEY_LOCK_TEST_ALIAS, None)
+                .context("test_insert_and_load_full_keyentry_domain_app")?
+                .0;
+            let (_key_guard, key_entry) = db
+                .load_key_entry(
+                    &KeyDescriptor {
+                        domain: Domain::APP,
+                        nspace: 0,
+                        alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
+                        blob: None,
+                    },
+                    KeyType::Client,
+                    KeyEntryLoadBits::BOTH,
+                    33,
+                    |_k, _av| Ok(()),
+                )
+                .unwrap();
+            assert_eq!(key_entry, make_test_key_entry_test_vector(key_id, None));
+            let state = Arc::new(AtomicU8::new(1));
+            let state2 = state.clone();
+
+            // Spawning a second thread that attempts to acquire the key id lock
+            // for the same key as the primary thread. The primary thread then
+            // waits, thereby forcing the secondary thread into the second stage
+            // of acquiring the lock (see KEY ID LOCK 2/2 above).
+            // The test succeeds if the secondary thread observes the transition
+            // of `state` from 1 to 2, despite having a whole second to overtake
+            // the primary thread.
+            let handle = thread::spawn(move || {
+                let temp_dir = temp_dir_clone;
+                let mut db = KeystoreDB::new(temp_dir.path(), None).unwrap();
+                assert!(db
+                    .load_key_entry(
+                        &KeyDescriptor {
+                            domain: Domain::APP,
+                            nspace: 0,
+                            alias: Some(KEY_LOCK_TEST_ALIAS.to_string()),
+                            blob: None,
+                        },
+                        KeyType::Client,
+                        KeyEntryLoadBits::BOTH,
+                        33,
+                        |_k, _av| Ok(()),
+                    )
+                    .is_ok());
+                // We should only see a 2 here because we can only return
+                // from load_key_entry when the `_key_guard` expires,
+                // which happens at the end of the scope.
+                assert_eq!(2, state2.load(Ordering::Relaxed));
+            });
+
+            thread::sleep(std::time::Duration::from_millis(1000));
+
+            assert_eq!(Ok(1), state.compare_exchange(1, 2, Ordering::Relaxed, Ordering::Relaxed));
+
+            // Return the handle from this scope so we can join with the
+            // secondary thread after the key id lock has expired.
+            handle
+            // This is where the `_key_guard` goes out of scope,
+            // which is the reason for concurrent load_key_entry on the same key
+            // to unblock.
+        };
+        // Join with the secondary thread and unwrap, to propagate failing asserts to the
+        // main test thread. We will not see failing asserts in secondary threads otherwise.
+        handle.join().unwrap();
+        Ok(())
+    }
+
+    #[test]
+    fn test_database_busy_error_code() {
+        let temp_dir =
+            TempDir::new("test_database_busy_error_code_").expect("Failed to create temp dir.");
+
+        let mut db1 = KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database1.");
+        let mut db2 = KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database2.");
+
+        let _tx1 = db1
+            .conn
+            .transaction_with_behavior(TransactionBehavior::Immediate)
+            .expect("Failed to create first transaction.");
+
+        let error = db2
+            .conn
+            .transaction_with_behavior(TransactionBehavior::Immediate)
+            .context("Transaction begin failed.")
+            .expect_err("This should fail.");
+        let root_cause = error.root_cause();
+        if let Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. }) =
+            root_cause.downcast_ref::<rusqlite::ffi::Error>()
+        {
+            return;
+        }
+        panic!(
+            "Unexpected error {:?} \n{:?} \n{:?}",
+            error,
+            root_cause,
+            root_cause.downcast_ref::<rusqlite::ffi::Error>()
+        )
+    }
+
+    #[cfg(disabled)]
+    #[test]
+    fn test_large_number_of_concurrent_db_manipulations() -> Result<()> {
+        let temp_dir = Arc::new(
+            TempDir::new("test_large_number_of_concurrent_db_manipulations_")
+                .expect("Failed to create temp dir."),
+        );
+
+        let test_begin = Instant::now();
+
+        let mut db = KeystoreDB::new(temp_dir.path()).expect("Failed to open database.");
+        const KEY_COUNT: u32 = 500u32;
+        const OPEN_DB_COUNT: u32 = 50u32;
+
+        let mut actual_key_count = KEY_COUNT;
+        // First insert KEY_COUNT keys.
+        for count in 0..KEY_COUNT {
+            if Instant::now().duration_since(test_begin) >= Duration::from_secs(15) {
+                actual_key_count = count;
+                break;
+            }
+            let alias = format!("test_alias_{}", count);
+            make_test_key_entry(&mut db, Domain::APP, 1, &alias, None)
+                .expect("Failed to make key entry.");
+        }
+
+        // Insert more keys from a different thread and into a different namespace.
+        let temp_dir1 = temp_dir.clone();
+        let handle1 = thread::spawn(move || {
+            let mut db = KeystoreDB::new(temp_dir1.path()).expect("Failed to open database.");
+
+            for count in 0..actual_key_count {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let alias = format!("test_alias_{}", count);
+                make_test_key_entry(&mut db, Domain::APP, 2, &alias, None)
+                    .expect("Failed to make key entry.");
+            }
+
+            // then unbind them again.
+            for count in 0..actual_key_count {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let key = KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(format!("test_alias_{}", count)),
+                    blob: None,
+                };
+                db.unbind_key(&key, KeyType::Client, 2, |_, _| Ok(())).expect("Unbind Failed.");
+            }
+        });
+
+        // And start unbinding the first set of keys.
+        let temp_dir2 = temp_dir.clone();
+        let handle2 = thread::spawn(move || {
+            let mut db = KeystoreDB::new(temp_dir2.path()).expect("Failed to open database.");
+
+            for count in 0..actual_key_count {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let key = KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(format!("test_alias_{}", count)),
+                    blob: None,
+                };
+                db.unbind_key(&key, KeyType::Client, 1, |_, _| Ok(())).expect("Unbind Failed.");
+            }
+        });
+
+        let stop_deleting = Arc::new(AtomicU8::new(0));
+        let stop_deleting2 = stop_deleting.clone();
+
+        // And delete anything that is unreferenced keys.
+        let temp_dir3 = temp_dir.clone();
+        let handle3 = thread::spawn(move || {
+            let mut db = KeystoreDB::new(temp_dir3.path()).expect("Failed to open database.");
+
+            while stop_deleting2.load(Ordering::Relaxed) != 1 {
+                while let Some((key_guard, _key)) =
+                    db.get_unreferenced_key().expect("Failed to get unreferenced Key.")
+                {
+                    if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                        return;
+                    }
+                    db.purge_key_entry(key_guard).expect("Failed to purge key.");
+                }
+                std::thread::sleep(std::time::Duration::from_millis(100));
+            }
+        });
+
+        // While a lot of inserting and deleting is going on we have to open database connections
+        // successfully and use them.
+        // This clone is not redundant, because temp_dir needs to be kept alive until db goes
+        // out of scope.
+        #[allow(clippy::redundant_clone)]
+        let temp_dir4 = temp_dir.clone();
+        let handle4 = thread::spawn(move || {
+            for count in 0..OPEN_DB_COUNT {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let mut db = KeystoreDB::new(temp_dir4.path()).expect("Failed to open database.");
+
+                let alias = format!("test_alias_{}", count);
+                make_test_key_entry(&mut db, Domain::APP, 3, &alias, None)
+                    .expect("Failed to make key entry.");
+                let key = KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(alias),
+                    blob: None,
+                };
+                db.unbind_key(&key, KeyType::Client, 3, |_, _| Ok(())).expect("Unbind Failed.");
+            }
+        });
+
+        handle1.join().expect("Thread 1 panicked.");
+        handle2.join().expect("Thread 2 panicked.");
+        handle4.join().expect("Thread 4 panicked.");
+
+        stop_deleting.store(1, Ordering::Relaxed);
+        handle3.join().expect("Thread 3 panicked.");
+
+        Ok(())
+    }
+
+    #[test]
+    fn list() -> Result<()> {
+        let temp_dir = TempDir::new("list_test")?;
+        let mut db = KeystoreDB::new(temp_dir.path(), None)?;
+        static LIST_O_ENTRIES: &[(Domain, i64, &str)] = &[
+            (Domain::APP, 1, "test1"),
+            (Domain::APP, 1, "test2"),
+            (Domain::APP, 1, "test3"),
+            (Domain::APP, 1, "test4"),
+            (Domain::APP, 1, "test5"),
+            (Domain::APP, 1, "test6"),
+            (Domain::APP, 1, "test7"),
+            (Domain::APP, 2, "test1"),
+            (Domain::APP, 2, "test2"),
+            (Domain::APP, 2, "test3"),
+            (Domain::APP, 2, "test4"),
+            (Domain::APP, 2, "test5"),
+            (Domain::APP, 2, "test6"),
+            (Domain::APP, 2, "test8"),
+            (Domain::SELINUX, 100, "test1"),
+            (Domain::SELINUX, 100, "test2"),
+            (Domain::SELINUX, 100, "test3"),
+            (Domain::SELINUX, 100, "test4"),
+            (Domain::SELINUX, 100, "test5"),
+            (Domain::SELINUX, 100, "test6"),
+            (Domain::SELINUX, 100, "test9"),
+        ];
+
+        let list_o_keys: Vec<(i64, i64)> = LIST_O_ENTRIES
+            .iter()
+            .map(|(domain, ns, alias)| {
+                let entry = make_test_key_entry(&mut db, *domain, *ns, *alias, None)
+                    .unwrap_or_else(|e| {
+                        panic!("Failed to insert {:?} {} {}. Error {:?}", domain, ns, alias, e)
+                    });
+                (entry.id(), *ns)
+            })
+            .collect();
+
+        for (domain, namespace) in
+            &[(Domain::APP, 1i64), (Domain::APP, 2i64), (Domain::SELINUX, 100i64)]
+        {
+            let mut list_o_descriptors: Vec<KeyDescriptor> = LIST_O_ENTRIES
+                .iter()
+                .filter_map(|(domain, ns, alias)| match ns {
+                    ns if *ns == *namespace => Some(KeyDescriptor {
+                        domain: *domain,
+                        nspace: *ns,
+                        alias: Some(alias.to_string()),
+                        blob: None,
+                    }),
+                    _ => None,
+                })
+                .collect();
+            list_o_descriptors.sort();
+            let mut list_result = db.list(*domain, *namespace)?;
+            list_result.sort();
+            assert_eq!(list_o_descriptors, list_result);
+
+            let mut list_o_ids: Vec<i64> = list_o_descriptors
+                .into_iter()
+                .map(|d| {
+                    let (_, entry) = db
+                        .load_key_entry(
+                            &d,
+                            KeyType::Client,
+                            KeyEntryLoadBits::NONE,
+                            *namespace as u32,
+                            |_, _| Ok(()),
+                        )
+                        .unwrap();
+                    entry.id()
+                })
+                .collect();
+            list_o_ids.sort_unstable();
+            let mut loaded_entries: Vec<i64> = list_o_keys
+                .iter()
+                .filter_map(|(id, ns)| match ns {
+                    ns if *ns == *namespace => Some(*id),
+                    _ => None,
+                })
+                .collect();
+            loaded_entries.sort_unstable();
+            assert_eq!(list_o_ids, loaded_entries);
+        }
+        assert_eq!(Vec::<KeyDescriptor>::new(), db.list(Domain::SELINUX, 101)?);
+
+        Ok(())
+    }
+
+    // Helpers
+
+    // Checks that the given result is an error containing the given string.
+    fn check_result_is_error_containing_string<T>(result: Result<T>, target: &str) {
+        let error_str = format!(
+            "{:#?}",
+            result.err().unwrap_or_else(|| panic!("Expected the error: {}", target))
+        );
+        assert!(
+            error_str.contains(target),
+            "The string \"{}\" should contain \"{}\"",
+            error_str,
+            target
+        );
+    }
+
+    #[derive(Debug, PartialEq)]
+    struct KeyEntryRow {
+        id: i64,
+        key_type: KeyType,
+        domain: Option<Domain>,
+        namespace: Option<i64>,
+        alias: Option<String>,
+        state: KeyLifeCycle,
+        km_uuid: Option<Uuid>,
+    }
+
+    fn get_keyentry(db: &KeystoreDB) -> Result<Vec<KeyEntryRow>> {
+        db.conn
+            .prepare("SELECT * FROM persistent.keyentry;")?
+            .query_map(NO_PARAMS, |row| {
+                Ok(KeyEntryRow {
+                    id: row.get(0)?,
+                    key_type: row.get(1)?,
+                    domain: match row.get(2)? {
+                        Some(i) => Some(Domain(i)),
+                        None => None,
+                    },
+                    namespace: row.get(3)?,
+                    alias: row.get(4)?,
+                    state: row.get(5)?,
+                    km_uuid: row.get(6)?,
+                })
+            })?
+            .map(|r| r.context("Could not read keyentry row."))
+            .collect::<Result<Vec<_>>>()
+    }
+
+    struct RemoteProvValues {
+        cert_chain: Vec<u8>,
+        priv_key: Vec<u8>,
+        batch_cert: Vec<u8>,
+    }
+
+    fn load_attestation_key_pool(
+        db: &mut KeystoreDB,
+        expiration_date: i64,
+        namespace: i64,
+        base_byte: u8,
+    ) -> Result<RemoteProvValues> {
+        let public_key: Vec<u8> = vec![base_byte, 0x02 * base_byte];
+        let cert_chain: Vec<u8> = vec![0x03 * base_byte, 0x04 * base_byte];
+        let priv_key: Vec<u8> = vec![0x05 * base_byte, 0x06 * base_byte];
+        let raw_public_key: Vec<u8> = vec![0x0b * base_byte, 0x0c * base_byte];
+        let batch_cert: Vec<u8> = vec![base_byte * 0x0d, base_byte * 0x0e];
+        db.create_attestation_key_entry(&public_key, &raw_public_key, &priv_key, &KEYSTORE_UUID)?;
+        db.store_signed_attestation_certificate_chain(
+            &raw_public_key,
+            &batch_cert,
+            &cert_chain,
+            expiration_date,
+            &KEYSTORE_UUID,
+        )?;
+        db.assign_attestation_key(Domain::APP, namespace, &KEYSTORE_UUID)?;
+        Ok(RemoteProvValues { cert_chain, priv_key, batch_cert })
+    }
+
+    // Note: The parameters and SecurityLevel associations are nonsensical. This
+    // collection is only used to check if the parameters are preserved as expected by the
+    // database.
+    fn make_test_params(max_usage_count: Option<i32>) -> Vec<KeyParameter> {
+        let mut params = vec![
+            KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::TRUSTED_ENVIRONMENT),
+            KeyParameter::new(
+                KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::Algorithm(Algorithm::RSA),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::TRUSTED_ENVIRONMENT),
+            KeyParameter::new(
+                KeyParameterValue::BlockMode(BlockMode::ECB),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::BlockMode(BlockMode::GCM),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::Digest(Digest::NONE), SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::Digest(Digest::MD5),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::Digest(Digest::SHA_2_224),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::Digest(Digest::SHA_2_256),
+                SecurityLevel::STRONGBOX,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::PaddingMode(PaddingMode::NONE),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::PaddingMode(PaddingMode::RSA_OAEP),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
+                SecurityLevel::STRONGBOX,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::PaddingMode(PaddingMode::RSA_PKCS1_1_5_SIGN),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::TRUSTED_ENVIRONMENT),
+            KeyParameter::new(KeyParameterValue::MinMacLength(256), SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::EcCurve(EcCurve::P_224),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::EcCurve(EcCurve::P_256), SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::EcCurve(EcCurve::P_384),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::EcCurve(EcCurve::P_521),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::RSAPublicExponent(3),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::IncludeUniqueID,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::BootLoaderOnly, SecurityLevel::STRONGBOX),
+            KeyParameter::new(KeyParameterValue::RollbackResistance, SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::ActiveDateTime(1234567890),
+                SecurityLevel::STRONGBOX,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::OriginationExpireDateTime(1234567890),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::UsageExpireDateTime(1234567890),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::MinSecondsBetweenOps(1234567890),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::MaxUsesPerBoot(1234567890),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::UserID(1), SecurityLevel::STRONGBOX),
+            KeyParameter::new(KeyParameterValue::UserSecureID(42), SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::NoAuthRequired,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::HardwareAuthenticatorType(HardwareAuthenticatorType::PASSWORD),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::AuthTimeout(1234567890), SecurityLevel::SOFTWARE),
+            KeyParameter::new(KeyParameterValue::AllowWhileOnBody, SecurityLevel::SOFTWARE),
+            KeyParameter::new(
+                KeyParameterValue::TrustedUserPresenceRequired,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::TrustedConfirmationRequired,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::UnlockedDeviceRequired,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::ApplicationID(vec![1u8, 2u8, 3u8, 4u8]),
+                SecurityLevel::SOFTWARE,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::ApplicationData(vec![4u8, 3u8, 2u8, 1u8]),
+                SecurityLevel::SOFTWARE,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::CreationDateTime(12345677890),
+                SecurityLevel::SOFTWARE,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::KeyOrigin(KeyOrigin::GENERATED),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::RootOfTrust(vec![3u8, 2u8, 1u8, 4u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::OSVersion(1), SecurityLevel::TRUSTED_ENVIRONMENT),
+            KeyParameter::new(KeyParameterValue::OSPatchLevel(2), SecurityLevel::SOFTWARE),
+            KeyParameter::new(
+                KeyParameterValue::UniqueID(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::SOFTWARE,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationChallenge(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationApplicationID(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdBrand(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdDevice(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdProduct(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdSerial(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdIMEI(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdMEID(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdManufacturer(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdModel(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::VendorPatchLevel(3),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::BootPatchLevel(4),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AssociatedData(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::Nonce(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::MacLength(256),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::ResetSinceIdRotation,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::ConfirmationToken(vec![5u8, 5u8, 5u8, 5u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+        ];
+        if let Some(value) = max_usage_count {
+            params.push(KeyParameter::new(
+                KeyParameterValue::UsageCountLimit(value),
+                SecurityLevel::SOFTWARE,
+            ));
+        }
+        params
+    }
+
+    fn make_test_key_entry(
+        db: &mut KeystoreDB,
+        domain: Domain,
+        namespace: i64,
+        alias: &str,
+        max_usage_count: Option<i32>,
+    ) -> Result<KeyIdGuard> {
+        let key_id = db.create_key_entry(&domain, &namespace, &KEYSTORE_UUID)?;
+        let mut blob_metadata = BlobMetaData::new();
+        blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
+        blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
+        blob_metadata.add(BlobMetaEntry::Iv(vec![2, 3, 1]));
+        blob_metadata.add(BlobMetaEntry::AeadTag(vec![3, 1, 2]));
+        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
+
+        db.set_blob(
+            &key_id,
+            SubComponentType::KEY_BLOB,
+            Some(TEST_KEY_BLOB),
+            Some(&blob_metadata),
+        )?;
+        db.set_blob(&key_id, SubComponentType::CERT, Some(TEST_CERT_BLOB), None)?;
+        db.set_blob(&key_id, SubComponentType::CERT_CHAIN, Some(TEST_CERT_CHAIN_BLOB), None)?;
+
+        let params = make_test_params(max_usage_count);
+        db.insert_keyparameter(&key_id, &params)?;
+
+        let mut metadata = KeyMetaData::new();
+        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
+        db.insert_key_metadata(&key_id, &metadata)?;
+        rebind_alias(db, &key_id, alias, domain, namespace)?;
+        Ok(key_id)
+    }
+
+    fn make_test_key_entry_test_vector(key_id: i64, max_usage_count: Option<i32>) -> KeyEntry {
+        let params = make_test_params(max_usage_count);
+
+        let mut blob_metadata = BlobMetaData::new();
+        blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
+        blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
+        blob_metadata.add(BlobMetaEntry::Iv(vec![2, 3, 1]));
+        blob_metadata.add(BlobMetaEntry::AeadTag(vec![3, 1, 2]));
+        blob_metadata.add(BlobMetaEntry::KmUuid(KEYSTORE_UUID));
+
+        let mut metadata = KeyMetaData::new();
+        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
+
+        KeyEntry {
+            id: key_id,
+            key_blob_info: Some((TEST_KEY_BLOB.to_vec(), blob_metadata)),
+            cert: Some(TEST_CERT_BLOB.to_vec()),
+            cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
+            km_uuid: KEYSTORE_UUID,
+            parameters: params,
+            metadata,
+            pure_cert: false,
+        }
+    }
+
+    fn debug_dump_keyentry_table(db: &mut KeystoreDB) -> Result<()> {
+        let mut stmt = db.conn.prepare(
+            "SELECT id, key_type, domain, namespace, alias, state, km_uuid FROM persistent.keyentry;",
+        )?;
+        let rows = stmt.query_map::<(i64, KeyType, i32, i64, String, KeyLifeCycle, Uuid), _, _>(
+            NO_PARAMS,
+            |row| {
+                Ok((
+                    row.get(0)?,
+                    row.get(1)?,
+                    row.get(2)?,
+                    row.get(3)?,
+                    row.get(4)?,
+                    row.get(5)?,
+                    row.get(6)?,
+                ))
+            },
+        )?;
+
+        println!("Key entry table rows:");
+        for r in rows {
+            let (id, key_type, domain, namespace, alias, state, km_uuid) = r.unwrap();
+            println!(
+                "    id: {} KeyType: {:?} Domain: {} Namespace: {} Alias: {} State: {:?} KmUuid: {:?}",
+                id, key_type, domain, namespace, alias, state, km_uuid
+            );
+        }
+        Ok(())
+    }
+
+    fn debug_dump_grant_table(db: &mut KeystoreDB) -> Result<()> {
+        let mut stmt = db
+            .conn
+            .prepare("SELECT id, grantee, keyentryid, access_vector FROM persistent.grant;")?;
+        let rows = stmt.query_map::<(i64, i64, i64, i64), _, _>(NO_PARAMS, |row| {
+            Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?))
+        })?;
+
+        println!("Grant table rows:");
+        for r in rows {
+            let (id, gt, ki, av) = r.unwrap();
+            println!("    id: {} grantee: {} key_id: {} access_vector: {}", id, gt, ki, av);
+        }
+        Ok(())
+    }
+
+    // Use a custom random number generator that repeats each number once.
+    // This allows us to test repeated elements.
+
+    thread_local! {
+        static RANDOM_COUNTER: RefCell<i64> = RefCell::new(0);
+    }
+
+    fn reset_random() {
+        RANDOM_COUNTER.with(|counter| {
+            *counter.borrow_mut() = 0;
+        })
+    }
+
+    pub fn random() -> i64 {
+        RANDOM_COUNTER.with(|counter| {
+            let result = *counter.borrow() / 2;
+            *counter.borrow_mut() += 1;
+            result
+        })
+    }
+
+    #[test]
+    fn test_last_off_body() -> Result<()> {
+        let mut db = new_test_db()?;
+        db.insert_last_off_body(MonotonicRawTime::now())?;
+        let tx = db.conn.transaction_with_behavior(TransactionBehavior::Immediate)?;
+        let last_off_body_1 = KeystoreDB::get_last_off_body(&tx)?;
+        tx.commit()?;
+        let one_second = Duration::from_secs(1);
+        thread::sleep(one_second);
+        db.update_last_off_body(MonotonicRawTime::now())?;
+        let tx2 = db.conn.transaction_with_behavior(TransactionBehavior::Immediate)?;
+        let last_off_body_2 = KeystoreDB::get_last_off_body(&tx2)?;
+        tx2.commit()?;
+        assert!(last_off_body_1.seconds() < last_off_body_2.seconds());
+        Ok(())
+    }
+
+    #[test]
+    fn test_unbind_keys_for_user() -> Result<()> {
+        let mut db = new_test_db()?;
+        db.unbind_keys_for_user(1, false)?;
+
+        make_test_key_entry(&mut db, Domain::APP, 210000, TEST_ALIAS, None)?;
+        make_test_key_entry(&mut db, Domain::APP, 110000, TEST_ALIAS, None)?;
+        db.unbind_keys_for_user(2, false)?;
+
+        assert_eq!(1, db.list(Domain::APP, 110000)?.len());
+        assert_eq!(0, db.list(Domain::APP, 210000)?.len());
+
+        db.unbind_keys_for_user(1, true)?;
+        assert_eq!(0, db.list(Domain::APP, 110000)?.len());
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_store_super_key() -> Result<()> {
+        let mut db = new_test_db()?;
+        let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
+        let super_key = keystore2_crypto::generate_aes256_key()?;
+        let secret_bytes = b"keystore2 is great.";
+        let (encrypted_secret, iv, tag) =
+            keystore2_crypto::aes_gcm_encrypt(secret_bytes, &super_key)?;
+
+        let (encrypted_super_key, metadata) =
+            SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
+        db.store_super_key(
+            1,
+            &USER_SUPER_KEY,
+            &encrypted_super_key,
+            &metadata,
+            &KeyMetaData::new(),
+        )?;
+
+        //check if super key exists
+        assert!(db.key_exists(Domain::APP, 1, &USER_SUPER_KEY.alias, KeyType::Super)?);
+
+        let (_, key_entry) = db.load_super_key(&USER_SUPER_KEY, 1)?.unwrap();
+        let loaded_super_key = SuperKeyManager::extract_super_key_from_key_entry(
+            USER_SUPER_KEY.algorithm,
+            key_entry,
+            &pw,
+            None,
+        )?;
+
+        let decrypted_secret_bytes =
+            loaded_super_key.aes_gcm_decrypt(&encrypted_secret, &iv, &tag)?;
+        assert_eq!(secret_bytes, &*decrypted_secret_bytes);
+        Ok(())
+    }
+
+    fn get_valid_statsd_storage_types() -> Vec<StatsdStorageType> {
+        vec![
+            StatsdStorageType::KeyEntry,
+            StatsdStorageType::KeyEntryIdIndex,
+            StatsdStorageType::KeyEntryDomainNamespaceIndex,
+            StatsdStorageType::BlobEntry,
+            StatsdStorageType::BlobEntryKeyEntryIdIndex,
+            StatsdStorageType::KeyParameter,
+            StatsdStorageType::KeyParameterKeyEntryIdIndex,
+            StatsdStorageType::KeyMetadata,
+            StatsdStorageType::KeyMetadataKeyEntryIdIndex,
+            StatsdStorageType::Grant,
+            StatsdStorageType::AuthToken,
+            StatsdStorageType::BlobMetadata,
+            StatsdStorageType::BlobMetadataBlobEntryIdIndex,
+        ]
+    }
+
+    /// Perform a simple check to ensure that we can query all the storage types
+    /// that are supported by the DB. Check for reasonable values.
+    #[test]
+    fn test_query_all_valid_table_sizes() -> Result<()> {
+        const PAGE_SIZE: i64 = 4096;
+
+        let mut db = new_test_db()?;
+
+        for t in get_valid_statsd_storage_types() {
+            let stat = db.get_storage_stat(t)?;
+            assert!(stat.size >= PAGE_SIZE);
+            assert!(stat.size >= stat.unused_size);
+        }
+
+        Ok(())
+    }
+
+    fn get_storage_stats_map(db: &mut KeystoreDB) -> BTreeMap<i32, Keystore2StorageStats> {
+        get_valid_statsd_storage_types()
+            .into_iter()
+            .map(|t| (t as i32, db.get_storage_stat(t).unwrap()))
+            .collect()
+    }
+
+    fn assert_storage_increased(
+        db: &mut KeystoreDB,
+        increased_storage_types: Vec<StatsdStorageType>,
+        baseline: &mut BTreeMap<i32, Keystore2StorageStats>,
+    ) {
+        for storage in increased_storage_types {
+            // Verify the expected storage increased.
+            let new = db.get_storage_stat(storage).unwrap();
+            let storage = storage as i32;
+            let old = &baseline[&storage];
+            assert!(new.size >= old.size, "{}: {} >= {}", storage, new.size, old.size);
+            assert!(
+                new.unused_size <= old.unused_size,
+                "{}: {} <= {}",
+                storage,
+                new.unused_size,
+                old.unused_size
+            );
+
+            // Update the baseline with the new value so that it succeeds in the
+            // later comparison.
+            baseline.insert(storage, new);
+        }
+
+        // Get an updated map of the storage and verify there were no unexpected changes.
+        let updated_stats = get_storage_stats_map(db);
+        assert_eq!(updated_stats.len(), baseline.len());
+
+        for &k in baseline.keys() {
+            let stringify = |map: &BTreeMap<i32, Keystore2StorageStats>| -> String {
+                let mut s = String::new();
+                for &k in map.keys() {
+                    writeln!(&mut s, "  {}: {}, {}", &k, map[&k].size, map[&k].unused_size)
+                        .expect("string concat failed");
+                }
+                s
+            };
+
+            assert!(
+                updated_stats[&k].size == baseline[&k].size
+                    && updated_stats[&k].unused_size == baseline[&k].unused_size,
+                "updated_stats:\n{}\nbaseline:\n{}",
+                stringify(&updated_stats),
+                stringify(&baseline)
+            );
+        }
+    }
+
+    #[test]
+    fn test_verify_key_table_size_reporting() -> Result<()> {
+        let mut db = new_test_db()?;
+        let mut working_stats = get_storage_stats_map(&mut db);
+
+        let key_id = db.create_key_entry(&Domain::APP, &42, &KEYSTORE_UUID)?;
+        assert_storage_increased(
+            &mut db,
+            vec![
+                StatsdStorageType::KeyEntry,
+                StatsdStorageType::KeyEntryIdIndex,
+                StatsdStorageType::KeyEntryDomainNamespaceIndex,
+            ],
+            &mut working_stats,
+        );
+
+        let mut blob_metadata = BlobMetaData::new();
+        blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
+        db.set_blob(&key_id, SubComponentType::KEY_BLOB, Some(TEST_KEY_BLOB), None)?;
+        assert_storage_increased(
+            &mut db,
+            vec![
+                StatsdStorageType::BlobEntry,
+                StatsdStorageType::BlobEntryKeyEntryIdIndex,
+                StatsdStorageType::BlobMetadata,
+                StatsdStorageType::BlobMetadataBlobEntryIdIndex,
+            ],
+            &mut working_stats,
+        );
+
+        let params = make_test_params(None);
+        db.insert_keyparameter(&key_id, &params)?;
+        assert_storage_increased(
+            &mut db,
+            vec![StatsdStorageType::KeyParameter, StatsdStorageType::KeyParameterKeyEntryIdIndex],
+            &mut working_stats,
+        );
+
+        let mut metadata = KeyMetaData::new();
+        metadata.add(KeyMetaEntry::CreationDate(DateTime::from_millis_epoch(123456789)));
+        db.insert_key_metadata(&key_id, &metadata)?;
+        assert_storage_increased(
+            &mut db,
+            vec![StatsdStorageType::KeyMetadata, StatsdStorageType::KeyMetadataKeyEntryIdIndex],
+            &mut working_stats,
+        );
+
+        let mut sum = 0;
+        for stat in working_stats.values() {
+            sum += stat.size;
+        }
+        let total = db.get_storage_stat(StatsdStorageType::Database)?.size;
+        assert!(sum <= total, "Expected sum <= total. sum: {}, total: {}", sum, total);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_verify_auth_table_size_reporting() -> Result<()> {
+        let mut db = new_test_db()?;
+        let mut working_stats = get_storage_stats_map(&mut db);
+        db.insert_auth_token(&HardwareAuthToken {
+            challenge: 123,
+            userId: 456,
+            authenticatorId: 789,
+            authenticatorType: kmhw_authenticator_type::ANY,
+            timestamp: Timestamp { milliSeconds: 10 },
+            mac: b"mac".to_vec(),
+        })?;
+        assert_storage_increased(&mut db, vec![StatsdStorageType::AuthToken], &mut working_stats);
+        Ok(())
+    }
+
+    #[test]
+    fn test_verify_grant_table_size_reporting() -> Result<()> {
+        const OWNER: i64 = 1;
+        let mut db = new_test_db()?;
+        make_test_key_entry(&mut db, Domain::APP, OWNER, TEST_ALIAS, None)?;
+
+        let mut working_stats = get_storage_stats_map(&mut db);
+        db.grant(
+            &KeyDescriptor {
+                domain: Domain::APP,
+                nspace: 0,
+                alias: Some(TEST_ALIAS.to_string()),
+                blob: None,
+            },
+            OWNER as u32,
+            123,
+            key_perm_set![KeyPerm::use_()],
+            |_, _| Ok(()),
+        )?;
+
+        assert_storage_increased(&mut db, vec![StatsdStorageType::Grant], &mut working_stats);
+
+        Ok(())
+    }
+}
diff --git a/keystore2/src/db_utils.rs b/keystore2/src/db_utils.rs
new file mode 100644
index 0000000..90f5616
--- /dev/null
+++ b/keystore2/src/db_utils.rs
@@ -0,0 +1,241 @@
+// Copyright 2020, 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.
+
+use crate::error::Error as KsError;
+use anyhow::{Context, Result};
+use rusqlite::{types::FromSql, Row, Rows};
+
+// Takes Rows as returned by a query call on prepared statement.
+// Extracts exactly one row with the `row_extractor` and fails if more
+// rows are available.
+// If no row was found, `None` is passed to the `row_extractor`.
+// This allows the row extractor to decide on an error condition or
+// a different default behavior.
+pub fn with_rows_extract_one<'a, T, F>(rows: &mut Rows<'a>, row_extractor: F) -> Result<T>
+where
+    F: FnOnce(Option<&Row<'a>>) -> Result<T>,
+{
+    let result =
+        row_extractor(rows.next().context("with_rows_extract_one: Failed to unpack row.")?);
+
+    rows.next()
+        .context("In with_rows_extract_one: Failed to unpack unexpected row.")?
+        .map_or_else(|| Ok(()), |_| Err(KsError::sys()))
+        .context("In with_rows_extract_one: Unexpected row.")?;
+
+    result
+}
+
+pub fn with_rows_extract_all<'a, F>(rows: &mut Rows<'a>, mut row_extractor: F) -> Result<()>
+where
+    F: FnMut(&Row<'a>) -> Result<()>,
+{
+    loop {
+        match rows.next().context("In with_rows_extract_all: Failed to unpack row")? {
+            Some(row) => {
+                row_extractor(&row).context("In with_rows_extract_all.")?;
+            }
+            None => break Ok(()),
+        }
+    }
+}
+
+/// This struct is defined to postpone converting rusqlite column value to the
+/// appropriate key parameter value until we know the corresponding tag value.
+/// Wraps the column index and a rusqlite row.
+pub struct SqlField<'a>(usize, &'a Row<'a>);
+
+impl<'a> SqlField<'a> {
+    /// Creates a new SqlField with the given index and row.
+    pub fn new(index: usize, row: &'a Row<'a>) -> Self {
+        Self(index, row)
+    }
+    /// Returns the column value from the row, when we know the expected type.
+    pub fn get<T: FromSql>(&self) -> rusqlite::Result<T> {
+        self.1.get(self.0)
+    }
+}
+
+/// This macro implements two types to aid in the implementation of a type safe metadata
+/// store. The first is a collection of metadata and the second is the entry in that
+/// collection. The caller has to provide the infrastructure to load and store the
+/// the collection or individual entries in a SQLite database. The idea is that once
+/// the infrastructure for a metadata collection is in place all it takes to add another
+/// field is make a new entry in the list of variants (see details below).
+///
+/// # Usage
+/// ```
+/// impl_metadata!{
+///     /// This is the name of the collection.
+///     #[derive(Debug, Default)]
+///     pub struct CollectionName;
+///     /// This is the name of the Entry type followed by a list of variants, accessor function
+///     /// names, and types.
+///     #[derive(Debug, Eq, PartialEq)]
+///     pub enum EntryName {
+///         /// An enum variant with an accessor function name.
+///         VariantA(u32) with accessor get_variant_a,
+///         /// A second variant. `MyType` must implement rusqlite::types::ToSql and FromSql.
+///         VariantB(MyType) with accessor get_variant_b,
+///         //  --- ADD NEW META DATA FIELDS HERE ---
+///         // For backwards compatibility add new entries only to
+///         // end of this list and above this comment.
+///     };
+/// }
+/// ```
+///
+/// expands to:
+///
+/// ```
+/// pub enum EntryName {
+///     VariantA(u32),
+///     VariantB(MyType),
+/// }
+///
+/// impl EntryName {}
+///     /// Returns a numeric variant id that can be used for persistent storage.
+///     fn db_tag(&self) -> i64 {...}
+///     /// Helper function that constructs a new `EntryName` given a variant identifier
+///     /// and a to-be-extracted `SqlFiled`
+///     fn new_from_sql(db_tag: i64, data: &SqlField) -> Result<Self> {...}
+/// }
+///
+/// impl ToSql for EntryName {...}
+///
+/// pub struct CollectionName {
+///     data: std::collections::HashMap<i64, EntryName>,
+/// }
+///
+/// impl CollectionName {
+///     /// Create a new collection of meta data.
+///     pub fn new() -> Self {...}
+///     /// Add a new entry to this collection. Replaces existing entries of the
+///     /// same variant unconditionally.
+///     pub fn add(&mut self, e: EntryName) {...}
+///     /// Type safe accessor function for the defined fields.
+///     pub fn get_variant_a() -> Option<u32> {...}
+///     pub fn get_variant_b() -> Option<MyType> {...}
+/// }
+///
+/// let mut collection = CollectionName::new();
+/// collection.add(EntryName::VariantA(3));
+/// let three: u32 = collection.get_variant_a().unwrap()
+/// ```
+///
+/// The caller of this macro must implement the actual database queries to load and store
+/// either a whole collection of metadata or individual fields. For example by associating
+/// with the given type:
+/// ```
+/// impl CollectionName {
+///     fn load(tx: &Transaction) -> Result<Self> {...}
+/// }
+/// ```
+#[macro_export]
+macro_rules! impl_metadata {
+    // These two macros assign incrementing numeric ids to each field which are used as
+    // database tags.
+    (@gen_consts {} {$($n:ident $nid:tt,)*} {$($count:tt)*}) => {
+        $(
+            // This allows us to reuse the variant name for these constants. The constants
+            // are private so that this exception does not spoil the public interface.
+            #[allow(non_upper_case_globals)]
+            const $n: i64 = $nid;
+        )*
+    };
+    (@gen_consts {$first:ident $(,$tail:ident)*} {$($out:tt)*} {$($count:tt)*}) => {
+        impl_metadata!(@gen_consts {$($tail),*} {$($out)* $first ($($count)*),} {$($count)* + 1});
+    };
+    (
+        $(#[$nmeta:meta])*
+        $nvis:vis struct $name:ident;
+        $(#[$emeta:meta])*
+        $evis:vis enum $entry:ident {
+            $($(#[$imeta:meta])* $vname:ident($t:ty) with accessor $func:ident),* $(,)?
+        };
+    ) => {
+        $(#[$emeta])*
+        $evis enum $entry {
+            $(
+                $(#[$imeta])*
+                $vname($t),
+            )*
+        }
+
+        impl $entry {
+            fn db_tag(&self) -> i64 {
+                match self {
+                    $(Self::$vname(_) => $name::$vname,)*
+                }
+            }
+
+            fn new_from_sql(db_tag: i64, data: &SqlField) -> anyhow::Result<Self> {
+                match db_tag {
+                    $(
+                        $name::$vname => {
+                            Ok($entry::$vname(
+                                data.get()
+                                .with_context(|| format!(
+                                    "In {}::new_from_sql: Unable to get {}.",
+                                    stringify!($entry),
+                                    stringify!($vname)
+                                ))?
+                            ))
+                        },
+                    )*
+                    _ => Err(anyhow!(format!(
+                        "In {}::new_from_sql: unknown db tag {}.",
+                        stringify!($entry), db_tag
+                    ))),
+                }
+            }
+        }
+
+        impl rusqlite::types::ToSql for $entry {
+            fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {
+                match self {
+                    $($entry::$vname(v) => v.to_sql(),)*
+                }
+            }
+        }
+
+        $(#[$nmeta])*
+        $nvis struct $name {
+            data: std::collections::HashMap<i64, $entry>,
+        }
+
+        impl $name {
+            /// Create a new instance of $name
+            pub fn new() -> Self {
+                Self{data: std::collections::HashMap::new()}
+            }
+
+            impl_metadata!{@gen_consts {$($vname),*} {} {0}}
+
+            /// Add a new instance of $entry to this collection of metadata.
+            pub fn add(&mut self, entry: $entry) {
+                self.data.insert(entry.db_tag(), entry);
+            }
+            $(
+                /// If the variant $vname is set, returns the wrapped value or None otherwise.
+                pub fn $func(&self) -> Option<&$t> {
+                    if let Some($entry::$vname(v)) = self.data.get(&Self::$vname) {
+                        Some(v)
+                    } else {
+                        None
+                    }
+                }
+            )*
+        }
+    };
+}
diff --git a/keystore2/src/ec_crypto.rs b/keystore2/src/ec_crypto.rs
new file mode 100644
index 0000000..0425d4a
--- /dev/null
+++ b/keystore2/src/ec_crypto.rs
@@ -0,0 +1,137 @@
+// Copyright 2021, 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.
+
+//! Implement ECDH-based encryption.
+
+use anyhow::{Context, Result};
+use keystore2_crypto::{
+    aes_gcm_decrypt, aes_gcm_encrypt, ec_key_generate_key, ec_key_get0_public_key,
+    ec_key_marshal_private_key, ec_key_parse_private_key, ec_point_oct_to_point,
+    ec_point_point_to_oct, ecdh_compute_key, generate_salt, hkdf_expand, hkdf_extract, ECKey, ZVec,
+    AES_256_KEY_LENGTH,
+};
+
+/// Private key for ECDH encryption.
+pub struct ECDHPrivateKey(ECKey);
+
+impl ECDHPrivateKey {
+    /// Randomly generate a fresh keypair.
+    pub fn generate() -> Result<ECDHPrivateKey> {
+        ec_key_generate_key()
+            .map(ECDHPrivateKey)
+            .context("In ECDHPrivateKey::generate: generation failed")
+    }
+
+    /// Deserialize bytes into an ECDH keypair
+    pub fn from_private_key(buf: &[u8]) -> Result<ECDHPrivateKey> {
+        ec_key_parse_private_key(buf)
+            .map(ECDHPrivateKey)
+            .context("In ECDHPrivateKey::from_private_key: parsing failed")
+    }
+
+    /// Serialize the ECDH key into bytes
+    pub fn private_key(&self) -> Result<ZVec> {
+        ec_key_marshal_private_key(&self.0)
+            .context("In ECDHPrivateKey::private_key: marshalling failed")
+    }
+
+    /// Generate the serialization of the corresponding public key
+    pub fn public_key(&self) -> Result<Vec<u8>> {
+        let point = ec_key_get0_public_key(&self.0);
+        ec_point_point_to_oct(point.get_point())
+            .context("In ECDHPrivateKey::public_key: marshalling failed")
+    }
+
+    /// Use ECDH to agree an AES key with another party whose public key we have.
+    /// Sender and recipient public keys are passed separately because they are
+    /// switched in encryption vs decryption.
+    fn agree_key(
+        &self,
+        salt: &[u8],
+        other_public_key: &[u8],
+        sender_public_key: &[u8],
+        recipient_public_key: &[u8],
+    ) -> Result<ZVec> {
+        let hkdf = hkdf_extract(sender_public_key, salt)
+            .context("In ECDHPrivateKey::agree_key: hkdf_extract on sender_public_key failed")?;
+        let hkdf = hkdf_extract(recipient_public_key, &hkdf)
+            .context("In ECDHPrivateKey::agree_key: hkdf_extract on recipient_public_key failed")?;
+        let other_public_key = ec_point_oct_to_point(other_public_key)
+            .context("In ECDHPrivateKey::agree_key: ec_point_oct_to_point failed")?;
+        let secret = ecdh_compute_key(other_public_key.get_point(), &self.0)
+            .context("In ECDHPrivateKey::agree_key: ecdh_compute_key failed")?;
+        let prk = hkdf_extract(&secret, &hkdf)
+            .context("In ECDHPrivateKey::agree_key: hkdf_extract on secret failed")?;
+
+        let aes_key = hkdf_expand(AES_256_KEY_LENGTH, &prk, b"AES-256-GCM key")
+            .context("In ECDHPrivateKey::agree_key: hkdf_expand failed")?;
+        Ok(aes_key)
+    }
+
+    /// Encrypt a message to the party with the given public key
+    pub fn encrypt_message(
+        recipient_public_key: &[u8],
+        message: &[u8],
+    ) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>, Vec<u8>, Vec<u8>)> {
+        let sender_key =
+            Self::generate().context("In ECDHPrivateKey::encrypt_message: generate failed")?;
+        let sender_public_key = sender_key
+            .public_key()
+            .context("In ECDHPrivateKey::encrypt_message: public_key failed")?;
+        let salt =
+            generate_salt().context("In ECDHPrivateKey::encrypt_message: generate_salt failed")?;
+        let aes_key = sender_key
+            .agree_key(&salt, recipient_public_key, &sender_public_key, recipient_public_key)
+            .context("In ECDHPrivateKey::encrypt_message: agree_key failed")?;
+        let (ciphertext, iv, tag) = aes_gcm_encrypt(message, &aes_key)
+            .context("In ECDHPrivateKey::encrypt_message: aes_gcm_encrypt failed")?;
+        Ok((sender_public_key, salt, iv, ciphertext, tag))
+    }
+
+    /// Decrypt a message sent to us
+    pub fn decrypt_message(
+        &self,
+        sender_public_key: &[u8],
+        salt: &[u8],
+        iv: &[u8],
+        ciphertext: &[u8],
+        tag: &[u8],
+    ) -> Result<ZVec> {
+        let recipient_public_key = self.public_key()?;
+        let aes_key = self
+            .agree_key(salt, sender_public_key, sender_public_key, &recipient_public_key)
+            .context("In ECDHPrivateKey::decrypt_message: agree_key failed")?;
+        aes_gcm_decrypt(ciphertext, iv, tag, &aes_key)
+            .context("In ECDHPrivateKey::decrypt_message: aes_gcm_decrypt failed")
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_crypto_roundtrip() -> Result<()> {
+        let message = b"Hello world";
+        let recipient = ECDHPrivateKey::generate()?;
+        let (sender_public_key, salt, iv, ciphertext, tag) =
+            ECDHPrivateKey::encrypt_message(&recipient.public_key()?, message)?;
+        let recipient = ECDHPrivateKey::from_private_key(&recipient.private_key()?)?;
+        let decrypted =
+            recipient.decrypt_message(&sender_public_key, &salt, &iv, &ciphertext, &tag)?;
+        let dc: &[u8] = &decrypted;
+        assert_eq!(message, dc);
+        Ok(())
+    }
+}
diff --git a/keystore2/src/enforcements.rs b/keystore2/src/enforcements.rs
new file mode 100644
index 0000000..04d1f77
--- /dev/null
+++ b/keystore2/src/enforcements.rs
@@ -0,0 +1,868 @@
+// Copyright 2020, 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.
+
+//! This is the Keystore 2.0 Enforcements module.
+// TODO: more description to follow.
+use crate::error::{map_binder_status, Error, ErrorCode};
+use crate::globals::{get_timestamp_service, ASYNC_TASK, DB, ENFORCEMENTS};
+use crate::key_parameter::{KeyParameter, KeyParameterValue};
+use crate::{authorization::Error as AuthzError, super_key::SuperEncryptionType};
+use crate::{
+    database::{AuthTokenEntry, MonotonicRawTime},
+    globals::SUPER_KEY,
+};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, ErrorCode::ErrorCode as Ec, HardwareAuthToken::HardwareAuthToken,
+    HardwareAuthenticatorType::HardwareAuthenticatorType,
+    KeyParameter::KeyParameter as KmKeyParameter, KeyPurpose::KeyPurpose, Tag::Tag,
+};
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
+    ISecureClock::ISecureClock, TimeStampToken::TimeStampToken,
+};
+use android_security_authorization::aidl::android::security::authorization::ResponseCode::ResponseCode as AuthzResponseCode;
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, IKeystoreSecurityLevel::KEY_FLAG_AUTH_BOUND_WITHOUT_CRYPTOGRAPHIC_LSKF_BINDING,
+    OperationChallenge::OperationChallenge,
+};
+use android_system_keystore2::binder::Strong;
+use anyhow::{Context, Result};
+use std::{
+    collections::{HashMap, HashSet},
+    sync::{
+        mpsc::{channel, Receiver, Sender, TryRecvError},
+        Arc, Mutex, Weak,
+    },
+    time::SystemTime,
+};
+
+#[derive(Debug)]
+enum AuthRequestState {
+    /// An outstanding per operation authorization request.
+    OpAuth,
+    /// An outstanding request for per operation authorization and secure timestamp.
+    TimeStampedOpAuth(Receiver<Result<TimeStampToken, Error>>),
+    /// An outstanding request for a timestamp token.
+    TimeStamp(Receiver<Result<TimeStampToken, Error>>),
+}
+
+#[derive(Debug)]
+struct AuthRequest {
+    state: AuthRequestState,
+    /// This need to be set to Some to fulfill a AuthRequestState::OpAuth or
+    /// AuthRequestState::TimeStampedOpAuth.
+    hat: Mutex<Option<HardwareAuthToken>>,
+}
+
+unsafe impl Sync for AuthRequest {}
+
+impl AuthRequest {
+    fn op_auth() -> Arc<Self> {
+        Arc::new(Self { state: AuthRequestState::OpAuth, hat: Mutex::new(None) })
+    }
+
+    fn timestamped_op_auth(receiver: Receiver<Result<TimeStampToken, Error>>) -> Arc<Self> {
+        Arc::new(Self {
+            state: AuthRequestState::TimeStampedOpAuth(receiver),
+            hat: Mutex::new(None),
+        })
+    }
+
+    fn timestamp(
+        hat: HardwareAuthToken,
+        receiver: Receiver<Result<TimeStampToken, Error>>,
+    ) -> Arc<Self> {
+        Arc::new(Self { state: AuthRequestState::TimeStamp(receiver), hat: Mutex::new(Some(hat)) })
+    }
+
+    fn add_auth_token(&self, hat: HardwareAuthToken) {
+        *self.hat.lock().unwrap() = Some(hat)
+    }
+
+    fn get_auth_tokens(&self) -> Result<(HardwareAuthToken, Option<TimeStampToken>)> {
+        let hat = self
+            .hat
+            .lock()
+            .unwrap()
+            .take()
+            .ok_or(Error::Km(ErrorCode::KEY_USER_NOT_AUTHENTICATED))
+            .context("In get_auth_tokens: No operation auth token received.")?;
+
+        let tst = match &self.state {
+            AuthRequestState::TimeStampedOpAuth(recv) | AuthRequestState::TimeStamp(recv) => {
+                let result = recv.recv().context("In get_auth_tokens: Sender disconnected.")?;
+                Some(result.context(concat!(
+                    "In get_auth_tokens: Worker responded with error ",
+                    "from generating timestamp token."
+                ))?)
+            }
+            AuthRequestState::OpAuth => None,
+        };
+        Ok((hat, tst))
+    }
+}
+
+/// DeferredAuthState describes how auth tokens and timestamp tokens need to be provided when
+/// updating and finishing an operation.
+#[derive(Debug)]
+enum DeferredAuthState {
+    /// Used when an operation does not require further authorization.
+    NoAuthRequired,
+    /// Indicates that the operation requires an operation specific token. This means we have
+    /// to return an operation challenge to the client which should reward us with an
+    /// operation specific auth token. If it is not provided before the client calls update
+    /// or finish, the operation fails as not authorized.
+    OpAuthRequired,
+    /// Indicates that the operation requires a time stamp token. The auth token was already
+    /// loaded from the database, but it has to be accompanied by a time stamp token to inform
+    /// the target KM with a different clock about the time on the authenticators.
+    TimeStampRequired(HardwareAuthToken),
+    /// Indicates that both an operation bound auth token and a verification token are
+    /// before the operation can commence.
+    TimeStampedOpAuthRequired,
+    /// In this state the auth info is waiting for the deferred authorizations to come in.
+    /// We block on timestamp tokens, because we can always make progress on these requests.
+    /// The per-op auth tokens might never come, which means we fail if the client calls
+    /// update or finish before we got a per-op auth token.
+    Waiting(Arc<AuthRequest>),
+    /// In this state we have gotten all of the required tokens, we just cache them to
+    /// be used when the operation progresses.
+    Token(HardwareAuthToken, Option<TimeStampToken>),
+}
+
+/// Auth info hold all of the authorization related information of an operation. It is stored
+/// in and owned by the operation. It is constructed by authorize_create and stays with the
+/// operation until it completes.
+#[derive(Debug)]
+pub struct AuthInfo {
+    state: DeferredAuthState,
+    /// An optional key id required to update the usage count if the key usage is limited.
+    key_usage_limited: Option<i64>,
+    confirmation_token_receiver: Option<Arc<Mutex<Option<Receiver<Vec<u8>>>>>>,
+}
+
+struct TokenReceiverMap {
+    /// The map maps an outstanding challenge to a TokenReceiver. If an incoming Hardware Auth
+    /// Token (HAT) has the map key in its challenge field, it gets passed to the TokenReceiver
+    /// and the entry is removed from the map. In the case where no HAT is received before the
+    /// corresponding operation gets dropped, the entry goes stale. So every time the cleanup
+    /// counter (second field in the tuple) turns 0, the map is cleaned from stale entries.
+    /// The cleanup counter is decremented every time a new receiver is added.
+    /// and reset to TokenReceiverMap::CLEANUP_PERIOD + 1 after each cleanup.
+    map_and_cleanup_counter: Mutex<(HashMap<i64, TokenReceiver>, u8)>,
+}
+
+impl Default for TokenReceiverMap {
+    fn default() -> Self {
+        Self { map_and_cleanup_counter: Mutex::new((HashMap::new(), Self::CLEANUP_PERIOD + 1)) }
+    }
+}
+
+impl TokenReceiverMap {
+    /// There is a chance that receivers may become stale because their operation is dropped
+    /// without ever being authorized. So occasionally we iterate through the map and throw
+    /// out obsolete entries.
+    /// This is the number of calls to add_receiver between cleanups.
+    const CLEANUP_PERIOD: u8 = 25;
+
+    pub fn add_auth_token(&self, hat: HardwareAuthToken) {
+        let recv = {
+            // Limit the scope of the mutex guard, so that it is not held while the auth token is
+            // added.
+            let mut map = self.map_and_cleanup_counter.lock().unwrap();
+            let (ref mut map, _) = *map;
+            map.remove_entry(&hat.challenge)
+        };
+
+        if let Some((_, recv)) = recv {
+            recv.add_auth_token(hat);
+        }
+    }
+
+    pub fn add_receiver(&self, challenge: i64, recv: TokenReceiver) {
+        let mut map = self.map_and_cleanup_counter.lock().unwrap();
+        let (ref mut map, ref mut cleanup_counter) = *map;
+        map.insert(challenge, recv);
+
+        *cleanup_counter -= 1;
+        if *cleanup_counter == 0 {
+            map.retain(|_, v| !v.is_obsolete());
+            map.shrink_to_fit();
+            *cleanup_counter = Self::CLEANUP_PERIOD + 1;
+        }
+    }
+}
+
+#[derive(Debug)]
+struct TokenReceiver(Weak<AuthRequest>);
+
+impl TokenReceiver {
+    fn is_obsolete(&self) -> bool {
+        self.0.upgrade().is_none()
+    }
+
+    fn add_auth_token(&self, hat: HardwareAuthToken) {
+        if let Some(state_arc) = self.0.upgrade() {
+            state_arc.add_auth_token(hat);
+        }
+    }
+}
+
+fn get_timestamp_token(challenge: i64) -> Result<TimeStampToken, Error> {
+    let dev: Strong<dyn ISecureClock> = get_timestamp_service()
+        .expect(concat!(
+            "Secure Clock service must be present ",
+            "if TimeStampTokens are required."
+        ))
+        .get_interface()
+        .expect("Fatal: Timestamp service does not implement ISecureClock.");
+    map_binder_status(dev.generateTimeStamp(challenge))
+}
+
+fn timestamp_token_request(challenge: i64, sender: Sender<Result<TimeStampToken, Error>>) {
+    if let Err(e) = sender.send(get_timestamp_token(challenge)) {
+        log::info!(
+            concat!(
+                "In timestamp_token_request: Receiver hung up ",
+                "before timestamp token could be delivered. {:?}"
+            ),
+            e
+        );
+    }
+}
+
+impl AuthInfo {
+    /// This function gets called after an operation was successfully created.
+    /// It makes all the preparations required, so that the operation has all the authentication
+    /// related artifacts to advance on update and finish.
+    pub fn finalize_create_authorization(&mut self, challenge: i64) -> Option<OperationChallenge> {
+        match &self.state {
+            DeferredAuthState::OpAuthRequired => {
+                let auth_request = AuthRequest::op_auth();
+                let token_receiver = TokenReceiver(Arc::downgrade(&auth_request));
+                ENFORCEMENTS.register_op_auth_receiver(challenge, token_receiver);
+
+                self.state = DeferredAuthState::Waiting(auth_request);
+                Some(OperationChallenge { challenge })
+            }
+            DeferredAuthState::TimeStampedOpAuthRequired => {
+                let (sender, receiver) = channel::<Result<TimeStampToken, Error>>();
+                let auth_request = AuthRequest::timestamped_op_auth(receiver);
+                let token_receiver = TokenReceiver(Arc::downgrade(&auth_request));
+                ENFORCEMENTS.register_op_auth_receiver(challenge, token_receiver);
+
+                ASYNC_TASK.queue_hi(move |_| timestamp_token_request(challenge, sender));
+                self.state = DeferredAuthState::Waiting(auth_request);
+                Some(OperationChallenge { challenge })
+            }
+            DeferredAuthState::TimeStampRequired(hat) => {
+                let hat = (*hat).clone();
+                let (sender, receiver) = channel::<Result<TimeStampToken, Error>>();
+                let auth_request = AuthRequest::timestamp(hat, receiver);
+                ASYNC_TASK.queue_hi(move |_| timestamp_token_request(challenge, sender));
+                self.state = DeferredAuthState::Waiting(auth_request);
+                None
+            }
+            _ => None,
+        }
+    }
+
+    /// This function is the authorization hook called before operation update.
+    /// It returns the auth tokens required by the operation to commence update.
+    pub fn before_update(&mut self) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>)> {
+        self.get_auth_tokens()
+    }
+
+    /// This function is the authorization hook called before operation finish.
+    /// It returns the auth tokens required by the operation to commence finish.
+    /// The third token is a confirmation token.
+    pub fn before_finish(
+        &mut self,
+    ) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>, Option<Vec<u8>>)> {
+        let mut confirmation_token: Option<Vec<u8>> = None;
+        if let Some(ref confirmation_token_receiver) = self.confirmation_token_receiver {
+            let locked_receiver = confirmation_token_receiver.lock().unwrap();
+            if let Some(ref receiver) = *locked_receiver {
+                loop {
+                    match receiver.try_recv() {
+                        // As long as we get tokens we loop and discard all but the most
+                        // recent one.
+                        Ok(t) => confirmation_token = Some(t),
+                        Err(TryRecvError::Empty) => break,
+                        Err(TryRecvError::Disconnected) => {
+                            log::error!(concat!(
+                                "We got disconnected from the APC service, ",
+                                "this should never happen."
+                            ));
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        self.get_auth_tokens().map(|(hat, tst)| (hat, tst, confirmation_token))
+    }
+
+    /// This function is the authorization hook called after finish succeeded.
+    /// As of this writing it checks if the key was a limited use key. If so it updates the
+    /// use counter of the key in the database. When the use counter is depleted, the key gets
+    /// marked for deletion and the garbage collector is notified.
+    pub fn after_finish(&self) -> Result<()> {
+        if let Some(key_id) = self.key_usage_limited {
+            // On the last successful use, the key gets deleted. In this case we
+            // have to notify the garbage collector.
+            DB.with(|db| {
+                db.borrow_mut()
+                    .check_and_update_key_usage_count(key_id)
+                    .context("Trying to update key usage count.")
+            })
+            .context("In after_finish.")?;
+        }
+        Ok(())
+    }
+
+    /// This function returns the auth tokens as needed by the ongoing operation or fails
+    /// with ErrorCode::KEY_USER_NOT_AUTHENTICATED. If this was called for the first time
+    /// after a deferred authorization was requested by finalize_create_authorization, this
+    /// function may block on the generation of a time stamp token. It then moves the
+    /// tokens into the DeferredAuthState::Token state for future use.
+    fn get_auth_tokens(&mut self) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>)> {
+        let deferred_tokens = if let DeferredAuthState::Waiting(ref auth_request) = self.state {
+            Some(auth_request.get_auth_tokens().context("In AuthInfo::get_auth_tokens.")?)
+        } else {
+            None
+        };
+
+        if let Some((hat, tst)) = deferred_tokens {
+            self.state = DeferredAuthState::Token(hat, tst);
+        }
+
+        match &self.state {
+            DeferredAuthState::NoAuthRequired => Ok((None, None)),
+            DeferredAuthState::Token(hat, tst) => Ok((Some((*hat).clone()), (*tst).clone())),
+            DeferredAuthState::OpAuthRequired
+            | DeferredAuthState::TimeStampedOpAuthRequired
+            | DeferredAuthState::TimeStampRequired(_) => {
+                Err(Error::Km(ErrorCode::KEY_USER_NOT_AUTHENTICATED)).context(concat!(
+                    "In AuthInfo::get_auth_tokens: No operation auth token requested??? ",
+                    "This should not happen."
+                ))
+            }
+            // This should not be reachable, because it should have been handled above.
+            DeferredAuthState::Waiting(_) => {
+                Err(Error::sys()).context("In AuthInfo::get_auth_tokens: Cannot be reached.")
+            }
+        }
+    }
+}
+
+/// Enforcements data structure
+#[derive(Default)]
+pub struct Enforcements {
+    /// This hash set contains the user ids for whom the device is currently unlocked. If a user id
+    /// is not in the set, it implies that the device is locked for the user.
+    device_unlocked_set: Mutex<HashSet<i32>>,
+    /// This field maps outstanding auth challenges to their operations. When an auth token
+    /// with the right challenge is received it is passed to the map using
+    /// TokenReceiverMap::add_auth_token() which removes the entry from the map. If an entry goes
+    /// stale, because the operation gets dropped before an auth token is received, the map
+    /// is cleaned up in regular intervals.
+    op_auth_map: TokenReceiverMap,
+    /// The enforcement module will try to get a confirmation token from this channel whenever
+    /// an operation that requires confirmation finishes.
+    confirmation_token_receiver: Arc<Mutex<Option<Receiver<Vec<u8>>>>>,
+}
+
+impl Enforcements {
+    /// Install the confirmation token receiver. The enforcement module will try to get a
+    /// confirmation token from this channel whenever an operation that requires confirmation
+    /// finishes.
+    pub fn install_confirmation_token_receiver(
+        &self,
+        confirmation_token_receiver: Receiver<Vec<u8>>,
+    ) {
+        *self.confirmation_token_receiver.lock().unwrap() = Some(confirmation_token_receiver);
+    }
+
+    /// Checks if a create call is authorized, given key parameters and operation parameters.
+    /// It returns an optional immediate auth token which can be presented to begin, and an
+    /// AuthInfo object which stays with the authorized operation and is used to obtain
+    /// auth tokens and timestamp tokens as required by the operation.
+    /// With regard to auth tokens, the following steps are taken:
+    ///
+    /// If no key parameters are given (typically when the client is self managed
+    /// (see Domain.Blob)) nothing is enforced.
+    /// If the key is time-bound, find a matching auth token from the database.
+    /// If the above step is successful, and if requires_timestamp is given, the returned
+    /// AuthInfo will provide a Timestamp token as appropriate.
+    pub fn authorize_create(
+        &self,
+        purpose: KeyPurpose,
+        key_properties: Option<&(i64, Vec<KeyParameter>)>,
+        op_params: &[KmKeyParameter],
+        requires_timestamp: bool,
+    ) -> Result<(Option<HardwareAuthToken>, AuthInfo)> {
+        let (key_id, key_params) = match key_properties {
+            Some((key_id, key_params)) => (*key_id, key_params),
+            None => {
+                return Ok((
+                    None,
+                    AuthInfo {
+                        state: DeferredAuthState::NoAuthRequired,
+                        key_usage_limited: None,
+                        confirmation_token_receiver: None,
+                    },
+                ))
+            }
+        };
+
+        match purpose {
+            // Allow SIGN, DECRYPT for both symmetric and asymmetric keys.
+            KeyPurpose::SIGN | KeyPurpose::DECRYPT => {}
+            // Rule out WRAP_KEY purpose
+            KeyPurpose::WRAP_KEY => {
+                return Err(Error::Km(Ec::INCOMPATIBLE_PURPOSE))
+                    .context("In authorize_create: WRAP_KEY purpose is not allowed here.");
+            }
+            // Allow AGREE_KEY for EC keys only.
+            KeyPurpose::AGREE_KEY => {
+                for kp in key_params.iter() {
+                    if kp.get_tag() == Tag::ALGORITHM
+                        && *kp.key_parameter_value() != KeyParameterValue::Algorithm(Algorithm::EC)
+                    {
+                        return Err(Error::Km(Ec::UNSUPPORTED_PURPOSE)).context(
+                            "In authorize_create: key agreement is only supported for EC keys.",
+                        );
+                    }
+                }
+            }
+            KeyPurpose::VERIFY | KeyPurpose::ENCRYPT => {
+                // We do not support ENCRYPT and VERIFY (the remaining two options of purpose) for
+                // asymmetric keys.
+                for kp in key_params.iter() {
+                    match *kp.key_parameter_value() {
+                        KeyParameterValue::Algorithm(Algorithm::RSA)
+                        | KeyParameterValue::Algorithm(Algorithm::EC) => {
+                            return Err(Error::Km(Ec::UNSUPPORTED_PURPOSE)).context(
+                                "In authorize_create: public operations on asymmetric keys are not
+                                 supported.",
+                            );
+                        }
+                        _ => {}
+                    }
+                }
+            }
+            _ => {
+                return Err(Error::Km(Ec::UNSUPPORTED_PURPOSE))
+                    .context("In authorize_create: specified purpose is not supported.");
+            }
+        }
+        // The following variables are to record information from key parameters to be used in
+        // enforcements, when two or more such pieces of information are required for enforcements.
+        // There is only one additional variable than what legacy keystore has, but this helps
+        // reduce the number of for loops on key parameters from 3 to 1, compared to legacy keystore
+        let mut key_purpose_authorized: bool = false;
+        let mut user_auth_type: Option<HardwareAuthenticatorType> = None;
+        let mut no_auth_required: bool = false;
+        let mut caller_nonce_allowed = false;
+        let mut user_id: i32 = -1;
+        let mut user_secure_ids = Vec::<i64>::new();
+        let mut key_time_out: Option<i64> = None;
+        let mut allow_while_on_body = false;
+        let mut unlocked_device_required = false;
+        let mut key_usage_limited: Option<i64> = None;
+        let mut confirmation_token_receiver: Option<Arc<Mutex<Option<Receiver<Vec<u8>>>>>> = None;
+        let mut max_boot_level: Option<i32> = None;
+
+        // iterate through key parameters, recording information we need for authorization
+        // enforcements later, or enforcing authorizations in place, where applicable
+        for key_param in key_params.iter() {
+            match key_param.key_parameter_value() {
+                KeyParameterValue::NoAuthRequired => {
+                    no_auth_required = true;
+                }
+                KeyParameterValue::AuthTimeout(t) => {
+                    key_time_out = Some(*t as i64);
+                }
+                KeyParameterValue::HardwareAuthenticatorType(a) => {
+                    user_auth_type = Some(*a);
+                }
+                KeyParameterValue::KeyPurpose(p) => {
+                    // The following check has the effect of key_params.contains(purpose)
+                    // Also, authorizing purpose can not be completed here, if there can be multiple
+                    // key parameters for KeyPurpose.
+                    key_purpose_authorized = key_purpose_authorized || *p == purpose;
+                }
+                KeyParameterValue::CallerNonce => {
+                    caller_nonce_allowed = true;
+                }
+                KeyParameterValue::ActiveDateTime(a) => {
+                    if !Enforcements::is_given_time_passed(*a, true) {
+                        return Err(Error::Km(Ec::KEY_NOT_YET_VALID))
+                            .context("In authorize_create: key is not yet active.");
+                    }
+                }
+                KeyParameterValue::OriginationExpireDateTime(o) => {
+                    if (purpose == KeyPurpose::ENCRYPT || purpose == KeyPurpose::SIGN)
+                        && Enforcements::is_given_time_passed(*o, false)
+                    {
+                        return Err(Error::Km(Ec::KEY_EXPIRED))
+                            .context("In authorize_create: key is expired.");
+                    }
+                }
+                KeyParameterValue::UsageExpireDateTime(u) => {
+                    if (purpose == KeyPurpose::DECRYPT || purpose == KeyPurpose::VERIFY)
+                        && Enforcements::is_given_time_passed(*u, false)
+                    {
+                        return Err(Error::Km(Ec::KEY_EXPIRED))
+                            .context("In authorize_create: key is expired.");
+                    }
+                }
+                KeyParameterValue::UserSecureID(s) => {
+                    user_secure_ids.push(*s);
+                }
+                KeyParameterValue::UserID(u) => {
+                    user_id = *u;
+                }
+                KeyParameterValue::UnlockedDeviceRequired => {
+                    unlocked_device_required = true;
+                }
+                KeyParameterValue::AllowWhileOnBody => {
+                    allow_while_on_body = true;
+                }
+                KeyParameterValue::UsageCountLimit(_) => {
+                    // We don't examine the limit here because this is enforced on finish.
+                    // Instead, we store the key_id so that finish can look up the key
+                    // in the database again and check and update the counter.
+                    key_usage_limited = Some(key_id);
+                }
+                KeyParameterValue::TrustedConfirmationRequired => {
+                    confirmation_token_receiver = Some(self.confirmation_token_receiver.clone());
+                }
+                KeyParameterValue::MaxBootLevel(level) => {
+                    max_boot_level = Some(*level);
+                }
+                // NOTE: as per offline discussion, sanitizing key parameters and rejecting
+                // create operation if any non-allowed tags are present, is not done in
+                // authorize_create (unlike in legacy keystore where AuthorizeBegin is rejected if
+                // a subset of non-allowed tags are present). Because sanitizing key parameters
+                // should have been done during generate/import key, by KeyMint.
+                _ => { /*Do nothing on all the other key parameters, as in legacy keystore*/ }
+            }
+        }
+
+        // authorize the purpose
+        if !key_purpose_authorized {
+            return Err(Error::Km(Ec::INCOMPATIBLE_PURPOSE))
+                .context("In authorize_create: the purpose is not authorized.");
+        }
+
+        // if both NO_AUTH_REQUIRED and USER_SECURE_ID tags are present, return error
+        if !user_secure_ids.is_empty() && no_auth_required {
+            return Err(Error::Km(Ec::INVALID_KEY_BLOB)).context(
+                "In authorize_create: key has both NO_AUTH_REQUIRED
+                and USER_SECURE_ID tags.",
+            );
+        }
+
+        // if either of auth_type or secure_id is present and the other is not present, return error
+        if (user_auth_type.is_some() && user_secure_ids.is_empty())
+            || (user_auth_type.is_none() && !user_secure_ids.is_empty())
+        {
+            return Err(Error::Km(Ec::KEY_USER_NOT_AUTHENTICATED)).context(
+                "In authorize_create: Auth required, but either auth type or secure ids
+                are not present.",
+            );
+        }
+
+        // validate caller nonce for origination purposes
+        if (purpose == KeyPurpose::ENCRYPT || purpose == KeyPurpose::SIGN)
+            && !caller_nonce_allowed
+            && op_params.iter().any(|kp| kp.tag == Tag::NONCE)
+        {
+            return Err(Error::Km(Ec::CALLER_NONCE_PROHIBITED)).context(
+                "In authorize_create, NONCE is present,
+                    although CALLER_NONCE is not present",
+            );
+        }
+
+        if unlocked_device_required {
+            // check the device locked status. If locked, operations on the key are not
+            // allowed.
+            if self.is_device_locked(user_id) {
+                return Err(Error::Km(Ec::DEVICE_LOCKED))
+                    .context("In authorize_create: device is locked.");
+            }
+        }
+
+        if let Some(level) = max_boot_level {
+            if !SUPER_KEY.level_accessible(level) {
+                return Err(Error::Km(Ec::BOOT_LEVEL_EXCEEDED))
+                    .context("In authorize_create: boot level is too late.");
+            }
+        }
+
+        if !unlocked_device_required && no_auth_required {
+            return Ok((
+                None,
+                AuthInfo {
+                    state: DeferredAuthState::NoAuthRequired,
+                    key_usage_limited,
+                    confirmation_token_receiver,
+                },
+            ));
+        }
+
+        let has_sids = !user_secure_ids.is_empty();
+
+        let timeout_bound = key_time_out.is_some() && has_sids;
+
+        let per_op_bound = key_time_out.is_none() && has_sids;
+
+        let need_auth_token = timeout_bound || unlocked_device_required;
+
+        let hat_and_last_off_body = if need_auth_token {
+            let hat_and_last_off_body = Self::find_auth_token(|hat: &AuthTokenEntry| {
+                if let (Some(auth_type), true) = (user_auth_type, has_sids) {
+                    hat.satisfies(&user_secure_ids, auth_type)
+                } else {
+                    unlocked_device_required
+                }
+            })
+            .context("In authorize_create: Trying to get required auth token.")?;
+            Some(
+                hat_and_last_off_body
+                    .ok_or(Error::Km(Ec::KEY_USER_NOT_AUTHENTICATED))
+                    .context("In authorize_create: No suitable auth token found.")?,
+            )
+        } else {
+            None
+        };
+
+        // Now check the validity of the auth token if the key is timeout bound.
+        let hat = match (hat_and_last_off_body, key_time_out) {
+            (Some((hat, last_off_body)), Some(key_time_out)) => {
+                let now = MonotonicRawTime::now();
+                let token_age = now
+                    .checked_sub(&hat.time_received())
+                    .ok_or_else(Error::sys)
+                    .context(concat!(
+                        "In authorize_create: Overflow while computing Auth token validity. ",
+                        "Validity cannot be established."
+                    ))?;
+
+                let on_body_extended = allow_while_on_body && last_off_body < hat.time_received();
+
+                if token_age.seconds() > key_time_out && !on_body_extended {
+                    return Err(Error::Km(Ec::KEY_USER_NOT_AUTHENTICATED))
+                        .context("In authorize_create: matching auth token is expired.");
+                }
+                Some(hat)
+            }
+            (Some((hat, _)), None) => Some(hat),
+            // If timeout_bound is true, above code must have retrieved a HAT or returned with
+            // KEY_USER_NOT_AUTHENTICATED. This arm should not be reachable.
+            (None, Some(_)) => panic!("Logical error."),
+            _ => None,
+        };
+
+        Ok(match (hat, requires_timestamp, per_op_bound) {
+            // Per-op-bound and Some(hat) can only happen if we are both per-op bound and unlocked
+            // device required. In addition, this KM instance needs a timestamp token.
+            // So the HAT cannot be presented on create. So on update/finish we present both
+            // an per-op-bound auth token and a timestamp token.
+            (Some(_), true, true) => (None, DeferredAuthState::TimeStampedOpAuthRequired),
+            (Some(hat), true, false) => (
+                Some(hat.auth_token().clone()),
+                DeferredAuthState::TimeStampRequired(hat.take_auth_token()),
+            ),
+            (Some(hat), false, true) => {
+                (Some(hat.take_auth_token()), DeferredAuthState::OpAuthRequired)
+            }
+            (Some(hat), false, false) => {
+                (Some(hat.take_auth_token()), DeferredAuthState::NoAuthRequired)
+            }
+            (None, _, true) => (None, DeferredAuthState::OpAuthRequired),
+            (None, _, false) => (None, DeferredAuthState::NoAuthRequired),
+        })
+        .map(|(hat, state)| {
+            (hat, AuthInfo { state, key_usage_limited, confirmation_token_receiver })
+        })
+    }
+
+    fn find_auth_token<F>(p: F) -> Result<Option<(AuthTokenEntry, MonotonicRawTime)>>
+    where
+        F: Fn(&AuthTokenEntry) -> bool,
+    {
+        DB.with(|db| {
+            let mut db = db.borrow_mut();
+            db.find_auth_token_entry(p).context("Trying to find auth token.")
+        })
+        .context("In find_auth_token.")
+    }
+
+    /// Checks if the time now since epoch is greater than (or equal, if is_given_time_inclusive is
+    /// set) the given time (in milliseconds)
+    fn is_given_time_passed(given_time: i64, is_given_time_inclusive: bool) -> bool {
+        let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH);
+
+        let time_since_epoch = match duration_since_epoch {
+            Ok(duration) => duration.as_millis(),
+            Err(_) => return false,
+        };
+
+        if is_given_time_inclusive {
+            time_since_epoch >= (given_time as u128)
+        } else {
+            time_since_epoch > (given_time as u128)
+        }
+    }
+
+    /// Check if the device is locked for the given user. If there's no entry yet for the user,
+    /// we assume that the device is locked
+    fn is_device_locked(&self, user_id: i32) -> bool {
+        // unwrap here because there's no way this mutex guard can be poisoned and
+        // because there's no way to recover, even if it is poisoned.
+        let set = self.device_unlocked_set.lock().unwrap();
+        !set.contains(&user_id)
+    }
+
+    /// Sets the device locked status for the user. This method is called externally.
+    pub fn set_device_locked(&self, user_id: i32, device_locked_status: bool) {
+        // unwrap here because there's no way this mutex guard can be poisoned and
+        // because there's no way to recover, even if it is poisoned.
+        let mut set = self.device_unlocked_set.lock().unwrap();
+        if device_locked_status {
+            set.remove(&user_id);
+        } else {
+            set.insert(user_id);
+        }
+    }
+
+    /// Add this auth token to the database.
+    /// Then present the auth token to the op auth map. If an operation is waiting for this
+    /// auth token this fulfills the request and removes the receiver from the map.
+    pub fn add_auth_token(&self, hat: HardwareAuthToken) -> Result<()> {
+        DB.with(|db| db.borrow_mut().insert_auth_token(&hat)).context("In add_auth_token.")?;
+
+        self.op_auth_map.add_auth_token(hat);
+        Ok(())
+    }
+
+    /// This allows adding an entry to the op_auth_map, indexed by the operation challenge.
+    /// This is to be called by create_operation, once it has received the operation challenge
+    /// from keymint for an operation whose authorization decision is OpAuthRequired, as signalled
+    /// by the DeferredAuthState.
+    fn register_op_auth_receiver(&self, challenge: i64, recv: TokenReceiver) {
+        self.op_auth_map.add_receiver(challenge, recv);
+    }
+
+    /// Given the set of key parameters and flags, check if super encryption is required.
+    pub fn super_encryption_required(
+        domain: &Domain,
+        key_parameters: &[KeyParameter],
+        flags: Option<i32>,
+    ) -> SuperEncryptionType {
+        if let Some(flags) = flags {
+            if (flags & KEY_FLAG_AUTH_BOUND_WITHOUT_CRYPTOGRAPHIC_LSKF_BINDING) != 0 {
+                return SuperEncryptionType::None;
+            }
+        }
+        // Each answer has a priority, numerically largest priority wins.
+        struct Candidate {
+            priority: u32,
+            enc_type: SuperEncryptionType,
+        }
+        let mut result = Candidate { priority: 0, enc_type: SuperEncryptionType::None };
+        for kp in key_parameters {
+            let t = match kp.key_parameter_value() {
+                KeyParameterValue::MaxBootLevel(level) => {
+                    Candidate { priority: 3, enc_type: SuperEncryptionType::BootLevel(*level) }
+                }
+                KeyParameterValue::UnlockedDeviceRequired if *domain == Domain::APP => {
+                    Candidate { priority: 2, enc_type: SuperEncryptionType::ScreenLockBound }
+                }
+                KeyParameterValue::UserSecureID(_) if *domain == Domain::APP => {
+                    Candidate { priority: 1, enc_type: SuperEncryptionType::LskfBound }
+                }
+                _ => Candidate { priority: 0, enc_type: SuperEncryptionType::None },
+            };
+            if t.priority > result.priority {
+                result = t;
+            }
+        }
+        result.enc_type
+    }
+
+    /// Finds a matching auth token along with a timestamp token.
+    /// This method looks through auth-tokens cached by keystore which satisfy the given
+    /// authentication information (i.e. |secureUserId|).
+    /// The most recent matching auth token which has a |challenge| field which matches
+    /// the passed-in |challenge| parameter is returned.
+    /// In this case the |authTokenMaxAgeMillis| parameter is not used.
+    ///
+    /// Otherwise, the most recent matching auth token which is younger than |authTokenMaxAgeMillis|
+    /// is returned.
+    pub fn get_auth_tokens(
+        &self,
+        challenge: i64,
+        secure_user_id: i64,
+        auth_token_max_age_millis: i64,
+    ) -> Result<(HardwareAuthToken, TimeStampToken)> {
+        let auth_type = HardwareAuthenticatorType::ANY;
+        let sids: Vec<i64> = vec![secure_user_id];
+        // Filter the matching auth tokens by challenge
+        let result = Self::find_auth_token(|hat: &AuthTokenEntry| {
+            (challenge == hat.challenge()) && hat.satisfies(&sids, auth_type)
+        })
+        .context(
+            "In get_auth_tokens: Failed to get a matching auth token filtered by challenge.",
+        )?;
+
+        let auth_token = if let Some((auth_token_entry, _)) = result {
+            auth_token_entry.take_auth_token()
+        } else {
+            // Filter the matching auth tokens by age.
+            if auth_token_max_age_millis != 0 {
+                let now_in_millis = MonotonicRawTime::now().milli_seconds();
+                let result = Self::find_auth_token(|auth_token_entry: &AuthTokenEntry| {
+                    let token_valid = now_in_millis
+                        .checked_sub(auth_token_entry.time_received().milli_seconds())
+                        .map_or(false, |token_age_in_millis| {
+                            auth_token_max_age_millis > token_age_in_millis
+                        });
+                    token_valid && auth_token_entry.satisfies(&sids, auth_type)
+                })
+                .context(
+                    "In get_auth_tokens: Failed to get a matching auth token filtered by age.",
+                )?;
+
+                if let Some((auth_token_entry, _)) = result {
+                    auth_token_entry.take_auth_token()
+                } else {
+                    return Err(AuthzError::Rc(AuthzResponseCode::NO_AUTH_TOKEN_FOUND))
+                        .context("In get_auth_tokens: No auth token found.");
+                }
+            } else {
+                return Err(AuthzError::Rc(AuthzResponseCode::NO_AUTH_TOKEN_FOUND))
+                    .context("In get_auth_tokens: Passed-in auth token max age is zero.");
+            }
+        };
+        // Wait and obtain the timestamp token from secure clock service.
+        let tst = get_timestamp_token(challenge)
+            .context("In get_auth_tokens. Error in getting timestamp token.")?;
+        Ok((auth_token, tst))
+    }
+}
+
+// TODO: Add tests to enforcement module (b/175578618).
diff --git a/keystore2/src/entropy.rs b/keystore2/src/entropy.rs
new file mode 100644
index 0000000..de38187
--- /dev/null
+++ b/keystore2/src/entropy.rs
@@ -0,0 +1,98 @@
+// Copyright 2021, 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.
+
+//! This module holds functionality for retrieving and distributing entropy.
+
+use anyhow::{Context, Result};
+use log::error;
+use std::time::{Duration, Instant};
+
+static ENTROPY_SIZE: usize = 64;
+static MIN_FEED_INTERVAL_SECS: u64 = 30;
+
+#[derive(Default)]
+struct FeederInfo {
+    last_feed: Option<Instant>,
+}
+
+/// Register the entropy feeder as an idle callback.
+pub fn register_feeder() {
+    crate::globals::ASYNC_TASK.add_idle(|shelf| {
+        let mut info = shelf.get_mut::<FeederInfo>();
+        let now = Instant::now();
+        let feed_needed = match info.last_feed {
+            None => true,
+            Some(last) => now.duration_since(last) > Duration::from_secs(MIN_FEED_INTERVAL_SECS),
+        };
+        if feed_needed {
+            info.last_feed = Some(now);
+            feed_devices();
+        }
+    });
+}
+
+fn get_entropy(size: usize) -> Result<Vec<u8>> {
+    keystore2_crypto::generate_random_data(size).context("Retrieving entropy for KeyMint device")
+}
+
+/// Feed entropy to all known KeyMint devices.
+pub fn feed_devices() {
+    let km_devs = crate::globals::get_keymint_devices();
+    if km_devs.is_empty() {
+        return;
+    }
+    let data = match get_entropy(km_devs.len() * ENTROPY_SIZE) {
+        Ok(data) => data,
+        Err(e) => {
+            error!(
+                "Failed to retrieve {}*{} bytes of entropy: {:?}",
+                km_devs.len(),
+                ENTROPY_SIZE,
+                e
+            );
+            return;
+        }
+    };
+    for (i, km_dev) in km_devs.iter().enumerate() {
+        let offset = i * ENTROPY_SIZE;
+        let sub_data = &data[offset..(offset + ENTROPY_SIZE)];
+        if let Err(e) = km_dev.addRngEntropy(sub_data) {
+            error!("Failed to feed entropy to KeyMint device: {:?}", e);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::collections::HashSet;
+
+    #[test]
+    fn test_entropy_size() {
+        for size in &[0, 1, 4, 8, 256, 4096] {
+            let data = get_entropy(*size).expect("failed to get entropy");
+            assert_eq!(data.len(), *size);
+        }
+    }
+    #[test]
+    fn test_entropy_uniqueness() {
+        let count = 10;
+        let mut seen = HashSet::new();
+        for _i in 0..count {
+            let data = get_entropy(16).expect("failed to get entropy");
+            seen.insert(data);
+        }
+        assert_eq!(seen.len(), count);
+    }
+}
diff --git a/keystore2/src/error.rs b/keystore2/src/error.rs
new file mode 100644
index 0000000..f969cb6
--- /dev/null
+++ b/keystore2/src/error.rs
@@ -0,0 +1,399 @@
+// Copyright 2020, 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.
+
+//! Keystore error provides convenience methods and types for Keystore error handling.
+//! Clients of Keystore expect one of two error codes, i.e., a Keystore ResponseCode as
+//! defined by the Keystore AIDL interface, or a Keymint ErrorCode as defined by
+//! the Keymint HAL specification.
+//! This crate provides `Error` which can wrap both. It is to be used
+//! internally by Keystore to diagnose error conditions that need to be reported to
+//! the client. To report the error condition to the client the Keystore AIDL
+//! interface defines a wire type `Result` which is distinctly different from Rust's
+//! `enum Result<T,E>`.
+//!
+//! This crate provides the convenience method `map_or_log_err` to convert `anyhow::Error`
+//! into this wire type. In addition to handling the conversion of `Error`
+//! to the `Result` wire type it handles any other error by mapping it to
+//! `ResponseCode::SYSTEM_ERROR` and logs any error condition.
+//!
+//! Keystore functions should use `anyhow::Result` to return error conditions, and
+//! context should be added every time an error is forwarded.
+
+pub use android_hardware_security_keymint::aidl::android::hardware::security::keymint::ErrorCode::ErrorCode;
+pub use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
+use android_system_keystore2::binder::{
+    ExceptionCode, Result as BinderResult, Status as BinderStatus, StatusCode,
+};
+use keystore2_selinux as selinux;
+use std::cmp::PartialEq;
+
+/// This is the main Keystore error type. It wraps the Keystore `ResponseCode` generated
+/// from AIDL in the `Rc` variant and Keymint `ErrorCode` in the Km variant.
+#[derive(Debug, thiserror::Error, PartialEq)]
+pub enum Error {
+    /// Wraps a Keystore `ResponseCode` as defined by the Keystore AIDL interface specification.
+    #[error("Error::Rc({0:?})")]
+    Rc(ResponseCode),
+    /// Wraps a Keymint `ErrorCode` as defined by the Keymint AIDL interface specification.
+    #[error("Error::Km({0:?})")]
+    Km(ErrorCode),
+    /// Wraps a Binder exception code other than a service specific exception.
+    #[error("Binder exception code {0:?}, {1:?}")]
+    Binder(ExceptionCode, i32),
+    /// Wraps a Binder status code.
+    #[error("Binder transaction error {0:?}")]
+    BinderTransaction(StatusCode),
+    /// Wraps a Remote Provisioning ErrorCode as defined by the IRemotelyProvisionedComponent
+    /// AIDL interface spec.
+    #[error("Error::Rp({0:?})")]
+    Rp(ErrorCode),
+}
+
+impl Error {
+    /// Short hand for `Error::Rc(ResponseCode::SYSTEM_ERROR)`
+    pub fn sys() -> Self {
+        Error::Rc(ResponseCode::SYSTEM_ERROR)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::PERMISSION_DENIED`
+    pub fn perm() -> Self {
+        Error::Rc(ResponseCode::PERMISSION_DENIED)
+    }
+}
+
+/// Helper function to map the binder status we get from calls into KeyMint
+/// to a Keystore Error. We don't create an anyhow error here to make
+/// it easier to evaluate KeyMint errors, which we must do in some cases, e.g.,
+/// when diagnosing authentication requirements, update requirements, and running
+/// out of operation slots.
+pub fn map_km_error<T>(r: BinderResult<T>) -> Result<T, Error> {
+    r.map_err(|s| {
+        match s.exception_code() {
+            ExceptionCode::SERVICE_SPECIFIC => {
+                let se = s.service_specific_error();
+                if se < 0 {
+                    // Negative service specific errors are KM error codes.
+                    Error::Km(ErrorCode(s.service_specific_error()))
+                } else {
+                    // Non negative error codes cannot be KM error codes.
+                    // So we create an `Error::Binder` variant to preserve
+                    // the service specific error code for logging.
+                    // `map_or_log_err` will map this on a system error,
+                    // but not before logging the details to logcat.
+                    Error::Binder(ExceptionCode::SERVICE_SPECIFIC, se)
+                }
+            }
+            // We create `Error::Binder` to preserve the exception code
+            // for logging.
+            // `map_or_log_err` will map this on a system error.
+            e_code => Error::Binder(e_code, 0),
+        }
+    })
+}
+
+/// Helper function to map the binder status we get from calls into a RemotelyProvisionedComponent
+/// to a Keystore Error. We don't create an anyhow error here to make
+/// it easier to evaluate service specific errors.
+pub fn map_rem_prov_error<T>(r: BinderResult<T>) -> Result<T, Error> {
+    r.map_err(|s| match s.exception_code() {
+        ExceptionCode::SERVICE_SPECIFIC => Error::Rp(ErrorCode(s.service_specific_error())),
+        e_code => Error::Binder(e_code, 0),
+    })
+}
+
+/// This function is similar to map_km_error only that we don't expect
+/// any KeyMint error codes, we simply preserve the exception code and optional
+/// service specific exception.
+pub fn map_binder_status<T>(r: BinderResult<T>) -> Result<T, Error> {
+    r.map_err(|s| match s.exception_code() {
+        ExceptionCode::SERVICE_SPECIFIC => {
+            let se = s.service_specific_error();
+            Error::Binder(ExceptionCode::SERVICE_SPECIFIC, se)
+        }
+        ExceptionCode::TRANSACTION_FAILED => {
+            let e = s.transaction_error();
+            Error::BinderTransaction(e)
+        }
+        e_code => Error::Binder(e_code, 0),
+    })
+}
+
+/// This function maps a status code onto a Keystore Error.
+pub fn map_binder_status_code<T>(r: Result<T, StatusCode>) -> Result<T, Error> {
+    r.map_err(Error::BinderTransaction)
+}
+
+/// This function should be used by Keystore service calls to translate error conditions
+/// into service specific exceptions.
+///
+/// All error conditions get logged by this function, except for KEY_NOT_FOUND error.
+///
+/// All `Error::Rc(x)` and `Error::Km(x)` variants get mapped onto a service specific error
+/// code of x. This is possible because KeyMint `ErrorCode` errors are always negative and
+/// `ResponseCode` codes are always positive.
+/// `selinux::Error::PermissionDenied` is mapped on `ResponseCode::PERMISSION_DENIED`.
+///
+/// All non `Error` error conditions and the Error::Binder variant get mapped onto
+/// ResponseCode::SYSTEM_ERROR`.
+///
+/// `handle_ok` will be called if `result` is `Ok(value)` where `value` will be passed
+/// as argument to `handle_ok`. `handle_ok` must generate a `BinderResult<T>`, but it
+/// typically returns Ok(value).
+///
+/// # Examples
+///
+/// ```
+/// fn loadKey() -> anyhow::Result<Vec<u8>> {
+///     if (good_but_auth_required) {
+///         Ok(vec!['k', 'e', 'y'])
+///     } else {
+///         Err(anyhow!(Error::Rc(ResponseCode::KEY_NOT_FOUND)))
+///     }
+/// }
+///
+/// map_or_log_err(loadKey(), Ok)
+/// ```
+pub fn map_or_log_err<T, U, F>(result: anyhow::Result<U>, handle_ok: F) -> BinderResult<T>
+where
+    F: FnOnce(U) -> BinderResult<T>,
+{
+    map_err_with(
+        result,
+        |e| {
+            // Make the key not found errors silent.
+            if !matches!(
+                e.root_cause().downcast_ref::<Error>(),
+                Some(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+            ) {
+                log::error!("{:?}", e);
+            }
+            e
+        },
+        handle_ok,
+    )
+}
+
+/// This function behaves similar to map_or_log_error, but it does not log the errors, instead
+/// it calls map_err on the error before mapping it to a binder result allowing callers to
+/// log or transform the error before mapping it.
+pub fn map_err_with<T, U, F1, F2>(
+    result: anyhow::Result<U>,
+    map_err: F1,
+    handle_ok: F2,
+) -> BinderResult<T>
+where
+    F1: FnOnce(anyhow::Error) -> anyhow::Error,
+    F2: FnOnce(U) -> BinderResult<T>,
+{
+    result.map_or_else(
+        |e| {
+            let e = map_err(e);
+            let rc = get_error_code(&e);
+            Err(BinderStatus::new_service_specific_error(rc, None))
+        },
+        handle_ok,
+    )
+}
+
+/// Returns the error code given a reference to the error
+pub fn get_error_code(e: &anyhow::Error) -> i32 {
+    let root_cause = e.root_cause();
+    match root_cause.downcast_ref::<Error>() {
+        Some(Error::Rc(rcode)) => rcode.0,
+        Some(Error::Km(ec)) => ec.0,
+        Some(Error::Rp(_)) => ResponseCode::SYSTEM_ERROR.0,
+        // If an Error::Binder reaches this stage we report a system error.
+        // The exception code and possible service specific error will be
+        // printed in the error log above.
+        Some(Error::Binder(_, _)) | Some(Error::BinderTransaction(_)) => {
+            ResponseCode::SYSTEM_ERROR.0
+        }
+        None => match root_cause.downcast_ref::<selinux::Error>() {
+            Some(selinux::Error::PermissionDenied) => ResponseCode::PERMISSION_DENIED.0,
+            _ => ResponseCode::SYSTEM_ERROR.0,
+        },
+    }
+}
+
+#[cfg(test)]
+pub mod tests {
+
+    use super::*;
+    use android_system_keystore2::binder::{
+        ExceptionCode, Result as BinderResult, Status as BinderStatus,
+    };
+    use anyhow::{anyhow, Context};
+
+    fn nested_nested_rc(rc: ResponseCode) -> anyhow::Result<()> {
+        Err(anyhow!(Error::Rc(rc))).context("nested nested rc")
+    }
+
+    fn nested_rc(rc: ResponseCode) -> anyhow::Result<()> {
+        nested_nested_rc(rc).context("nested rc")
+    }
+
+    fn nested_nested_ec(ec: ErrorCode) -> anyhow::Result<()> {
+        Err(anyhow!(Error::Km(ec))).context("nested nested ec")
+    }
+
+    fn nested_ec(ec: ErrorCode) -> anyhow::Result<()> {
+        nested_nested_ec(ec).context("nested ec")
+    }
+
+    fn nested_nested_ok(rc: ResponseCode) -> anyhow::Result<ResponseCode> {
+        Ok(rc)
+    }
+
+    fn nested_ok(rc: ResponseCode) -> anyhow::Result<ResponseCode> {
+        nested_nested_ok(rc).context("nested ok")
+    }
+
+    fn nested_nested_selinux_perm() -> anyhow::Result<()> {
+        Err(anyhow!(selinux::Error::perm())).context("nested nexted selinux permission denied")
+    }
+
+    fn nested_selinux_perm() -> anyhow::Result<()> {
+        nested_nested_selinux_perm().context("nested selinux permission denied")
+    }
+
+    #[derive(Debug, thiserror::Error)]
+    enum TestError {
+        #[error("TestError::Fail")]
+        Fail = 0,
+    }
+
+    fn nested_nested_other_error() -> anyhow::Result<()> {
+        Err(anyhow!(TestError::Fail)).context("nested nested other error")
+    }
+
+    fn nested_other_error() -> anyhow::Result<()> {
+        nested_nested_other_error().context("nested other error")
+    }
+
+    fn binder_sse_error(sse: i32) -> BinderResult<()> {
+        Err(BinderStatus::new_service_specific_error(sse, None))
+    }
+
+    fn binder_exception(ex: ExceptionCode) -> BinderResult<()> {
+        Err(BinderStatus::new_exception(ex, None))
+    }
+
+    #[test]
+    fn keystore_error_test() -> anyhow::Result<(), String> {
+        android_logger::init_once(
+            android_logger::Config::default()
+                .with_tag("keystore_error_tests")
+                .with_min_level(log::Level::Debug),
+        );
+        // All Error::Rc(x) get mapped on a service specific error
+        // code of x.
+        for rc in ResponseCode::LOCKED.0..ResponseCode::BACKEND_BUSY.0 {
+            assert_eq!(
+                Result::<(), i32>::Err(rc),
+                map_or_log_err(nested_rc(ResponseCode(rc)), |_| Err(BinderStatus::ok()))
+                    .map_err(|s| s.service_specific_error())
+            );
+        }
+
+        // All Keystore Error::Km(x) get mapped on a service
+        // specific error of x.
+        for ec in ErrorCode::UNKNOWN_ERROR.0..ErrorCode::ROOT_OF_TRUST_ALREADY_SET.0 {
+            assert_eq!(
+                Result::<(), i32>::Err(ec),
+                map_or_log_err(nested_ec(ErrorCode(ec)), |_| Err(BinderStatus::ok()))
+                    .map_err(|s| s.service_specific_error())
+            );
+        }
+
+        // All Keymint errors x received through a Binder Result get mapped on
+        // a service specific error of x.
+        for ec in ErrorCode::UNKNOWN_ERROR.0..ErrorCode::ROOT_OF_TRUST_ALREADY_SET.0 {
+            assert_eq!(
+                Result::<(), i32>::Err(ec),
+                map_or_log_err(
+                    map_km_error(binder_sse_error(ec))
+                        .with_context(|| format!("Km error code: {}.", ec)),
+                    |_| Err(BinderStatus::ok())
+                )
+                .map_err(|s| s.service_specific_error())
+            );
+        }
+
+        // map_km_error creates an Error::Binder variant storing
+        // ExceptionCode::SERVICE_SPECIFIC and the given
+        // service specific error.
+        let sse = map_km_error(binder_sse_error(1));
+        assert_eq!(Err(Error::Binder(ExceptionCode::SERVICE_SPECIFIC, 1)), sse);
+        // map_or_log_err then maps it on a service specific error of ResponseCode::SYSTEM_ERROR.
+        assert_eq!(
+            Result::<(), ResponseCode>::Err(ResponseCode::SYSTEM_ERROR),
+            map_or_log_err(sse.context("Non negative service specific error."), |_| Err(
+                BinderStatus::ok()
+            ))
+            .map_err(|s| ResponseCode(s.service_specific_error()))
+        );
+
+        // map_km_error creates a Error::Binder variant storing the given exception code.
+        let binder_exception = map_km_error(binder_exception(ExceptionCode::TRANSACTION_FAILED));
+        assert_eq!(Err(Error::Binder(ExceptionCode::TRANSACTION_FAILED, 0)), binder_exception);
+        // map_or_log_err then maps it on a service specific error of ResponseCode::SYSTEM_ERROR.
+        assert_eq!(
+            Result::<(), ResponseCode>::Err(ResponseCode::SYSTEM_ERROR),
+            map_or_log_err(binder_exception.context("Binder Exception."), |_| Err(
+                BinderStatus::ok()
+            ))
+            .map_err(|s| ResponseCode(s.service_specific_error()))
+        );
+
+        // selinux::Error::Perm() needs to be mapped to ResponseCode::PERMISSION_DENIED
+        assert_eq!(
+            Result::<(), ResponseCode>::Err(ResponseCode::PERMISSION_DENIED),
+            map_or_log_err(nested_selinux_perm(), |_| Err(BinderStatus::ok()))
+                .map_err(|s| ResponseCode(s.service_specific_error()))
+        );
+
+        // All other errors get mapped on System Error.
+        assert_eq!(
+            Result::<(), ResponseCode>::Err(ResponseCode::SYSTEM_ERROR),
+            map_or_log_err(nested_other_error(), |_| Err(BinderStatus::ok()))
+                .map_err(|s| ResponseCode(s.service_specific_error()))
+        );
+
+        // Result::Ok variants get passed to the ok handler.
+        assert_eq!(Ok(ResponseCode::LOCKED), map_or_log_err(nested_ok(ResponseCode::LOCKED), Ok));
+        assert_eq!(
+            Ok(ResponseCode::SYSTEM_ERROR),
+            map_or_log_err(nested_ok(ResponseCode::SYSTEM_ERROR), Ok)
+        );
+
+        Ok(())
+    }
+
+    //Helper function to test whether error cases are handled as expected.
+    pub fn check_result_contains_error_string<T>(
+        result: anyhow::Result<T>,
+        expected_error_string: &str,
+    ) {
+        let error_str = format!(
+            "{:#?}",
+            result.err().unwrap_or_else(|| panic!("Expected the error: {}", expected_error_string))
+        );
+        assert!(
+            error_str.contains(expected_error_string),
+            "The string \"{}\" should contain \"{}\"",
+            error_str,
+            expected_error_string
+        );
+    }
+} // mod tests
diff --git a/keystore2/src/gc.rs b/keystore2/src/gc.rs
new file mode 100644
index 0000000..2010c79
--- /dev/null
+++ b/keystore2/src/gc.rs
@@ -0,0 +1,152 @@
+// Copyright 2020, 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.
+
+//! This module implements the key garbage collector.
+//! The key garbage collector has one public function `notify_gc()`. This will create
+//! a thread on demand which will query the database for unreferenced key entries,
+//! optionally dispose of sensitive key material appropriately, and then delete
+//! the key entry from the database.
+
+use crate::{
+    async_task,
+    database::{BlobMetaData, KeystoreDB, Uuid},
+    super_key::SuperKeyManager,
+};
+use anyhow::{Context, Result};
+use async_task::AsyncTask;
+use std::sync::{
+    atomic::{AtomicU8, Ordering},
+    Arc,
+};
+
+pub struct Gc {
+    async_task: Arc<AsyncTask>,
+    notified: Arc<AtomicU8>,
+}
+
+impl Gc {
+    /// Creates a garbage collector using the given async_task.
+    /// The garbage collector needs a function to invalidate key blobs, a database connection,
+    /// and a reference to the `SuperKeyManager`. They are obtained from the init function.
+    /// The function is only called if this is first time a garbage collector was initialized
+    /// with the given AsyncTask instance.
+    /// Note: It is a logical error to initialize different Gc instances with the same `AsyncTask`.
+    pub fn new_init_with<F>(async_task: Arc<AsyncTask>, init: F) -> Self
+    where
+        F: FnOnce() -> (
+                Box<dyn Fn(&Uuid, &[u8]) -> Result<()> + Send + 'static>,
+                KeystoreDB,
+                Arc<SuperKeyManager>,
+            ) + Send
+            + 'static,
+    {
+        let weak_at = Arc::downgrade(&async_task);
+        let notified = Arc::new(AtomicU8::new(0));
+        let notified_clone = notified.clone();
+        // Initialize the task's shelf.
+        async_task.queue_hi(move |shelf| {
+            let (invalidate_key, db, super_key) = init();
+            let notified = notified_clone;
+            shelf.get_or_put_with(|| GcInternal {
+                deleted_blob_ids: vec![],
+                superseded_blobs: vec![],
+                invalidate_key,
+                db,
+                async_task: weak_at,
+                super_key,
+                notified,
+            });
+        });
+        Self { async_task, notified }
+    }
+
+    /// Notifies the key garbage collector to iterate through orphaned and superseded blobs and
+    /// attempts their deletion. We only process one key at a time and then schedule another
+    /// attempt by queueing it in the async_task (low priority) queue.
+    pub fn notify_gc(&self) {
+        if let Ok(0) = self.notified.compare_exchange(0, 1, Ordering::Relaxed, Ordering::Relaxed) {
+            self.async_task.queue_lo(|shelf| shelf.get_downcast_mut::<GcInternal>().unwrap().step())
+        }
+    }
+}
+
+struct GcInternal {
+    deleted_blob_ids: Vec<i64>,
+    superseded_blobs: Vec<(i64, Vec<u8>, BlobMetaData)>,
+    invalidate_key: Box<dyn Fn(&Uuid, &[u8]) -> Result<()> + Send + 'static>,
+    db: KeystoreDB,
+    async_task: std::sync::Weak<AsyncTask>,
+    super_key: Arc<SuperKeyManager>,
+    notified: Arc<AtomicU8>,
+}
+
+impl GcInternal {
+    /// Attempts to process one blob from the database.
+    /// We process one key at a time, because deleting a key is a time consuming process which
+    /// may involve calling into the KeyMint backend and we don't want to hog neither the backend
+    /// nor the database for extended periods of time.
+    /// To limit the number of database transactions, which are also expensive and competing
+    /// with threads on the critical path, deleted blobs are loaded in batches.
+    fn process_one_key(&mut self) -> Result<()> {
+        if self.superseded_blobs.is_empty() {
+            let blobs = self
+                .db
+                .handle_next_superseded_blobs(&self.deleted_blob_ids, 20)
+                .context("In process_one_key: Trying to handle superseded blob.")?;
+            self.deleted_blob_ids = vec![];
+            self.superseded_blobs = blobs;
+        }
+
+        if let Some((blob_id, blob, blob_metadata)) = self.superseded_blobs.pop() {
+            // Add the next blob_id to the deleted blob ids list. So it will be
+            // removed from the database regardless of whether the following
+            // succeeds or not.
+            self.deleted_blob_ids.push(blob_id);
+
+            // If the key has a km_uuid we try to get the corresponding device
+            // and delete the key, unwrapping if necessary and possible.
+            // (At this time keys may get deleted without having the super encryption
+            // key in this case we can only delete the key from the database.)
+            if let Some(uuid) = blob_metadata.km_uuid() {
+                let blob = self
+                    .super_key
+                    .unwrap_key_if_required(&blob_metadata, &blob)
+                    .context("In process_one_key: Trying to unwrap to-be-deleted blob.")?;
+                (self.invalidate_key)(&uuid, &*blob)
+                    .context("In process_one_key: Trying to invalidate key.")?;
+            }
+        }
+        Ok(())
+    }
+
+    /// Processes one key and then schedules another attempt until it runs out of blobs to delete.
+    fn step(&mut self) {
+        self.notified.store(0, Ordering::Relaxed);
+        if let Err(e) = self.process_one_key() {
+            log::error!("Error trying to delete blob entry. {:?}", e);
+        }
+        // Schedule the next step. This gives high priority requests a chance to interleave.
+        if !self.deleted_blob_ids.is_empty() {
+            if let Some(at) = self.async_task.upgrade() {
+                if let Ok(0) =
+                    self.notified.compare_exchange(0, 1, Ordering::Relaxed, Ordering::Relaxed)
+                {
+                    at.queue_lo(move |shelf| {
+                        shelf.get_downcast_mut::<GcInternal>().unwrap().step()
+                    });
+                }
+            }
+        }
+    }
+}
diff --git a/keystore2/src/globals.rs b/keystore2/src/globals.rs
new file mode 100644
index 0000000..c492120
--- /dev/null
+++ b/keystore2/src/globals.rs
@@ -0,0 +1,379 @@
+// Copyright 2020, 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.
+
+//! This module holds global state of Keystore such as the thread local
+//! database connections and connections to services that Keystore needs
+//! to talk to.
+
+use crate::gc::Gc;
+use crate::legacy_blob::LegacyBlobLoader;
+use crate::legacy_migrator::LegacyMigrator;
+use crate::super_key::SuperKeyManager;
+use crate::utils::watchdog as wd;
+use crate::utils::Asp;
+use crate::{async_task::AsyncTask, database::MonotonicRawTime};
+use crate::{
+    database::KeystoreDB,
+    database::Uuid,
+    error::{map_binder_status, map_binder_status_code, Error, ErrorCode},
+};
+use crate::{enforcements::Enforcements, error::map_km_error};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    IKeyMintDevice::IKeyMintDevice, IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
+    KeyMintHardwareInfo::KeyMintHardwareInfo, SecurityLevel::SecurityLevel,
+};
+use android_hardware_security_keymint::binder::{StatusCode, Strong};
+use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
+use anyhow::{Context, Result};
+use binder::FromIBinder;
+use keystore2_vintf::get_aidl_instances;
+use lazy_static::lazy_static;
+use std::sync::{Arc, Mutex};
+use std::{cell::RefCell, sync::Once};
+use std::{collections::HashMap, path::Path, path::PathBuf};
+
+static DB_INIT: Once = Once::new();
+
+/// Open a connection to the Keystore 2.0 database. This is called during the initialization of
+/// the thread local DB field. It should never be called directly. The first time this is called
+/// we also call KeystoreDB::cleanup_leftovers to restore the key lifecycle invariant. See the
+/// documentation of cleanup_leftovers for more details. The function also constructs a blob
+/// garbage collector. The initializing closure constructs another database connection without
+/// a gc. Although one GC is created for each thread local database connection, this closure
+/// is run only once, as long as the ASYNC_TASK instance is the same. So only one additional
+/// database connection is created for the garbage collector worker.
+pub fn create_thread_local_db() -> KeystoreDB {
+    let mut db = KeystoreDB::new(
+        &DB_PATH.lock().expect("Could not get the database directory."),
+        Some(GC.clone()),
+    )
+    .expect("Failed to open database.");
+    DB_INIT.call_once(|| {
+        log::info!("Touching Keystore 2.0 database for this first time since boot.");
+        db.insert_last_off_body(MonotonicRawTime::now())
+            .expect("Could not initialize database with last off body.");
+        log::info!("Calling cleanup leftovers.");
+        let n = db.cleanup_leftovers().expect("Failed to cleanup database on startup.");
+        if n != 0 {
+            log::info!(
+                concat!(
+                    "Cleaned up {} failed entries. ",
+                    "This indicates keystore crashed during key generation."
+                ),
+                n
+            );
+        }
+    });
+    db
+}
+
+thread_local! {
+    /// Database connections are not thread safe, but connecting to the
+    /// same database multiple times is safe as long as each connection is
+    /// used by only one thread. So we store one database connection per
+    /// thread in this thread local key.
+    pub static DB: RefCell<KeystoreDB> =
+            RefCell::new(create_thread_local_db());
+}
+
+#[derive(Default)]
+struct DevicesMap {
+    devices_by_uuid: HashMap<Uuid, (Asp, KeyMintHardwareInfo)>,
+    uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
+}
+
+impl DevicesMap {
+    fn dev_by_sec_level(
+        &self,
+        sec_level: &SecurityLevel,
+    ) -> Option<(Asp, KeyMintHardwareInfo, Uuid)> {
+        self.uuid_by_sec_level.get(sec_level).and_then(|uuid| self.dev_by_uuid(uuid))
+    }
+
+    fn dev_by_uuid(&self, uuid: &Uuid) -> Option<(Asp, KeyMintHardwareInfo, Uuid)> {
+        self.devices_by_uuid
+            .get(uuid)
+            .map(|(dev, hw_info)| ((*dev).clone(), (*hw_info).clone(), *uuid))
+    }
+
+    fn devices<T: FromIBinder + ?Sized>(&self) -> Vec<Strong<T>> {
+        self.devices_by_uuid.values().filter_map(|(asp, _)| asp.get_interface::<T>().ok()).collect()
+    }
+
+    /// The requested security level and the security level of the actual implementation may
+    /// differ. So we map the requested security level to the uuid of the implementation
+    /// so that there cannot be any confusion as to which KeyMint instance is requested.
+    fn insert(&mut self, sec_level: SecurityLevel, dev: Asp, hw_info: KeyMintHardwareInfo) {
+        // For now we use the reported security level of the KM instance as UUID.
+        // TODO update this section once UUID was added to the KM hardware info.
+        let uuid: Uuid = sec_level.into();
+        self.devices_by_uuid.insert(uuid, (dev, hw_info));
+        self.uuid_by_sec_level.insert(sec_level, uuid);
+    }
+}
+
+#[derive(Default)]
+struct RemotelyProvisionedDevicesMap {
+    devices_by_sec_level: HashMap<SecurityLevel, Asp>,
+}
+
+impl RemotelyProvisionedDevicesMap {
+    fn dev_by_sec_level(&self, sec_level: &SecurityLevel) -> Option<Asp> {
+        self.devices_by_sec_level.get(sec_level).map(|dev| (*dev).clone())
+    }
+
+    fn insert(&mut self, sec_level: SecurityLevel, dev: Asp) {
+        self.devices_by_sec_level.insert(sec_level, dev);
+    }
+}
+
+lazy_static! {
+    /// The path where keystore stores all its keys.
+    pub static ref DB_PATH: Mutex<PathBuf> = Mutex::new(
+        Path::new("/data/misc/keystore").to_path_buf());
+    /// Runtime database of unwrapped super keys.
+    pub static ref SUPER_KEY: Arc<SuperKeyManager> = Default::default();
+    /// Map of KeyMint devices.
+    static ref KEY_MINT_DEVICES: Mutex<DevicesMap> = Default::default();
+    /// Timestamp service.
+    static ref TIME_STAMP_DEVICE: Mutex<Option<Asp>> = Default::default();
+    /// RemotelyProvisionedComponent HAL devices.
+    static ref REMOTELY_PROVISIONED_COMPONENT_DEVICES: Mutex<RemotelyProvisionedDevicesMap> = Default::default();
+    /// A single on-demand worker thread that handles deferred tasks with two different
+    /// priorities.
+    pub static ref ASYNC_TASK: Arc<AsyncTask> = Default::default();
+    /// Singleton for enforcements.
+    pub static ref ENFORCEMENTS: Enforcements = Default::default();
+    /// LegacyBlobLoader is initialized and exists globally.
+    /// The same directory used by the database is used by the LegacyBlobLoader as well.
+    pub static ref LEGACY_BLOB_LOADER: Arc<LegacyBlobLoader> = Arc::new(LegacyBlobLoader::new(
+        &DB_PATH.lock().expect("Could not get the database path for legacy blob loader.")));
+    /// Legacy migrator. Atomically migrates legacy blobs to the database.
+    pub static ref LEGACY_MIGRATOR: Arc<LegacyMigrator> =
+        Arc::new(LegacyMigrator::new(Arc::new(Default::default())));
+    /// Background thread which handles logging via statsd and logd
+    pub static ref LOGS_HANDLER: Arc<AsyncTask> = Default::default();
+
+    static ref GC: Arc<Gc> = Arc::new(Gc::new_init_with(ASYNC_TASK.clone(), || {
+        (
+            Box::new(|uuid, blob| {
+                let km_dev: Strong<dyn IKeyMintDevice> =
+                    get_keymint_dev_by_uuid(uuid).map(|(dev, _)| dev)?.get_interface()?;
+                let _wp = wd::watch_millis("In invalidate key closure: calling deleteKey", 500);
+                map_km_error(km_dev.deleteKey(&*blob))
+                    .context("In invalidate key closure: Trying to invalidate key blob.")
+            }),
+            KeystoreDB::new(&DB_PATH.lock().expect("Could not get the database directory."), None)
+                .expect("Failed to open database."),
+            SUPER_KEY.clone(),
+        )
+    }));
+}
+
+static KEYMINT_SERVICE_NAME: &str = "android.hardware.security.keymint.IKeyMintDevice";
+
+/// Make a new connection to a KeyMint device of the given security level.
+/// If no native KeyMint device can be found this function also brings
+/// up the compatibility service and attempts to connect to the legacy wrapper.
+fn connect_keymint(security_level: &SecurityLevel) -> Result<(Asp, KeyMintHardwareInfo)> {
+    let keymint_instances =
+        get_aidl_instances("android.hardware.security.keymint", 1, "IKeyMintDevice");
+
+    let service_name = match *security_level {
+        SecurityLevel::TRUSTED_ENVIRONMENT => {
+            if keymint_instances.as_vec()?.iter().any(|instance| *instance == "default") {
+                Some(format!("{}/default", KEYMINT_SERVICE_NAME))
+            } else {
+                None
+            }
+        }
+        SecurityLevel::STRONGBOX => {
+            if keymint_instances.as_vec()?.iter().any(|instance| *instance == "strongbox") {
+                Some(format!("{}/strongbox", KEYMINT_SERVICE_NAME))
+            } else {
+                None
+            }
+        }
+        _ => {
+            return Err(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
+                .context("In connect_keymint.")
+        }
+    };
+
+    let keymint = if let Some(service_name) = service_name {
+        map_binder_status_code(binder::get_interface(&service_name))
+            .context("In connect_keymint: Trying to connect to genuine KeyMint service.")
+    } else {
+        // This is a no-op if it was called before.
+        keystore2_km_compat::add_keymint_device_service();
+
+        let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
+            map_binder_status_code(binder::get_interface("android.security.compat"))
+                .context("In connect_keymint: Trying to connect to compat service.")?;
+        map_binder_status(keystore_compat_service.getKeyMintDevice(*security_level))
+            .map_err(|e| match e {
+                Error::BinderTransaction(StatusCode::NAME_NOT_FOUND) => {
+                    Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)
+                }
+                e => e,
+            })
+            .context("In connect_keymint: Trying to get Legacy wrapper.")
+    }?;
+
+    let wp = wd::watch_millis("In connect_keymint: calling getHardwareInfo()", 500);
+    let hw_info = map_km_error(keymint.getHardwareInfo())
+        .context("In connect_keymint: Failed to get hardware info.")?;
+    drop(wp);
+
+    Ok((Asp::new(keymint.as_binder()), hw_info))
+}
+
+/// Get a keymint device for the given security level either from our cache or
+/// by making a new connection. Returns the device, the hardware info and the uuid.
+/// TODO the latter can be removed when the uuid is part of the hardware info.
+pub fn get_keymint_device(
+    security_level: &SecurityLevel,
+) -> Result<(Asp, KeyMintHardwareInfo, Uuid)> {
+    let mut devices_map = KEY_MINT_DEVICES.lock().unwrap();
+    if let Some((dev, hw_info, uuid)) = devices_map.dev_by_sec_level(&security_level) {
+        Ok((dev, hw_info, uuid))
+    } else {
+        let (dev, hw_info) = connect_keymint(security_level).context("In get_keymint_device.")?;
+        devices_map.insert(*security_level, dev, hw_info);
+        // Unwrap must succeed because we just inserted it.
+        Ok(devices_map.dev_by_sec_level(security_level).unwrap())
+    }
+}
+
+/// Get a keymint device for the given uuid. This will only access the cache, but will not
+/// attempt to establish a new connection. It is assumed that the cache is already populated
+/// when this is called. This is a fair assumption, because service.rs iterates through all
+/// security levels when it gets instantiated.
+pub fn get_keymint_dev_by_uuid(uuid: &Uuid) -> Result<(Asp, KeyMintHardwareInfo)> {
+    let devices_map = KEY_MINT_DEVICES.lock().unwrap();
+    if let Some((dev, hw_info, _)) = devices_map.dev_by_uuid(uuid) {
+        Ok((dev, hw_info))
+    } else {
+        Err(Error::sys()).context("In get_keymint_dev_by_uuid: No KeyMint instance found.")
+    }
+}
+
+/// Return all known keymint devices.
+pub fn get_keymint_devices() -> Vec<Strong<dyn IKeyMintDevice>> {
+    KEY_MINT_DEVICES.lock().unwrap().devices()
+}
+
+static TIME_STAMP_SERVICE_NAME: &str = "android.hardware.security.secureclock.ISecureClock";
+
+/// Make a new connection to a secure clock service.
+/// If no native SecureClock device can be found brings up the compatibility service and attempts
+/// to connect to the legacy wrapper.
+fn connect_secureclock() -> Result<Asp> {
+    let secureclock_instances =
+        get_aidl_instances("android.hardware.security.secureclock", 1, "ISecureClock");
+
+    let secure_clock_available =
+        secureclock_instances.as_vec()?.iter().any(|instance| *instance == "default");
+
+    let default_time_stamp_service_name = format!("{}/default", TIME_STAMP_SERVICE_NAME);
+
+    let secureclock = if secure_clock_available {
+        map_binder_status_code(binder::get_interface(&default_time_stamp_service_name))
+            .context("In connect_secureclock: Trying to connect to genuine secure clock service.")
+    } else {
+        // This is a no-op if it was called before.
+        keystore2_km_compat::add_keymint_device_service();
+
+        let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
+            map_binder_status_code(binder::get_interface("android.security.compat"))
+                .context("In connect_secureclock: Trying to connect to compat service.")?;
+
+        // Legacy secure clock services were only implemented by TEE.
+        map_binder_status(keystore_compat_service.getSecureClock())
+            .map_err(|e| match e {
+                Error::BinderTransaction(StatusCode::NAME_NOT_FOUND) => {
+                    Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)
+                }
+                e => e,
+            })
+            .context("In connect_secureclock: Trying to get Legacy wrapper.")
+    }?;
+
+    Ok(Asp::new(secureclock.as_binder()))
+}
+
+/// Get the timestamp service that verifies auth token timeliness towards security levels with
+/// different clocks.
+pub fn get_timestamp_service() -> Result<Asp> {
+    let mut ts_device = TIME_STAMP_DEVICE.lock().unwrap();
+    if let Some(dev) = &*ts_device {
+        Ok(dev.clone())
+    } else {
+        let dev = connect_secureclock().context("In get_timestamp_service.")?;
+        *ts_device = Some(dev.clone());
+        Ok(dev)
+    }
+}
+
+static REMOTE_PROVISIONING_HAL_SERVICE_NAME: &str =
+    "android.hardware.security.keymint.IRemotelyProvisionedComponent";
+
+fn connect_remotely_provisioned_component(security_level: &SecurityLevel) -> Result<Asp> {
+    let remotely_prov_instances =
+        get_aidl_instances("android.hardware.security.keymint", 1, "IRemotelyProvisionedComponent");
+
+    let service_name = match *security_level {
+        SecurityLevel::TRUSTED_ENVIRONMENT => {
+            if remotely_prov_instances.as_vec()?.iter().any(|instance| *instance == "default") {
+                Some(format!("{}/default", REMOTE_PROVISIONING_HAL_SERVICE_NAME))
+            } else {
+                None
+            }
+        }
+        SecurityLevel::STRONGBOX => {
+            if remotely_prov_instances.as_vec()?.iter().any(|instance| *instance == "strongbox") {
+                Some(format!("{}/strongbox", REMOTE_PROVISIONING_HAL_SERVICE_NAME))
+            } else {
+                None
+            }
+        }
+        _ => None,
+    }
+    .ok_or(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
+    .context("In connect_remotely_provisioned_component.")?;
+
+    let rem_prov_hal: Strong<dyn IRemotelyProvisionedComponent> =
+        map_binder_status_code(binder::get_interface(&service_name))
+            .context(concat!(
+                "In connect_remotely_provisioned_component: Trying to connect to",
+                " RemotelyProvisionedComponent service."
+            ))
+            .map_err(|e| e)?;
+    Ok(Asp::new(rem_prov_hal.as_binder()))
+}
+
+/// Get a remote provisiong component device for the given security level either from the cache or
+/// by making a new connection. Returns the device.
+pub fn get_remotely_provisioned_component(security_level: &SecurityLevel) -> Result<Asp> {
+    let mut devices_map = REMOTELY_PROVISIONED_COMPONENT_DEVICES.lock().unwrap();
+    if let Some(dev) = devices_map.dev_by_sec_level(&security_level) {
+        Ok(dev)
+    } else {
+        let dev = connect_remotely_provisioned_component(security_level)
+            .context("In get_remotely_provisioned_component.")?;
+        devices_map.insert(*security_level, dev);
+        // Unwrap must succeed because we just inserted it.
+        Ok(devices_map.dev_by_sec_level(security_level).unwrap())
+    }
+}
diff --git a/keystore2/src/id_rotation.rs b/keystore2/src/id_rotation.rs
new file mode 100644
index 0000000..dbf0fc9
--- /dev/null
+++ b/keystore2/src/id_rotation.rs
@@ -0,0 +1,122 @@
+// Copyright 2021, 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.
+
+//! This module implements the unique id rotation privacy feature. Certain system components
+//! have the ability to include a per-app unique id into the key attestation. The key rotation
+//! feature assures that the unique id is rotated on factory reset at least once in a 30 day
+//! key rotation period.
+//!
+//! It is assumed that the timestamp file does not exist after a factory reset. So the creation
+//! time of the timestamp file provides a lower bound for the time since factory reset.
+
+use anyhow::{Context, Result};
+use std::fs;
+use std::io::ErrorKind;
+use std::path::{Path, PathBuf};
+use std::time::Duration;
+
+const ID_ROTATION_PERIOD: Duration = Duration::from_secs(30 * 24 * 60 * 60); // Thirty days.
+static TIMESTAMP_FILE_NAME: &str = &"timestamp";
+
+/// The IdRotationState stores the path to the timestamp file for deferred usage. The data
+/// partition is usually not available when Keystore 2.0 starts up. So this object is created
+/// and passed down to the users of the feature which can then query the timestamp on demand.
+#[derive(Debug, Clone)]
+pub struct IdRotationState {
+    timestamp_path: PathBuf,
+}
+
+impl IdRotationState {
+    /// Creates a new IdRotationState. It holds the path to the timestamp file for deferred usage.
+    pub fn new(keystore_db_path: &Path) -> Self {
+        let mut timestamp_path = keystore_db_path.to_owned();
+        timestamp_path.push(TIMESTAMP_FILE_NAME);
+        Self { timestamp_path }
+    }
+
+    /// Reads the metadata of or creates the timestamp file. It returns true if the timestamp
+    /// file is younger than `ID_ROTATION_PERIOD`, i.e., 30 days.
+    pub fn had_factory_reset_since_id_rotation(&self) -> Result<bool> {
+        match fs::metadata(&self.timestamp_path) {
+            Ok(metadata) => {
+                let duration_since_factory_reset = metadata
+                    .modified()
+                    .context("File creation time not supported.")?
+                    .elapsed()
+                    .context("Failed to compute time elapsed since factory reset.")?;
+                Ok(duration_since_factory_reset < ID_ROTATION_PERIOD)
+            }
+            Err(e) => match e.kind() {
+                ErrorKind::NotFound => {
+                    fs::File::create(&self.timestamp_path)
+                        .context("Failed to create timestamp file.")?;
+                    Ok(true)
+                }
+                _ => Err(e).context("Failed to open timestamp file."),
+            },
+        }
+        .context("In had_factory_reset_since_id_rotation:")
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use keystore2_test_utils::TempDir;
+    use nix::sys::stat::utimes;
+    use nix::sys::time::{TimeVal, TimeValLike};
+    use std::convert::TryInto;
+    use std::time::UNIX_EPOCH;
+
+    #[test]
+    fn test_had_factory_reset_since_id_rotation() -> Result<()> {
+        let temp_dir = TempDir::new("test_had_factory_reset_since_id_rotation_")
+            .expect("Failed to create temp dir.");
+        let id_rotation_state = IdRotationState::new(&temp_dir.path());
+
+        let mut temp_file_path = temp_dir.path().to_owned();
+        temp_file_path.push(TIMESTAMP_FILE_NAME);
+
+        // The timestamp file should not exist.
+        assert!(!temp_file_path.exists());
+
+        // This should return true.
+        assert!(id_rotation_state.had_factory_reset_since_id_rotation()?);
+
+        // Now the timestamp file should exist.
+        assert!(temp_file_path.exists());
+
+        // We should still return true because the timestamp file is young.
+        assert!(id_rotation_state.had_factory_reset_since_id_rotation()?);
+
+        // Now let's age the timestamp file by backdating the modification time.
+        let metadata = fs::metadata(&temp_file_path)?;
+        let mtime = metadata.modified()?;
+        let mtime = mtime.duration_since(UNIX_EPOCH)?;
+        let mtime =
+            mtime.checked_sub(ID_ROTATION_PERIOD).expect("Failed to subtract id rotation period");
+        let mtime = TimeVal::seconds(mtime.as_secs().try_into().unwrap());
+
+        let atime = metadata.accessed()?;
+        let atime = atime.duration_since(UNIX_EPOCH)?;
+        let atime = TimeVal::seconds(atime.as_secs().try_into().unwrap());
+
+        utimes(&temp_file_path, &atime, &mtime)?;
+
+        // Now that the file has aged we should see false.
+        assert!(!id_rotation_state.had_factory_reset_since_id_rotation()?);
+
+        Ok(())
+    }
+}
diff --git a/keystore2/src/key_parameter.rs b/keystore2/src/key_parameter.rs
new file mode 100644
index 0000000..74a9b23
--- /dev/null
+++ b/keystore2/src/key_parameter.rs
@@ -0,0 +1,1507 @@
+// Copyright 2020, 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.
+
+//! Key parameters are declared by KeyMint to describe properties of keys and operations.
+//! During key generation and import, key parameters are used to characterize a key, its usage
+//! restrictions, and additional parameters for attestation. During the lifetime of the key,
+//! the key characteristics are expressed as set of key parameters. During cryptographic
+//! operations, clients may specify additional operation specific parameters.
+//! This module provides a Keystore 2.0 internal representation for key parameters and
+//! implements traits to convert it from and into KeyMint KeyParameters and store it in
+//! the SQLite database.
+//!
+//! ## Synopsis
+//!
+//! enum KeyParameterValue {
+//!     Invalid,
+//!     Algorithm(Algorithm),
+//!     ...
+//! }
+//!
+//! impl KeyParameterValue {
+//!     pub fn get_tag(&self) -> Tag;
+//!     pub fn new_from_sql(tag: Tag, data: &SqlField) -> Result<Self>;
+//!     pub fn new_from_tag_primitive_pair<T: Into<Primitive>>(tag: Tag, v: T)
+//!        -> Result<Self, PrimitiveError>;
+//!     fn to_sql(&self) -> SqlResult<ToSqlOutput>
+//! }
+//!
+//! use ...::keymint::KeyParameter as KmKeyParameter;
+//! impl Into<KmKeyParameter> for KeyParameterValue {}
+//! impl From<KmKeyParameter> for KeyParameterValue {}
+//!
+//! ## Implementation
+//! Each of the six functions is implemented as match statement over each key parameter variant.
+//! We bootstrap these function as well as the KeyParameterValue enum itself from a single list
+//! of key parameters, that needs to be kept in sync with the KeyMint AIDL specification.
+//!
+//! The list resembles an enum declaration with a few extra fields.
+//! enum KeyParameterValue {
+//!    Invalid with tag INVALID and field Invalid,
+//!    Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
+//!    ...
+//! }
+//! The tag corresponds to the variant of the keymint::Tag, and the field corresponds to the
+//! variant of the keymint::KeyParameterValue union. There is no one to one mapping between
+//! tags and union fields, e.g., the values of both tags BOOT_PATCHLEVEL and VENDOR_PATCHLEVEL
+//! are stored in the Integer field.
+//!
+//! The macros interpreting them all follow a similar pattern and follow the following fragment
+//! naming scheme:
+//!
+//!    Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
+//!    $vname $(($vtype ))? with tag $tag_name and field $field_name,
+//!
+//! Further, KeyParameterValue appears in the macro as $enum_name.
+//! Note that $vtype is optional to accommodate variants like Invalid which don't wrap a value.
+//!
+//! In some cases $vtype is not part of the expansion, but we still have to modify the expansion
+//! depending on the presence of $vtype. In these cases we recurse through the list following the
+//! following pattern:
+//!
+//! (@<marker> <non repeating args>, [<out list>], [<in list>])
+//!
+//! These macros usually have four rules:
+//!  * Two main recursive rules, of the form:
+//!    (
+//!        @<marker>
+//!        <non repeating args>,
+//!        [<out list>],
+//!        [<one element pattern> <in tail>]
+//!    ) => {
+//!        macro!{@<marker> <non repeating args>, [<out list>
+//!            <one element expansion>
+//!        ], [<in tail>]}
+//!    };
+//!    They pop one element off the <in list> and add one expansion to the out list.
+//!    The element expansion is kept on a separate line (or lines) for better readability.
+//!    The two variants differ in whether or not $vtype is expected.
+//!  * The termination condition which has an empty in list.
+//!  * The public interface, which does not have @marker and calls itself with an empty out list.
+
+#![allow(clippy::from_over_into, clippy::needless_question_mark)]
+
+use std::convert::TryInto;
+
+use crate::db_utils::SqlField;
+use crate::error::Error as KeystoreError;
+use crate::error::ResponseCode;
+
+pub use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
+    HardwareAuthenticatorType::HardwareAuthenticatorType, KeyOrigin::KeyOrigin,
+    KeyParameter::KeyParameter as KmKeyParameter,
+    KeyParameterValue::KeyParameterValue as KmKeyParameterValue, KeyPurpose::KeyPurpose,
+    PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
+};
+use android_system_keystore2::aidl::android::system::keystore2::Authorization::Authorization;
+use anyhow::{Context, Result};
+use rusqlite::types::{Null, ToSql, ToSqlOutput};
+use rusqlite::Result as SqlResult;
+
+/// This trait is used to associate a primitive to any type that can be stored inside a
+/// KeyParameterValue, especially the AIDL enum types, e.g., keymint::{Algorithm, Digest, ...}.
+/// This allows for simplifying the macro rules, e.g., for reading from the SQL database.
+/// An expression like `KeyParameterValue::Algorithm(row.get(0))` would not work because
+/// a type of `Algorithm` is expected which does not implement `FromSql` and we cannot
+/// implement it because we own neither the type nor the trait.
+/// With AssociatePrimitive we can write an expression
+/// `KeyParameter::Algorithm(<Algorithm>::from_primitive(row.get(0)))` to inform `get`
+/// about the expected primitive type that it can convert into. By implementing this
+/// trait for all inner types we can write a single rule to cover all cases (except where
+/// there is no wrapped type):
+/// `KeyParameterValue::$vname(<$vtype>::from_primitive(row.get(0)))`
+trait AssociatePrimitive {
+    type Primitive;
+
+    fn from_primitive(v: Self::Primitive) -> Self;
+    fn to_primitive(&self) -> Self::Primitive;
+}
+
+/// Associates the given type with i32. The macro assumes that the given type is actually a
+/// tuple struct wrapping i32, such as AIDL enum types.
+macro_rules! implement_associate_primitive_for_aidl_enum {
+    ($t:ty) => {
+        impl AssociatePrimitive for $t {
+            type Primitive = i32;
+
+            fn from_primitive(v: Self::Primitive) -> Self {
+                Self(v)
+            }
+            fn to_primitive(&self) -> Self::Primitive {
+                self.0
+            }
+        }
+    };
+}
+
+/// Associates the given type with itself.
+macro_rules! implement_associate_primitive_identity {
+    ($t:ty) => {
+        impl AssociatePrimitive for $t {
+            type Primitive = $t;
+
+            fn from_primitive(v: Self::Primitive) -> Self {
+                v
+            }
+            fn to_primitive(&self) -> Self::Primitive {
+                self.clone()
+            }
+        }
+    };
+}
+
+implement_associate_primitive_for_aidl_enum! {Algorithm}
+implement_associate_primitive_for_aidl_enum! {BlockMode}
+implement_associate_primitive_for_aidl_enum! {Digest}
+implement_associate_primitive_for_aidl_enum! {EcCurve}
+implement_associate_primitive_for_aidl_enum! {HardwareAuthenticatorType}
+implement_associate_primitive_for_aidl_enum! {KeyOrigin}
+implement_associate_primitive_for_aidl_enum! {KeyPurpose}
+implement_associate_primitive_for_aidl_enum! {PaddingMode}
+implement_associate_primitive_for_aidl_enum! {SecurityLevel}
+
+implement_associate_primitive_identity! {Vec<u8>}
+implement_associate_primitive_identity! {i64}
+implement_associate_primitive_identity! {i32}
+
+/// This enum allows passing a primitive value to `KeyParameterValue::new_from_tag_primitive_pair`
+/// Usually, it is not necessary to use this type directly because the function uses
+/// `Into<Primitive>` as a trait bound.
+pub enum Primitive {
+    /// Wraps an i64.
+    I64(i64),
+    /// Wraps an i32.
+    I32(i32),
+    /// Wraps a Vec<u8>.
+    Vec(Vec<u8>),
+}
+
+impl From<i64> for Primitive {
+    fn from(v: i64) -> Self {
+        Self::I64(v)
+    }
+}
+impl From<i32> for Primitive {
+    fn from(v: i32) -> Self {
+        Self::I32(v)
+    }
+}
+impl From<Vec<u8>> for Primitive {
+    fn from(v: Vec<u8>) -> Self {
+        Self::Vec(v)
+    }
+}
+
+/// This error is returned by `KeyParameterValue::new_from_tag_primitive_pair`.
+#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub enum PrimitiveError {
+    /// Returned if this primitive is unsuitable for the given tag type.
+    #[error("Primitive does not match the expected tag type.")]
+    TypeMismatch,
+    /// Return if the tag type is unknown.
+    #[error("Unknown tag.")]
+    UnknownTag,
+}
+
+impl TryInto<i64> for Primitive {
+    type Error = PrimitiveError;
+
+    fn try_into(self) -> Result<i64, Self::Error> {
+        match self {
+            Self::I64(v) => Ok(v),
+            _ => Err(Self::Error::TypeMismatch),
+        }
+    }
+}
+impl TryInto<i32> for Primitive {
+    type Error = PrimitiveError;
+
+    fn try_into(self) -> Result<i32, Self::Error> {
+        match self {
+            Self::I32(v) => Ok(v),
+            _ => Err(Self::Error::TypeMismatch),
+        }
+    }
+}
+impl TryInto<Vec<u8>> for Primitive {
+    type Error = PrimitiveError;
+
+    fn try_into(self) -> Result<Vec<u8>, Self::Error> {
+        match self {
+            Self::Vec(v) => Ok(v),
+            _ => Err(Self::Error::TypeMismatch),
+        }
+    }
+}
+
+/// Expands the list of KeyParameterValue variants as follows:
+///
+/// Input:
+/// Invalid with tag INVALID and field Invalid,
+/// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
+///
+/// Output:
+/// ```
+/// pub fn new_from_tag_primitive_pair<T: Into<Primitive>>(
+///     tag: Tag,
+///     v: T
+/// ) -> Result<KeyParameterValue, PrimitiveError> {
+///     let p: Primitive = v.into();
+///     Ok(match tag {
+///         Tag::INVALID => KeyParameterValue::Invalid,
+///         Tag::ALGORITHM => KeyParameterValue::Algorithm(
+///             <Algorithm>::from_primitive(p.try_into()?)
+///         ),
+///         _ => return Err(PrimitiveError::UnknownTag),
+///     })
+/// }
+/// ```
+macro_rules! implement_from_tag_primitive_pair {
+    ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => {
+        /// Returns the an instance of $enum_name or an error if the given primitive does not match
+        /// the tag type or the tag is unknown.
+        pub fn new_from_tag_primitive_pair<T: Into<Primitive>>(
+            tag: Tag,
+            v: T
+        ) -> Result<$enum_name, PrimitiveError> {
+            let p: Primitive = v.into();
+            Ok(match tag {
+                $(Tag::$tag_name => $enum_name::$vname$((
+                    <$vtype>::from_primitive(p.try_into()?)
+                ))?,)*
+                _ => return Err(PrimitiveError::UnknownTag),
+            })
+        }
+    };
+}
+
+/// Expands the list of KeyParameterValue variants as follows:
+///
+/// Input:
+/// pub enum KeyParameterValue {
+///     Invalid with tag INVALID and field Invalid,
+///     Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
+/// }
+///
+/// Output:
+/// ```
+/// pub enum KeyParameterValue {
+///     Invalid,
+///     Algorithm(Algorithm),
+/// }
+/// ```
+macro_rules! implement_enum {
+    (
+        $(#[$enum_meta:meta])*
+        $enum_vis:vis enum $enum_name:ident {
+             $($(#[$emeta:meta])* $vname:ident$(($vtype:ty))?),* $(,)?
+        }
+    ) => {
+        $(#[$enum_meta])*
+        $enum_vis enum $enum_name {
+            $(
+                $(#[$emeta])*
+                $vname$(($vtype))?
+            ),*
+        }
+    };
+}
+
+/// Expands the list of KeyParameterValue variants as follows:
+///
+/// Input:
+/// Invalid with tag INVALID and field Invalid,
+/// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
+///
+/// Output:
+/// ```
+/// pub fn get_tag(&self) -> Tag {
+///     match self {
+///         KeyParameterValue::Invalid => Tag::INVALID,
+///         KeyParameterValue::Algorithm(_) => Tag::ALGORITHM,
+///     }
+/// }
+/// ```
+macro_rules! implement_get_tag {
+    (
+        @replace_type_spec
+        $enum_name:ident,
+        [$($out:tt)*],
+        [$vname:ident($vtype:ty) $tag_name:ident, $($in:tt)*]
+    ) => {
+        implement_get_tag!{@replace_type_spec $enum_name, [$($out)*
+            $enum_name::$vname(_) => Tag::$tag_name,
+        ], [$($in)*]}
+    };
+    (
+        @replace_type_spec
+        $enum_name:ident,
+        [$($out:tt)*],
+        [$vname:ident $tag_name:ident, $($in:tt)*]
+    ) => {
+        implement_get_tag!{@replace_type_spec $enum_name, [$($out)*
+            $enum_name::$vname => Tag::$tag_name,
+        ], [$($in)*]}
+    };
+    (@replace_type_spec $enum_name:ident, [$($out:tt)*], []) => {
+        /// Returns the tag of the given instance.
+        pub fn get_tag(&self) -> Tag {
+            match self {
+                $($out)*
+            }
+        }
+    };
+
+    ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => {
+        implement_get_tag!{@replace_type_spec $enum_name, [], [$($vname$(($vtype))? $tag_name,)*]}
+    };
+}
+
+/// Expands the list of KeyParameterValue variants as follows:
+///
+/// Input:
+/// Invalid with tag INVALID and field Invalid,
+/// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
+///
+/// Output:
+/// ```
+/// fn to_sql(&self) -> SqlResult<ToSqlOutput> {
+///     match self {
+///         KeyParameterValue::Invalid => Ok(ToSqlOutput::from(Null)),
+///         KeyParameterValue::Algorithm(v) => Ok(ToSqlOutput::from(v.to_primitive())),
+///     }
+/// }
+/// ```
+macro_rules! implement_to_sql {
+    (
+        @replace_type_spec
+        $enum_name:ident,
+        [$($out:tt)*],
+        [$vname:ident($vtype:ty), $($in:tt)*]
+    ) => {
+        implement_to_sql!{@replace_type_spec $enum_name, [ $($out)*
+            $enum_name::$vname(v) => Ok(ToSqlOutput::from(v.to_primitive())),
+        ], [$($in)*]}
+    };
+    (
+        @replace_type_spec
+        $enum_name:ident,
+        [$($out:tt)*],
+        [$vname:ident, $($in:tt)*]
+    ) => {
+        implement_to_sql!{@replace_type_spec $enum_name, [ $($out)*
+            $enum_name::$vname => Ok(ToSqlOutput::from(Null)),
+        ], [$($in)*]}
+    };
+    (@replace_type_spec $enum_name:ident, [$($out:tt)*], []) => {
+        /// Converts $enum_name to be stored in a rusqlite database.
+        fn to_sql(&self) -> SqlResult<ToSqlOutput> {
+            match self {
+                $($out)*
+            }
+        }
+    };
+
+
+    ($enum_name:ident; $($vname:ident$(($vtype:ty))?),*) => {
+        impl ToSql for $enum_name {
+            implement_to_sql!{@replace_type_spec $enum_name, [], [$($vname$(($vtype))?,)*]}
+        }
+
+    }
+}
+
+/// Expands the list of KeyParameterValue variants as follows:
+///
+/// Input:
+/// Invalid with tag INVALID and field Invalid,
+/// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
+///
+/// Output:
+/// ```
+/// pub fn new_from_sql(
+///     tag: Tag,
+///     data: &SqlField,
+/// ) -> Result<Self> {
+///     Ok(match self {
+///         Tag::Invalid => KeyParameterValue::Invalid,
+///         Tag::ALGORITHM => {
+///             KeyParameterValue::Algorithm(<Algorithm>::from_primitive(data
+///                 .get()
+///                 .map_err(|_| KeystoreError::Rc(ResponseCode::VALUE_CORRUPTED))
+///                 .context(concat!("Failed to read sql data for tag: ", "ALGORITHM", "."))?
+///             ))
+///         },
+///     })
+/// }
+/// ```
+macro_rules! implement_new_from_sql {
+    ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => {
+        /// Takes a tag and an SqlField and attempts to construct a KeyParameter value.
+        /// This function may fail if the parameter value cannot be extracted from the
+        /// database cell.
+        pub fn new_from_sql(
+            tag: Tag,
+            data: &SqlField,
+        ) -> Result<Self> {
+            Ok(match tag {
+                $(
+                    Tag::$tag_name => {
+                        $enum_name::$vname$((<$vtype>::from_primitive(data
+                            .get()
+                            .map_err(|_| KeystoreError::Rc(ResponseCode::VALUE_CORRUPTED))
+                            .context(concat!(
+                                "Failed to read sql data for tag: ",
+                                stringify!($tag_name),
+                                "."
+                            ))?
+                        )))?
+                    },
+                )*
+                _ => $enum_name::Invalid,
+            })
+        }
+    };
+}
+
+/// This key parameter default is used during the conversion from KeyParameterValue
+/// to keymint::KeyParameterValue. Keystore's version does not have wrapped types
+/// for boolean tags and the tag Invalid. The AIDL version uses bool and integer
+/// variants respectively. This default function is invoked in these cases to
+/// homogenize the rules for boolean and invalid tags.
+/// The bool variant returns true because boolean parameters are implicitly true
+/// if present.
+trait KpDefault {
+    fn default() -> Self;
+}
+
+impl KpDefault for i32 {
+    fn default() -> Self {
+        0
+    }
+}
+
+impl KpDefault for bool {
+    fn default() -> Self {
+        true
+    }
+}
+
+/// Expands the list of KeyParameterValue variants as follows:
+///
+/// Input:
+/// Invalid with tag INVALID and field Invalid,
+/// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
+///
+/// Output:
+/// ```
+/// impl From<KmKeyParameter> for KeyParameterValue {
+///     fn from(kp: KmKeyParameter) -> Self {
+///         match kp {
+///             KmKeyParameter { tag: Tag::INVALID, value: KmKeyParameterValue::Invalid(_) }
+///                 => $enum_name::$vname,
+///             KmKeyParameter { tag: Tag::Algorithm, value: KmKeyParameterValue::Algorithm(v) }
+///                 => $enum_name::Algorithm(v),
+///             _ => $enum_name::Invalid,
+///         }
+///     }
+/// }
+///
+/// impl Into<KmKeyParameter> for KeyParameterValue {
+///     fn into(self) -> KmKeyParameter {
+///         match self {
+///             KeyParameterValue::Invalid => KmKeyParameter {
+///                 tag: Tag::INVALID,
+///                 value: KmKeyParameterValue::Invalid(KpDefault::default())
+///             },
+///             KeyParameterValue::Algorithm(v) => KmKeyParameter {
+///                 tag: Tag::ALGORITHM,
+///                 value: KmKeyParameterValue::Algorithm(v)
+///             },
+///         }
+///     }
+/// }
+/// ```
+macro_rules! implement_try_from_to_km_parameter {
+    // The first three rules expand From<KmKeyParameter>.
+    (
+        @from
+        $enum_name:ident,
+        [$($out:tt)*],
+        [$vname:ident($vtype:ty) $tag_name:ident $field_name:ident, $($in:tt)*]
+    ) => {
+        implement_try_from_to_km_parameter!{@from $enum_name, [$($out)*
+            KmKeyParameter {
+                tag: Tag::$tag_name,
+                value: KmKeyParameterValue::$field_name(v)
+            } => $enum_name::$vname(v),
+        ], [$($in)*]
+    }};
+    (
+        @from
+        $enum_name:ident,
+        [$($out:tt)*],
+        [$vname:ident $tag_name:ident $field_name:ident, $($in:tt)*]
+    ) => {
+        implement_try_from_to_km_parameter!{@from $enum_name, [$($out)*
+            KmKeyParameter {
+                tag: Tag::$tag_name,
+                value: KmKeyParameterValue::$field_name(_)
+            } => $enum_name::$vname,
+        ], [$($in)*]
+    }};
+    (@from $enum_name:ident, [$($out:tt)*], []) => {
+        impl From<KmKeyParameter> for $enum_name {
+            fn from(kp: KmKeyParameter) -> Self {
+                match kp {
+                    $($out)*
+                    _ => $enum_name::Invalid,
+                }
+            }
+        }
+    };
+
+    // The next three rules expand Into<KmKeyParameter>.
+    (
+        @into
+        $enum_name:ident,
+        [$($out:tt)*],
+        [$vname:ident($vtype:ty) $tag_name:ident $field_name:ident, $($in:tt)*]
+    ) => {
+        implement_try_from_to_km_parameter!{@into $enum_name, [$($out)*
+            $enum_name::$vname(v) => KmKeyParameter {
+                tag: Tag::$tag_name,
+                value: KmKeyParameterValue::$field_name(v)
+            },
+        ], [$($in)*]
+    }};
+    (
+        @into
+        $enum_name:ident,
+        [$($out:tt)*],
+        [$vname:ident $tag_name:ident $field_name:ident, $($in:tt)*]
+    ) => {
+        implement_try_from_to_km_parameter!{@into $enum_name, [$($out)*
+            $enum_name::$vname => KmKeyParameter {
+                tag: Tag::$tag_name,
+                value: KmKeyParameterValue::$field_name(KpDefault::default())
+            },
+        ], [$($in)*]
+    }};
+    (@into $enum_name:ident, [$($out:tt)*], []) => {
+        impl Into<KmKeyParameter> for $enum_name {
+            fn into(self) -> KmKeyParameter {
+                match self {
+                    $($out)*
+                }
+            }
+        }
+    };
+
+
+    ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident $field_name:ident),*) => {
+        implement_try_from_to_km_parameter!(
+            @from $enum_name,
+            [],
+            [$($vname$(($vtype))? $tag_name $field_name,)*]
+        );
+        implement_try_from_to_km_parameter!(
+            @into $enum_name,
+            [],
+            [$($vname$(($vtype))? $tag_name $field_name,)*]
+        );
+    };
+}
+
+/// This is the top level macro. While the other macros do most of the heavy lifting, this takes
+/// the key parameter list and passes it on to the other macros to generate all of the conversion
+/// functions. In addition, it generates an important test vector for verifying that tag type of the
+/// keymint tag matches the associated keymint KeyParameterValue field.
+macro_rules! implement_key_parameter_value {
+    (
+        $(#[$enum_meta:meta])*
+        $enum_vis:vis enum $enum_name:ident {
+            $(
+                $(#[$($emeta:tt)+])*
+                $vname:ident$(($vtype:ty))?
+            ),* $(,)?
+        }
+    ) => {
+        implement_key_parameter_value!{
+            @extract_attr
+            $(#[$enum_meta])*
+            $enum_vis enum $enum_name {
+                []
+                [$(
+                    [] [$(#[$($emeta)+])*]
+                    $vname$(($vtype))?,
+                )*]
+            }
+        }
+    };
+
+    (
+        @extract_attr
+        $(#[$enum_meta:meta])*
+        $enum_vis:vis enum $enum_name:ident {
+            [$($out:tt)*]
+            [
+                [$(#[$mout:meta])*]
+                [
+                    #[key_param(tag = $tag_name:ident, field = $field_name:ident)]
+                    $(#[$($mtail:tt)+])*
+                ]
+                $vname:ident$(($vtype:ty))?,
+                $($tail:tt)*
+            ]
+        }
+    ) => {
+        implement_key_parameter_value!{
+            @extract_attr
+            $(#[$enum_meta])*
+            $enum_vis enum $enum_name {
+                [
+                    $($out)*
+                    $(#[$mout])*
+                    $(#[$($mtail)+])*
+                    $tag_name $field_name $vname$(($vtype))?,
+                ]
+                [$($tail)*]
+            }
+        }
+    };
+
+    (
+        @extract_attr
+        $(#[$enum_meta:meta])*
+        $enum_vis:vis enum $enum_name:ident {
+            [$($out:tt)*]
+            [
+                [$(#[$mout:meta])*]
+                [
+                    #[$front:meta]
+                    $(#[$($mtail:tt)+])*
+                ]
+                $vname:ident$(($vtype:ty))?,
+                $($tail:tt)*
+            ]
+        }
+    ) => {
+        implement_key_parameter_value!{
+            @extract_attr
+            $(#[$enum_meta])*
+            $enum_vis enum $enum_name {
+                [$($out)*]
+                [
+                    [
+                        $(#[$mout])*
+                        #[$front]
+                    ]
+                    [$(#[$($mtail)+])*]
+                    $vname$(($vtype))?,
+                    $($tail)*
+                ]
+            }
+        }
+    };
+
+    (
+        @extract_attr
+        $(#[$enum_meta:meta])*
+        $enum_vis:vis enum $enum_name:ident {
+            [$($out:tt)*]
+            []
+        }
+    ) => {
+        implement_key_parameter_value!{
+            @spill
+            $(#[$enum_meta])*
+            $enum_vis enum $enum_name {
+                $($out)*
+            }
+        }
+    };
+
+    (
+        @spill
+        $(#[$enum_meta:meta])*
+        $enum_vis:vis enum $enum_name:ident {
+            $(
+                $(#[$emeta:meta])*
+                $tag_name:ident $field_name:ident $vname:ident$(($vtype:ty))?,
+            )*
+        }
+    ) => {
+        implement_enum!(
+            $(#[$enum_meta])*
+            $enum_vis enum $enum_name {
+            $(
+                $(#[$emeta])*
+                $vname$(($vtype))?
+            ),*
+        });
+
+        impl $enum_name {
+            implement_new_from_sql!($enum_name; $($vname$(($vtype))? $tag_name),*);
+            implement_get_tag!($enum_name; $($vname$(($vtype))? $tag_name),*);
+            implement_from_tag_primitive_pair!($enum_name; $($vname$(($vtype))? $tag_name),*);
+
+            #[cfg(test)]
+            fn make_field_matches_tag_type_test_vector() -> Vec<KmKeyParameter> {
+                vec![$(KmKeyParameter{
+                    tag: Tag::$tag_name,
+                    value: KmKeyParameterValue::$field_name(Default::default())}
+                ),*]
+            }
+        }
+
+        implement_try_from_to_km_parameter!(
+            $enum_name;
+            $($vname$(($vtype))? $tag_name $field_name),*
+        );
+
+        implement_to_sql!($enum_name; $($vname$(($vtype))?),*);
+    };
+}
+
+implement_key_parameter_value! {
+/// KeyParameterValue holds a value corresponding to one of the Tags defined in
+/// the AIDL spec at hardware/interfaces/security/keymint
+#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
+pub enum KeyParameterValue {
+    /// Associated with Tag:INVALID
+    #[key_param(tag = INVALID, field = Invalid)]
+    Invalid,
+    /// Set of purposes for which the key may be used
+    #[key_param(tag = PURPOSE, field = KeyPurpose)]
+    KeyPurpose(KeyPurpose),
+    /// Cryptographic algorithm with which the key is used
+    #[key_param(tag = ALGORITHM, field = Algorithm)]
+    Algorithm(Algorithm),
+    /// Size of the key , in bits
+    #[key_param(tag = KEY_SIZE, field = Integer)]
+    KeySize(i32),
+    /// Block cipher mode(s) with which the key may be used
+    #[key_param(tag = BLOCK_MODE, field = BlockMode)]
+    BlockMode(BlockMode),
+    /// Digest algorithms that may be used with the key to perform signing and verification
+    #[key_param(tag = DIGEST, field = Digest)]
+    Digest(Digest),
+    /// Padding modes that may be used with the key.  Relevant to RSA, AES and 3DES keys.
+    #[key_param(tag = PADDING, field = PaddingMode)]
+    PaddingMode(PaddingMode),
+    /// Can the caller provide a nonce for nonce-requiring operations
+    #[key_param(tag = CALLER_NONCE, field = BoolValue)]
+    CallerNonce,
+    /// Minimum length of MAC for HMAC keys and AES keys that support GCM mode
+    #[key_param(tag = MIN_MAC_LENGTH, field = Integer)]
+    MinMacLength(i32),
+    /// The elliptic curve
+    #[key_param(tag = EC_CURVE, field = EcCurve)]
+    EcCurve(EcCurve),
+    /// Value of the public exponent for an RSA key pair
+    #[key_param(tag = RSA_PUBLIC_EXPONENT, field = LongInteger)]
+    RSAPublicExponent(i64),
+    /// An attestation certificate for the generated key should contain an application-scoped
+    /// and time-bounded device-unique ID
+    #[key_param(tag = INCLUDE_UNIQUE_ID, field = BoolValue)]
+    IncludeUniqueID,
+    //TODO: find out about this
+    // /// Necessary system environment conditions for the generated key to be used
+    // KeyBlobUsageRequirements(KeyBlobUsageRequirements),
+    /// Only the boot loader can use the key
+    #[key_param(tag = BOOTLOADER_ONLY, field = BoolValue)]
+    BootLoaderOnly,
+    /// When deleted, the key is guaranteed to be permanently deleted and unusable
+    #[key_param(tag = ROLLBACK_RESISTANCE, field = BoolValue)]
+    RollbackResistance,
+    /// The date and time at which the key becomes active
+    #[key_param(tag = ACTIVE_DATETIME, field = DateTime)]
+    ActiveDateTime(i64),
+    /// The date and time at which the key expires for signing and encryption
+    #[key_param(tag = ORIGINATION_EXPIRE_DATETIME, field = DateTime)]
+    OriginationExpireDateTime(i64),
+    /// The date and time at which the key expires for verification and decryption
+    #[key_param(tag = USAGE_EXPIRE_DATETIME, field = DateTime)]
+    UsageExpireDateTime(i64),
+    /// Minimum amount of time that elapses between allowed operations
+    #[key_param(tag = MIN_SECONDS_BETWEEN_OPS, field = Integer)]
+    MinSecondsBetweenOps(i32),
+    /// Maximum number of times that a key may be used between system reboots
+    #[key_param(tag = MAX_USES_PER_BOOT, field = Integer)]
+    MaxUsesPerBoot(i32),
+    /// The number of times that a limited use key can be used
+    #[key_param(tag = USAGE_COUNT_LIMIT, field = Integer)]
+    UsageCountLimit(i32),
+    /// ID of the Android user that is permitted to use the key
+    #[key_param(tag = USER_ID, field = Integer)]
+    UserID(i32),
+    /// A key may only be used under a particular secure user authentication state
+    #[key_param(tag = USER_SECURE_ID, field = LongInteger)]
+    UserSecureID(i64),
+    /// No authentication is required to use this key
+    #[key_param(tag = NO_AUTH_REQUIRED, field = BoolValue)]
+    NoAuthRequired,
+    /// The types of user authenticators that may be used to authorize this key
+    #[key_param(tag = USER_AUTH_TYPE, field = HardwareAuthenticatorType)]
+    HardwareAuthenticatorType(HardwareAuthenticatorType),
+    /// The time in seconds for which the key is authorized for use, after user authentication
+    #[key_param(tag = AUTH_TIMEOUT, field = Integer)]
+    AuthTimeout(i32),
+    /// The key may be used after authentication timeout if device is still on-body
+    #[key_param(tag = ALLOW_WHILE_ON_BODY, field = BoolValue)]
+    AllowWhileOnBody,
+    /// The key must be unusable except when the user has provided proof of physical presence
+    #[key_param(tag = TRUSTED_USER_PRESENCE_REQUIRED, field = BoolValue)]
+    TrustedUserPresenceRequired,
+    /// Applicable to keys with KeyPurpose SIGN, and specifies that this key must not be usable
+    /// unless the user provides confirmation of the data to be signed
+    #[key_param(tag = TRUSTED_CONFIRMATION_REQUIRED, field = BoolValue)]
+    TrustedConfirmationRequired,
+    /// The key may only be used when the device is unlocked
+    #[key_param(tag = UNLOCKED_DEVICE_REQUIRED, field = BoolValue)]
+    UnlockedDeviceRequired,
+    /// When provided to generateKey or importKey, this tag specifies data
+    /// that is necessary during all uses of the key
+    #[key_param(tag = APPLICATION_ID, field = Blob)]
+    ApplicationID(Vec<u8>),
+    /// When provided to generateKey or importKey, this tag specifies data
+    /// that is necessary during all uses of the key
+    #[key_param(tag = APPLICATION_DATA, field = Blob)]
+    ApplicationData(Vec<u8>),
+    /// Specifies the date and time the key was created
+    #[key_param(tag = CREATION_DATETIME, field = DateTime)]
+    CreationDateTime(i64),
+    /// Specifies where the key was created, if known
+    #[key_param(tag = ORIGIN, field = Origin)]
+    KeyOrigin(KeyOrigin),
+    /// The key used by verified boot to validate the operating system booted
+    #[key_param(tag = ROOT_OF_TRUST, field = Blob)]
+    RootOfTrust(Vec<u8>),
+    /// System OS version with which the key may be used
+    #[key_param(tag = OS_VERSION, field = Integer)]
+    OSVersion(i32),
+    /// Specifies the system security patch level with which the key may be used
+    #[key_param(tag = OS_PATCHLEVEL, field = Integer)]
+    OSPatchLevel(i32),
+    /// Specifies a unique, time-based identifier
+    #[key_param(tag = UNIQUE_ID, field = Blob)]
+    UniqueID(Vec<u8>),
+    /// Used to deliver a "challenge" value to the attestKey() method
+    #[key_param(tag = ATTESTATION_CHALLENGE, field = Blob)]
+    AttestationChallenge(Vec<u8>),
+    /// The set of applications which may use a key, used only with attestKey()
+    #[key_param(tag = ATTESTATION_APPLICATION_ID, field = Blob)]
+    AttestationApplicationID(Vec<u8>),
+    /// Provides the device's brand name, to attestKey()
+    #[key_param(tag = ATTESTATION_ID_BRAND, field = Blob)]
+    AttestationIdBrand(Vec<u8>),
+    /// Provides the device's device name, to attestKey()
+    #[key_param(tag = ATTESTATION_ID_DEVICE, field = Blob)]
+    AttestationIdDevice(Vec<u8>),
+    /// Provides the device's product name, to attestKey()
+    #[key_param(tag = ATTESTATION_ID_PRODUCT, field = Blob)]
+    AttestationIdProduct(Vec<u8>),
+    /// Provides the device's serial number, to attestKey()
+    #[key_param(tag = ATTESTATION_ID_SERIAL, field = Blob)]
+    AttestationIdSerial(Vec<u8>),
+    /// Provides the IMEIs for all radios on the device, to attestKey()
+    #[key_param(tag = ATTESTATION_ID_IMEI, field = Blob)]
+    AttestationIdIMEI(Vec<u8>),
+    /// Provides the MEIDs for all radios on the device, to attestKey()
+    #[key_param(tag = ATTESTATION_ID_MEID, field = Blob)]
+    AttestationIdMEID(Vec<u8>),
+    /// Provides the device's manufacturer name, to attestKey()
+    #[key_param(tag = ATTESTATION_ID_MANUFACTURER, field = Blob)]
+    AttestationIdManufacturer(Vec<u8>),
+    /// Provides the device's model name, to attestKey()
+    #[key_param(tag = ATTESTATION_ID_MODEL, field = Blob)]
+    AttestationIdModel(Vec<u8>),
+    /// Specifies the vendor image security patch level with which the key may be used
+    #[key_param(tag = VENDOR_PATCHLEVEL, field = Integer)]
+    VendorPatchLevel(i32),
+    /// Specifies the boot image (kernel) security patch level with which the key may be used
+    #[key_param(tag = BOOT_PATCHLEVEL, field = Integer)]
+    BootPatchLevel(i32),
+    /// Provides "associated data" for AES-GCM encryption or decryption
+    #[key_param(tag = ASSOCIATED_DATA, field = Blob)]
+    AssociatedData(Vec<u8>),
+    /// Provides or returns a nonce or Initialization Vector (IV) for AES-GCM,
+    /// AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption
+    #[key_param(tag = NONCE, field = Blob)]
+    Nonce(Vec<u8>),
+    /// Provides the requested length of a MAC or GCM authentication tag, in bits
+    #[key_param(tag = MAC_LENGTH, field = Integer)]
+    MacLength(i32),
+    /// Specifies whether the device has been factory reset since the
+    /// last unique ID rotation.  Used for key attestation
+    #[key_param(tag = RESET_SINCE_ID_ROTATION, field = BoolValue)]
+    ResetSinceIdRotation,
+    /// Used to deliver a cryptographic token proving that the user
+    /// confirmed a signing request
+    #[key_param(tag = CONFIRMATION_TOKEN, field = Blob)]
+    ConfirmationToken(Vec<u8>),
+    /// Used to deliver the certificate serial number to the KeyMint instance
+    /// certificate generation.
+    #[key_param(tag = CERTIFICATE_SERIAL, field = Blob)]
+    CertificateSerial(Vec<u8>),
+    /// Used to deliver the certificate subject to the KeyMint instance
+    /// certificate generation. This must be DER encoded X509 name.
+    #[key_param(tag = CERTIFICATE_SUBJECT, field = Blob)]
+    CertificateSubject(Vec<u8>),
+    /// Used to deliver the not before date in milliseconds to KeyMint during key generation/import.
+    #[key_param(tag = CERTIFICATE_NOT_BEFORE, field = DateTime)]
+    CertificateNotBefore(i64),
+    /// Used to deliver the not after date in milliseconds to KeyMint during key generation/import.
+    #[key_param(tag = CERTIFICATE_NOT_AFTER, field = DateTime)]
+    CertificateNotAfter(i64),
+    /// Specifies a maximum boot level at which a key should function
+    #[key_param(tag = MAX_BOOT_LEVEL, field = Integer)]
+    MaxBootLevel(i32),
+}
+}
+
+impl From<&KmKeyParameter> for KeyParameterValue {
+    fn from(kp: &KmKeyParameter) -> Self {
+        kp.clone().into()
+    }
+}
+
+/// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced.
+#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
+pub struct KeyParameter {
+    value: KeyParameterValue,
+    security_level: SecurityLevel,
+}
+
+impl KeyParameter {
+    /// Create an instance of KeyParameter, given the value and the security level.
+    pub fn new(value: KeyParameterValue, security_level: SecurityLevel) -> Self {
+        KeyParameter { value, security_level }
+    }
+
+    /// Construct a KeyParameter from the data from a rusqlite row.
+    /// Note that following variants of KeyParameterValue should not be stored:
+    /// IncludeUniqueID, ApplicationID, ApplicationData, RootOfTrust, UniqueID,
+    /// Attestation*, AssociatedData, Nonce, MacLength, ResetSinceIdRotation, ConfirmationToken.
+    /// This filtering is enforced at a higher level and here we support conversion for all the
+    /// variants.
+    pub fn new_from_sql(
+        tag_val: Tag,
+        data: &SqlField,
+        security_level_val: SecurityLevel,
+    ) -> Result<Self> {
+        Ok(Self {
+            value: KeyParameterValue::new_from_sql(tag_val, data)?,
+            security_level: security_level_val,
+        })
+    }
+
+    /// Get the KeyMint Tag of this this key parameter.
+    pub fn get_tag(&self) -> Tag {
+        self.value.get_tag()
+    }
+
+    /// Returns key parameter value.
+    pub fn key_parameter_value(&self) -> &KeyParameterValue {
+        &self.value
+    }
+
+    /// Returns the security level of this key parameter.
+    pub fn security_level(&self) -> &SecurityLevel {
+        &self.security_level
+    }
+
+    /// An authorization is a KeyParameter with an associated security level that is used
+    /// to convey the key characteristics to keystore clients. This function consumes
+    /// an internal KeyParameter representation to produce the Authorization wire type.
+    pub fn into_authorization(self) -> Authorization {
+        Authorization { securityLevel: self.security_level, keyParameter: self.value.into() }
+    }
+}
+
+#[cfg(test)]
+mod generated_key_parameter_tests {
+    use super::*;
+    use android_hardware_security_keymint::aidl::android::hardware::security::keymint::TagType::TagType;
+
+    fn get_field_by_tag_type(tag: Tag) -> KmKeyParameterValue {
+        let tag_type = TagType((tag.0 as u32 & 0xF0000000) as i32);
+        match tag {
+            Tag::ALGORITHM => return KmKeyParameterValue::Algorithm(Default::default()),
+            Tag::BLOCK_MODE => return KmKeyParameterValue::BlockMode(Default::default()),
+            Tag::PADDING => return KmKeyParameterValue::PaddingMode(Default::default()),
+            Tag::DIGEST => return KmKeyParameterValue::Digest(Default::default()),
+            Tag::EC_CURVE => return KmKeyParameterValue::EcCurve(Default::default()),
+            Tag::ORIGIN => return KmKeyParameterValue::Origin(Default::default()),
+            Tag::PURPOSE => return KmKeyParameterValue::KeyPurpose(Default::default()),
+            Tag::USER_AUTH_TYPE => {
+                return KmKeyParameterValue::HardwareAuthenticatorType(Default::default())
+            }
+            Tag::HARDWARE_TYPE => return KmKeyParameterValue::SecurityLevel(Default::default()),
+            _ => {}
+        }
+        match tag_type {
+            TagType::INVALID => return KmKeyParameterValue::Invalid(Default::default()),
+            TagType::ENUM | TagType::ENUM_REP => {}
+            TagType::UINT | TagType::UINT_REP => {
+                return KmKeyParameterValue::Integer(Default::default())
+            }
+            TagType::ULONG | TagType::ULONG_REP => {
+                return KmKeyParameterValue::LongInteger(Default::default())
+            }
+            TagType::DATE => return KmKeyParameterValue::DateTime(Default::default()),
+            TagType::BOOL => return KmKeyParameterValue::BoolValue(Default::default()),
+            TagType::BIGNUM | TagType::BYTES => {
+                return KmKeyParameterValue::Blob(Default::default())
+            }
+            _ => {}
+        }
+        panic!("Unknown tag/tag_type: {:?} {:?}", tag, tag_type);
+    }
+
+    fn check_field_matches_tag_type(list_o_parameters: &[KmKeyParameter]) {
+        for kp in list_o_parameters.iter() {
+            match (&kp.value, get_field_by_tag_type(kp.tag)) {
+                (&KmKeyParameterValue::Algorithm(_), KmKeyParameterValue::Algorithm(_))
+                | (&KmKeyParameterValue::BlockMode(_), KmKeyParameterValue::BlockMode(_))
+                | (&KmKeyParameterValue::PaddingMode(_), KmKeyParameterValue::PaddingMode(_))
+                | (&KmKeyParameterValue::Digest(_), KmKeyParameterValue::Digest(_))
+                | (&KmKeyParameterValue::EcCurve(_), KmKeyParameterValue::EcCurve(_))
+                | (&KmKeyParameterValue::Origin(_), KmKeyParameterValue::Origin(_))
+                | (&KmKeyParameterValue::KeyPurpose(_), KmKeyParameterValue::KeyPurpose(_))
+                | (
+                    &KmKeyParameterValue::HardwareAuthenticatorType(_),
+                    KmKeyParameterValue::HardwareAuthenticatorType(_),
+                )
+                | (&KmKeyParameterValue::SecurityLevel(_), KmKeyParameterValue::SecurityLevel(_))
+                | (&KmKeyParameterValue::Invalid(_), KmKeyParameterValue::Invalid(_))
+                | (&KmKeyParameterValue::Integer(_), KmKeyParameterValue::Integer(_))
+                | (&KmKeyParameterValue::LongInteger(_), KmKeyParameterValue::LongInteger(_))
+                | (&KmKeyParameterValue::DateTime(_), KmKeyParameterValue::DateTime(_))
+                | (&KmKeyParameterValue::BoolValue(_), KmKeyParameterValue::BoolValue(_))
+                | (&KmKeyParameterValue::Blob(_), KmKeyParameterValue::Blob(_)) => {}
+                (actual, expected) => panic!(
+                    "Tag {:?} associated with variant {:?} expected {:?}",
+                    kp.tag, actual, expected
+                ),
+            }
+        }
+    }
+
+    #[test]
+    fn key_parameter_value_field_matches_tag_type() {
+        check_field_matches_tag_type(&KeyParameterValue::make_field_matches_tag_type_test_vector());
+    }
+}
+
+#[cfg(test)]
+mod basic_tests {
+    use crate::key_parameter::*;
+
+    // Test basic functionality of KeyParameter.
+    #[test]
+    fn test_key_parameter() {
+        let key_parameter = KeyParameter::new(
+            KeyParameterValue::Algorithm(Algorithm::RSA),
+            SecurityLevel::STRONGBOX,
+        );
+
+        assert_eq!(key_parameter.get_tag(), Tag::ALGORITHM);
+
+        assert_eq!(
+            *key_parameter.key_parameter_value(),
+            KeyParameterValue::Algorithm(Algorithm::RSA)
+        );
+
+        assert_eq!(*key_parameter.security_level(), SecurityLevel::STRONGBOX);
+    }
+}
+
+/// The storage_tests module first tests the 'new_from_sql' method for KeyParameters of different
+/// data types and then tests 'to_sql' method for KeyParameters of those
+/// different data types. The five different data types for KeyParameter values are:
+/// i) enums of u32
+/// ii) u32
+/// iii) u64
+/// iv) Vec<u8>
+/// v) bool
+#[cfg(test)]
+mod storage_tests {
+    use crate::error::*;
+    use crate::key_parameter::*;
+    use anyhow::Result;
+    use rusqlite::types::ToSql;
+    use rusqlite::{params, Connection, NO_PARAMS};
+
+    /// Test initializing a KeyParameter (with key parameter value corresponding to an enum of i32)
+    /// from a database table row.
+    #[test]
+    fn test_new_from_sql_enum_i32() -> Result<()> {
+        let db = init_db()?;
+        insert_into_keyparameter(
+            &db,
+            1,
+            Tag::ALGORITHM.0,
+            &Algorithm::RSA.0,
+            SecurityLevel::STRONGBOX.0,
+        )?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(Tag::ALGORITHM, key_param.get_tag());
+        assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::Algorithm(Algorithm::RSA));
+        assert_eq!(*key_param.security_level(), SecurityLevel::STRONGBOX);
+        Ok(())
+    }
+
+    /// Test initializing a KeyParameter (with key parameter value which is of i32)
+    /// from a database table row.
+    #[test]
+    fn test_new_from_sql_i32() -> Result<()> {
+        let db = init_db()?;
+        insert_into_keyparameter(&db, 1, Tag::KEY_SIZE.0, &1024, SecurityLevel::STRONGBOX.0)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(Tag::KEY_SIZE, key_param.get_tag());
+        assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::KeySize(1024));
+        Ok(())
+    }
+
+    /// Test initializing a KeyParameter (with key parameter value which is of i64)
+    /// from a database table row.
+    #[test]
+    fn test_new_from_sql_i64() -> Result<()> {
+        let db = init_db()?;
+        // max value for i64, just to test corner cases
+        insert_into_keyparameter(
+            &db,
+            1,
+            Tag::RSA_PUBLIC_EXPONENT.0,
+            &(i64::MAX),
+            SecurityLevel::STRONGBOX.0,
+        )?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(Tag::RSA_PUBLIC_EXPONENT, key_param.get_tag());
+        assert_eq!(
+            *key_param.key_parameter_value(),
+            KeyParameterValue::RSAPublicExponent(i64::MAX)
+        );
+        Ok(())
+    }
+
+    /// Test initializing a KeyParameter (with key parameter value which is of bool)
+    /// from a database table row.
+    #[test]
+    fn test_new_from_sql_bool() -> Result<()> {
+        let db = init_db()?;
+        insert_into_keyparameter(&db, 1, Tag::CALLER_NONCE.0, &Null, SecurityLevel::STRONGBOX.0)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(Tag::CALLER_NONCE, key_param.get_tag());
+        assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::CallerNonce);
+        Ok(())
+    }
+
+    /// Test initializing a KeyParameter (with key parameter value which is of Vec<u8>)
+    /// from a database table row.
+    #[test]
+    fn test_new_from_sql_vec_u8() -> Result<()> {
+        let db = init_db()?;
+        let app_id = String::from("MyAppID");
+        let app_id_bytes = app_id.into_bytes();
+        insert_into_keyparameter(
+            &db,
+            1,
+            Tag::APPLICATION_ID.0,
+            &app_id_bytes,
+            SecurityLevel::STRONGBOX.0,
+        )?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(Tag::APPLICATION_ID, key_param.get_tag());
+        assert_eq!(
+            *key_param.key_parameter_value(),
+            KeyParameterValue::ApplicationID(app_id_bytes)
+        );
+        Ok(())
+    }
+
+    /// Test storing a KeyParameter (with key parameter value which corresponds to an enum of i32)
+    /// in the database
+    #[test]
+    fn test_to_sql_enum_i32() -> Result<()> {
+        let db = init_db()?;
+        let kp = KeyParameter::new(
+            KeyParameterValue::Algorithm(Algorithm::RSA),
+            SecurityLevel::STRONGBOX,
+        );
+        store_keyparameter(&db, 1, &kp)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(kp.get_tag(), key_param.get_tag());
+        assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
+        assert_eq!(kp.security_level(), key_param.security_level());
+        Ok(())
+    }
+
+    /// Test storing a KeyParameter (with key parameter value which is of i32) in the database
+    #[test]
+    fn test_to_sql_i32() -> Result<()> {
+        let db = init_db()?;
+        let kp = KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::STRONGBOX);
+        store_keyparameter(&db, 1, &kp)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(kp.get_tag(), key_param.get_tag());
+        assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
+        assert_eq!(kp.security_level(), key_param.security_level());
+        Ok(())
+    }
+
+    /// Test storing a KeyParameter (with key parameter value which is of i64) in the database
+    #[test]
+    fn test_to_sql_i64() -> Result<()> {
+        let db = init_db()?;
+        // max value for i64, just to test corner cases
+        let kp = KeyParameter::new(
+            KeyParameterValue::RSAPublicExponent(i64::MAX),
+            SecurityLevel::STRONGBOX,
+        );
+        store_keyparameter(&db, 1, &kp)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(kp.get_tag(), key_param.get_tag());
+        assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
+        assert_eq!(kp.security_level(), key_param.security_level());
+        Ok(())
+    }
+
+    /// Test storing a KeyParameter (with key parameter value which is of Vec<u8>) in the database
+    #[test]
+    fn test_to_sql_vec_u8() -> Result<()> {
+        let db = init_db()?;
+        let kp = KeyParameter::new(
+            KeyParameterValue::ApplicationID(String::from("MyAppID").into_bytes()),
+            SecurityLevel::STRONGBOX,
+        );
+        store_keyparameter(&db, 1, &kp)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(kp.get_tag(), key_param.get_tag());
+        assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
+        assert_eq!(kp.security_level(), key_param.security_level());
+        Ok(())
+    }
+
+    /// Test storing a KeyParameter (with key parameter value which is of i32) in the database
+    #[test]
+    fn test_to_sql_bool() -> Result<()> {
+        let db = init_db()?;
+        let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX);
+        store_keyparameter(&db, 1, &kp)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(kp.get_tag(), key_param.get_tag());
+        assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
+        assert_eq!(kp.security_level(), key_param.security_level());
+        Ok(())
+    }
+
+    #[test]
+    /// Test Tag::Invalid
+    fn test_invalid_tag() -> Result<()> {
+        let db = init_db()?;
+        insert_into_keyparameter(&db, 1, 0, &123, 1)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(Tag::INVALID, key_param.get_tag());
+        Ok(())
+    }
+
+    #[test]
+    fn test_non_existing_enum_variant() -> Result<()> {
+        let db = init_db()?;
+        insert_into_keyparameter(&db, 1, 100, &123, 1)?;
+        let key_param = query_from_keyparameter(&db)?;
+        assert_eq!(Tag::INVALID, key_param.get_tag());
+        Ok(())
+    }
+
+    #[test]
+    fn test_invalid_conversion_from_sql() -> Result<()> {
+        let db = init_db()?;
+        insert_into_keyparameter(&db, 1, Tag::ALGORITHM.0, &Null, 1)?;
+        tests::check_result_contains_error_string(
+            query_from_keyparameter(&db),
+            "Failed to read sql data for tag: ALGORITHM.",
+        );
+        Ok(())
+    }
+
+    /// Helper method to init database table for key parameter
+    fn init_db() -> Result<Connection> {
+        let db = Connection::open_in_memory().context("Failed to initialize sqlite connection.")?;
+        db.execute("ATTACH DATABASE ? as 'persistent';", params![""])
+            .context("Failed to attach databases.")?;
+        db.execute(
+            "CREATE TABLE IF NOT EXISTS persistent.keyparameter (
+                                keyentryid INTEGER,
+                                tag INTEGER,
+                                data ANY,
+                                security_level INTEGER);",
+            NO_PARAMS,
+        )
+        .context("Failed to initialize \"keyparameter\" table.")?;
+        Ok(db)
+    }
+
+    /// Helper method to insert an entry into key parameter table, with individual parameters
+    fn insert_into_keyparameter<T: ToSql>(
+        db: &Connection,
+        key_id: i64,
+        tag: i32,
+        value: &T,
+        security_level: i32,
+    ) -> Result<()> {
+        db.execute(
+            "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
+                VALUES(?, ?, ?, ?);",
+            params![key_id, tag, *value, security_level],
+        )?;
+        Ok(())
+    }
+
+    /// Helper method to store a key parameter instance.
+    fn store_keyparameter(db: &Connection, key_id: i64, kp: &KeyParameter) -> Result<()> {
+        db.execute(
+            "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
+                VALUES(?, ?, ?, ?);",
+            params![key_id, kp.get_tag().0, kp.key_parameter_value(), kp.security_level().0],
+        )?;
+        Ok(())
+    }
+
+    /// Helper method to query a row from keyparameter table
+    fn query_from_keyparameter(db: &Connection) -> Result<KeyParameter> {
+        let mut stmt =
+            db.prepare("SELECT tag, data, security_level FROM persistent.keyparameter")?;
+        let mut rows = stmt.query(NO_PARAMS)?;
+        let row = rows.next()?.unwrap();
+        Ok(KeyParameter::new_from_sql(
+            Tag(row.get(0)?),
+            &SqlField::new(1, row),
+            SecurityLevel(row.get(2)?),
+        )?)
+    }
+}
+
+/// The wire_tests module tests the 'convert_to_wire' and 'convert_from_wire' methods for
+/// KeyParameter, for the four different types used in KmKeyParameter, in addition to Invalid
+/// key parameter.
+/// i) bool
+/// ii) integer
+/// iii) longInteger
+/// iv) blob
+#[cfg(test)]
+mod wire_tests {
+    use crate::key_parameter::*;
+    /// unit tests for to conversions
+    #[test]
+    fn test_convert_to_wire_invalid() {
+        let kp = KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::STRONGBOX);
+        assert_eq!(
+            KmKeyParameter { tag: Tag::INVALID, value: KmKeyParameterValue::Invalid(0) },
+            kp.value.into()
+        );
+    }
+    #[test]
+    fn test_convert_to_wire_bool() {
+        let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX);
+        assert_eq!(
+            KmKeyParameter { tag: Tag::CALLER_NONCE, value: KmKeyParameterValue::BoolValue(true) },
+            kp.value.into()
+        );
+    }
+    #[test]
+    fn test_convert_to_wire_integer() {
+        let kp = KeyParameter::new(
+            KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
+            SecurityLevel::STRONGBOX,
+        );
+        assert_eq!(
+            KmKeyParameter {
+                tag: Tag::PURPOSE,
+                value: KmKeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT)
+            },
+            kp.value.into()
+        );
+    }
+    #[test]
+    fn test_convert_to_wire_long_integer() {
+        let kp =
+            KeyParameter::new(KeyParameterValue::UserSecureID(i64::MAX), SecurityLevel::STRONGBOX);
+        assert_eq!(
+            KmKeyParameter {
+                tag: Tag::USER_SECURE_ID,
+                value: KmKeyParameterValue::LongInteger(i64::MAX)
+            },
+            kp.value.into()
+        );
+    }
+    #[test]
+    fn test_convert_to_wire_blob() {
+        let kp = KeyParameter::new(
+            KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()),
+            SecurityLevel::STRONGBOX,
+        );
+        assert_eq!(
+            KmKeyParameter {
+                tag: Tag::CONFIRMATION_TOKEN,
+                value: KmKeyParameterValue::Blob(String::from("ConfirmationToken").into_bytes())
+            },
+            kp.value.into()
+        );
+    }
+
+    /// unit tests for from conversion
+    #[test]
+    fn test_convert_from_wire_invalid() {
+        let aidl_kp = KmKeyParameter { tag: Tag::INVALID, ..Default::default() };
+        assert_eq!(KeyParameterValue::Invalid, aidl_kp.into());
+    }
+    #[test]
+    fn test_convert_from_wire_bool() {
+        let aidl_kp =
+            KmKeyParameter { tag: Tag::CALLER_NONCE, value: KmKeyParameterValue::BoolValue(true) };
+        assert_eq!(KeyParameterValue::CallerNonce, aidl_kp.into());
+    }
+    #[test]
+    fn test_convert_from_wire_integer() {
+        let aidl_kp = KmKeyParameter {
+            tag: Tag::PURPOSE,
+            value: KmKeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
+        };
+        assert_eq!(KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT), aidl_kp.into());
+    }
+    #[test]
+    fn test_convert_from_wire_long_integer() {
+        let aidl_kp = KmKeyParameter {
+            tag: Tag::USER_SECURE_ID,
+            value: KmKeyParameterValue::LongInteger(i64::MAX),
+        };
+        assert_eq!(KeyParameterValue::UserSecureID(i64::MAX), aidl_kp.into());
+    }
+    #[test]
+    fn test_convert_from_wire_blob() {
+        let aidl_kp = KmKeyParameter {
+            tag: Tag::CONFIRMATION_TOKEN,
+            value: KmKeyParameterValue::Blob(String::from("ConfirmationToken").into_bytes()),
+        };
+        assert_eq!(
+            KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()),
+            aidl_kp.into()
+        );
+    }
+}
diff --git a/keystore2/src/keystore2_main.rs b/keystore2/src/keystore2_main.rs
new file mode 100644
index 0000000..4d4a718
--- /dev/null
+++ b/keystore2/src/keystore2_main.rs
@@ -0,0 +1,150 @@
+// Copyright 2020, 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.
+
+//! This crate implements the Keystore 2.0 service entry point.
+
+use keystore2::entropy;
+use keystore2::globals::ENFORCEMENTS;
+use keystore2::maintenance::Maintenance;
+use keystore2::metrics;
+use keystore2::remote_provisioning::RemoteProvisioningService;
+use keystore2::service::KeystoreService;
+use keystore2::{apc::ApcManager, shared_secret_negotiation};
+use keystore2::{authorization::AuthorizationManager, id_rotation::IdRotationState};
+use log::{error, info};
+use std::{panic, path::Path, sync::mpsc::channel};
+use vpnprofilestore::VpnProfileStore;
+
+static KS2_SERVICE_NAME: &str = "android.system.keystore2.IKeystoreService/default";
+static APC_SERVICE_NAME: &str = "android.security.apc";
+static AUTHORIZATION_SERVICE_NAME: &str = "android.security.authorization";
+static REMOTE_PROVISIONING_SERVICE_NAME: &str = "android.security.remoteprovisioning";
+static USER_MANAGER_SERVICE_NAME: &str = "android.security.maintenance";
+static VPNPROFILESTORE_SERVICE_NAME: &str = "android.security.vpnprofilestore";
+
+/// Keystore 2.0 takes one argument which is a path indicating its designated working directory.
+fn main() {
+    // Initialize android logging.
+    android_logger::init_once(
+        android_logger::Config::default().with_tag("keystore2").with_min_level(log::Level::Debug),
+    );
+    // Redirect panic messages to logcat.
+    panic::set_hook(Box::new(|panic_info| {
+        error!("{}", panic_info);
+    }));
+
+    // Saying hi.
+    info!("Keystore2 is starting.");
+
+    // Initialize the per boot database.
+    let _keep_me_alive = keystore2::database::KeystoreDB::keep_perboot_db_alive()
+        .expect("Failed to initialize the perboot database.");
+
+    let mut args = std::env::args();
+    args.next().expect("That's odd. How is there not even a first argument?");
+
+    // Keystore 2.0 cannot change to the database directory (typically /data/misc/keystore) on
+    // startup as Keystore 1.0 did because Keystore 2.0 is intended to run much earlier than
+    // Keystore 1.0. Instead we set a global variable to the database path.
+    // For the ground truth check the service startup rule for init (typically in keystore2.rc).
+    let id_rotation_state = if let Some(dir) = args.next() {
+        let db_path = Path::new(&dir);
+        *keystore2::globals::DB_PATH.lock().expect("Could not lock DB_PATH.") =
+            db_path.to_path_buf();
+        IdRotationState::new(&db_path)
+    } else {
+        panic!("Must specify a database directory.");
+    };
+
+    let (confirmation_token_sender, confirmation_token_receiver) = channel();
+
+    ENFORCEMENTS.install_confirmation_token_receiver(confirmation_token_receiver);
+
+    entropy::register_feeder();
+    shared_secret_negotiation::perform_shared_secret_negotiation();
+
+    info!("Starting thread pool now.");
+    binder::ProcessState::start_thread_pool();
+
+    let ks_service = KeystoreService::new_native_binder(id_rotation_state).unwrap_or_else(|e| {
+        panic!("Failed to create service {} because of {:?}.", KS2_SERVICE_NAME, e);
+    });
+    binder::add_service(KS2_SERVICE_NAME, ks_service.as_binder()).unwrap_or_else(|e| {
+        panic!("Failed to register service {} because of {:?}.", KS2_SERVICE_NAME, e);
+    });
+
+    let apc_service =
+        ApcManager::new_native_binder(confirmation_token_sender).unwrap_or_else(|e| {
+            panic!("Failed to create service {} because of {:?}.", APC_SERVICE_NAME, e);
+        });
+    binder::add_service(APC_SERVICE_NAME, apc_service.as_binder()).unwrap_or_else(|e| {
+        panic!("Failed to register service {} because of {:?}.", APC_SERVICE_NAME, e);
+    });
+
+    let authorization_service = AuthorizationManager::new_native_binder().unwrap_or_else(|e| {
+        panic!("Failed to create service {} because of {:?}.", AUTHORIZATION_SERVICE_NAME, e);
+    });
+    binder::add_service(AUTHORIZATION_SERVICE_NAME, authorization_service.as_binder())
+        .unwrap_or_else(|e| {
+            panic!("Failed to register service {} because of {:?}.", AUTHORIZATION_SERVICE_NAME, e);
+        });
+
+    let maintenance_service = Maintenance::new_native_binder().unwrap_or_else(|e| {
+        panic!("Failed to create service {} because of {:?}.", USER_MANAGER_SERVICE_NAME, e);
+    });
+    binder::add_service(USER_MANAGER_SERVICE_NAME, maintenance_service.as_binder()).unwrap_or_else(
+        |e| {
+            panic!("Failed to register service {} because of {:?}.", USER_MANAGER_SERVICE_NAME, e);
+        },
+    );
+
+    // Devices with KS2 and KM 1.0 may not have any IRemotelyProvisionedComponent HALs at all. Do
+    // not panic if new_native_binder returns failure because it could not find the TEE HAL.
+    if let Ok(remote_provisioning_service) = RemoteProvisioningService::new_native_binder() {
+        binder::add_service(
+            REMOTE_PROVISIONING_SERVICE_NAME,
+            remote_provisioning_service.as_binder(),
+        )
+        .unwrap_or_else(|e| {
+            panic!(
+                "Failed to register service {} because of {:?}.",
+                REMOTE_PROVISIONING_SERVICE_NAME, e
+            );
+        });
+    }
+
+    let vpnprofilestore = VpnProfileStore::new_native_binder(
+        &keystore2::globals::DB_PATH.lock().expect("Could not get DB_PATH."),
+    );
+    binder::add_service(VPNPROFILESTORE_SERVICE_NAME, vpnprofilestore.as_binder()).unwrap_or_else(
+        |e| {
+            panic!(
+                "Failed to register service {} because of {:?}.",
+                VPNPROFILESTORE_SERVICE_NAME, e
+            );
+        },
+    );
+
+    std::thread::spawn(|| {
+        match metrics::register_pull_metrics_callbacks() {
+            Err(e) => error!("register_pull_metrics_callbacks failed: {:?}.", e),
+            _ => info!("Pull metrics callbacks successfully registered."),
+        };
+    });
+
+    info!("Successfully registered Keystore 2.0 service.");
+
+    info!("Joining thread pool now.");
+    binder::ProcessState::join_thread_pool();
+}
diff --git a/keystore2/src/km_compat/Android.bp b/keystore2/src/km_compat/Android.bp
new file mode 100644
index 0000000..541788e
--- /dev/null
+++ b/keystore2/src/km_compat/Android.bp
@@ -0,0 +1,126 @@
+// Copyright 2020, 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 {
+    // 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",
+    srcs: ["lib.rs"],
+
+    rustlibs: [
+        "android.hardware.security.keymint-V1-rust",
+        "android.security.compat-rust",
+    ],
+    shared_libs: [
+        "libkm_compat_service",
+    ]
+}
+
+rust_test {
+    name: "keystore2_km_compat_test",
+    crate_name: "keystore2",
+    srcs: ["lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    rustlibs: [
+        "android.hardware.security.keymint-V1-rust",
+        "android.security.compat-rust",
+    ],
+    shared_libs: [
+        "libkm_compat_service",
+    ],
+}
+
+cc_library {
+    name: "libkm_compat",
+    srcs: ["km_compat.cpp"],
+    shared_libs: [
+        "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
+        "android.hardware.keymaster@4.1",
+        "android.hardware.security.keymint-V1-ndk_platform",
+        "android.hardware.security.secureclock-V1-ndk_platform",
+        "android.hardware.security.sharedsecret-V1-ndk_platform",
+        "android.security.compat-ndk_platform",
+        "android.system.keystore2-V1-ndk_platform",
+        "libbase",
+        "libbinder_ndk",
+        "libcrypto",
+        "libhidlbase",
+        "libkeymaster4_1support",
+        "libkeymint",
+        "libkeymint_support",
+        "libkeystore2_crypto",
+        "libutils",
+    ],
+}
+
+cc_library {
+    name: "libkm_compat_service",
+    srcs: ["km_compat_service.cpp"],
+    shared_libs: [
+        "android.hardware.security.keymint-V1-ndk_platform",
+        "android.hardware.security.secureclock-V1-ndk_platform",
+        "android.hardware.security.sharedsecret-V1-ndk_platform",
+        "android.security.compat-ndk_platform",
+        "libbinder_ndk",
+        "libcrypto",
+        "libkm_compat",
+        "libkeymaster4_1support",
+        "libkeystore2_crypto",
+    ],
+}
+
+cc_test {
+    name: "keystore2_km_compat_test_cpp",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    srcs: [
+        "certificate_test.cpp",
+        "gtest_main.cpp",
+        "parameter_conversion_test.cpp",
+        "slot_test.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
+        "android.hardware.keymaster@4.1",
+        "android.hardware.security.keymint-V1-ndk_platform",
+        "android.hardware.security.secureclock-V1-ndk_platform",
+        "android.hardware.security.sharedsecret-V1-ndk_platform",
+        "android.security.compat-ndk_platform",
+        "android.system.keystore2-V1-ndk_platform",
+        "libbase",
+        "libbinder_ndk",
+        "libcrypto",
+        "libhidlbase",
+        "libkeymaster4_1support",
+        "libkeymint_support",
+        "libkeystore2_crypto",
+        "libkm_compat",
+        "libkm_compat_service",
+        "libutils",
+    ],
+}
diff --git a/keystore2/src/km_compat/certificate_test.cpp b/keystore2/src/km_compat/certificate_test.cpp
new file mode 100644
index 0000000..06cb0cb
--- /dev/null
+++ b/keystore2/src/km_compat/certificate_test.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2020, 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 <gtest/gtest.h>
+
+#include "km_compat.h"
+#include <keymint_support/keymint_tags.h>
+
+#include <aidl/android/hardware/security/keymint/Algorithm.h>
+#include <aidl/android/hardware/security/keymint/BlockMode.h>
+#include <aidl/android/hardware/security/keymint/Digest.h>
+#include <aidl/android/hardware/security/keymint/PaddingMode.h>
+#include <android/binder_manager.h>
+
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#define DEFINE_OPENSSL_OBJECT_POINTER(name) using name##_Ptr = bssl::UniquePtr<name>
+
+DEFINE_OPENSSL_OBJECT_POINTER(EVP_PKEY);
+DEFINE_OPENSSL_OBJECT_POINTER(X509);
+
+using ::aidl::android::hardware::security::keymint::Algorithm;
+using ::aidl::android::hardware::security::keymint::BlockMode;
+using ::aidl::android::hardware::security::keymint::Certificate;
+using ::aidl::android::hardware::security::keymint::Digest;
+using ::aidl::android::hardware::security::keymint::PaddingMode;
+using ::aidl::android::hardware::security::keymint::SecurityLevel;
+using ::aidl::android::hardware::security::keymint::Tag;
+using ::aidl::android::security::compat::IKeystoreCompatService;
+
+namespace KMV1 = ::aidl::android::hardware::security::keymint;
+
+extern "C" int32_t addKeyMintDeviceService();
+
+static std::variant<std::shared_ptr<IKeyMintDevice>, ScopedAStatus> getDevice() {
+    addKeyMintDeviceService();
+    std::shared_ptr<IKeyMintDevice> device;
+    auto service = IKeystoreCompatService::fromBinder(
+        ndk::SpAIBinder(AServiceManager_getService("android.security.compat")));
+    if (!service) {
+        return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
+    }
+    service->getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT, &device);
+    if (!device) {
+        return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
+    }
+    return device;
+}
+
+static std::variant<std::vector<Certificate>, ScopedAStatus>
+getCertificate(std::shared_ptr<IKeyMintDevice> device, const std::vector<KeyParameter>& keyParams) {
+    KeyCreationResult creationResult;
+    auto status = device->generateKey(keyParams, std::nullopt /* attest_key */, &creationResult);
+    if (!status.isOk()) {
+        return status;
+    }
+    return creationResult.certificateChain;
+}
+
+static void ensureCertChainSize(const std::variant<std::vector<Certificate>, ScopedAStatus>& result,
+                                uint32_t size) {
+    ASSERT_TRUE(std::holds_alternative<std::vector<Certificate>>(result));
+    auto certChain = std::get<std::vector<Certificate>>(result);
+    ASSERT_EQ(certChain.size(), size);
+}
+
+static void verify(const Certificate& certificate) {
+    const uint8_t* p = certificate.encodedCertificate.data();
+    X509_Ptr decoded_cert(d2i_X509(nullptr, &p, (long)certificate.encodedCertificate.size()));
+    EVP_PKEY_Ptr decoded_pkey(X509_get_pubkey(decoded_cert.get()));
+    ASSERT_TRUE(X509_verify(decoded_cert.get(), decoded_pkey.get()));
+}
+
+static std::vector<KeyParameter> getRSAKeyParams(const std::vector<KeyParameter>& extraParams) {
+    auto keyParams = std::vector<KeyParameter>({
+        KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, Algorithm::RSA),
+        KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, 2048),
+        KMV1::makeKeyParameter(KMV1::TAG_RSA_PUBLIC_EXPONENT, 65537),
+        KMV1::makeKeyParameter(KMV1::TAG_CERTIFICATE_NOT_BEFORE, 0),
+        KMV1::makeKeyParameter(KMV1::TAG_CERTIFICATE_NOT_AFTER, 253402300799000),
+    });
+    keyParams.insert(keyParams.end(), extraParams.begin(), extraParams.end());
+    return keyParams;
+}
+
+TEST(CertificateTest, TestRSAKeygen) {
+    auto keyParams = getRSAKeyParams({
+        KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
+        KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
+        KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED),
+        KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
+    });
+    auto device = getDevice();
+    if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
+        auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
+        ensureCertChainSize(result, 1);
+    }
+}
+
+TEST(CertificateTest, TestAES) {
+    auto keyParams = {
+        KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, Algorithm::AES),
+        KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, 128),
+        KMV1::makeKeyParameter(KMV1::TAG_BLOCK_MODE, BlockMode::CBC),
+        KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::NONE),
+        KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::ENCRYPT),
+    };
+    auto device = getDevice();
+    if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
+        auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
+        ensureCertChainSize(result, 0);
+    }
+}
+
+TEST(CertificateTest, TestAttestation) {
+    auto keyParams = getRSAKeyParams({
+        KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
+        KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_CHALLENGE, 42),
+        KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_APPLICATION_ID, 42),
+    });
+    auto device = getDevice();
+    if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
+        auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
+        ensureCertChainSize(result, 3);
+        verify(std::get<std::vector<Certificate>>(result).back());
+    }
+}
+
+TEST(CertificateTest, TestRSAKeygenNoEncryptNoAuthRequired) {
+    auto keyParams = getRSAKeyParams({
+        KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
+        KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
+        KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED, true),
+        KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
+    });
+    auto device = getDevice();
+    if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
+        auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
+        ensureCertChainSize(result, 1);
+        verify(std::get<std::vector<Certificate>>(result)[0]);
+    }
+}
+
+TEST(CertificateTest, TestRSAKeygenNoEncryptAuthRequired) {
+    auto keyParams = getRSAKeyParams({
+        KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
+        KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::RSA_PSS),
+        KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
+    });
+    auto device = getDevice();
+    if (std::holds_alternative<std::shared_ptr<IKeyMintDevice>>(device)) {
+        auto result = getCertificate(std::get<std::shared_ptr<IKeyMintDevice>>(device), keyParams);
+        ensureCertChainSize(result, 1);
+    }
+}
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/keystore2/src/km_compat/gtest_main.cpp
similarity index 74%
copy from keystore/binder/android/security/keymaster/OperationResult.aidl
copy to keystore2/src/km_compat/gtest_main.cpp
index db689d4..149cbbc 100644
--- a/keystore/binder/android/security/keymaster/OperationResult.aidl
+++ b/keystore2/src/km_compat/gtest_main.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-package android.security.keymaster;
-
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
+#include <gtest/gtest.h>
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
new file mode 100644
index 0000000..bdc3f2a
--- /dev/null
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -0,0 +1,1386 @@
+/*
+ * Copyright (C) 2020 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 "km_compat.h"
+
+#include "km_compat_type_conversion.h"
+#include <AndroidKeyMintDevice.h>
+#include <aidl/android/hardware/security/keymint/Algorithm.h>
+#include <aidl/android/hardware/security/keymint/Digest.h>
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
+#include <aidl/android/hardware/security/keymint/KeyParameterValue.h>
+#include <aidl/android/hardware/security/keymint/PaddingMode.h>
+#include <aidl/android/system/keystore2/ResponseCode.h>
+#include <android-base/logging.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <binder/IServiceManager.h>
+#include <hardware/keymaster_defs.h>
+#include <keymasterV4_1/Keymaster.h>
+#include <keymasterV4_1/Keymaster3.h>
+#include <keymasterV4_1/Keymaster4.h>
+
+#include <chrono>
+
+#include "certificate_utils.h"
+
+using ::aidl::android::hardware::security::keymint::Algorithm;
+using ::aidl::android::hardware::security::keymint::CreateKeyMintDevice;
+using ::aidl::android::hardware::security::keymint::Digest;
+using ::aidl::android::hardware::security::keymint::KeyParameterValue;
+using ::aidl::android::hardware::security::keymint::PaddingMode;
+using ::aidl::android::hardware::security::keymint::Tag;
+using ::aidl::android::system::keystore2::ResponseCode;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::keymaster::V4_0::TagType;
+using ::android::hidl::manager::V1_2::IServiceManager;
+using V4_0_HardwareAuthToken = ::android::hardware::keymaster::V4_0::HardwareAuthToken;
+using V4_0_HmacSharingParameters = ::android::hardware::keymaster::V4_0::HmacSharingParameters;
+using V4_0_KeyCharacteristics = ::android::hardware::keymaster::V4_0::KeyCharacteristics;
+using V4_0_KeyFormat = ::android::hardware::keymaster::V4_0::KeyFormat;
+using V4_0_KeyParameter = ::android::hardware::keymaster::V4_0::KeyParameter;
+using V4_0_VerificationToken = ::android::hardware::keymaster::V4_0::VerificationToken;
+namespace V4_0 = ::android::hardware::keymaster::V4_0;
+namespace V4_1 = ::android::hardware::keymaster::V4_1;
+namespace KMV1 = ::aidl::android::hardware::security::keymint;
+
+using namespace std::chrono_literals;
+using std::chrono::duration_cast;
+
+// Utility functions
+
+// Returns true if this parameter may be passed to attestKey.
+bool isAttestationParameter(const KMV1::KeyParameter& param) {
+    switch (param.tag) {
+    case Tag::APPLICATION_ID:
+    case Tag::APPLICATION_DATA:
+    case Tag::ATTESTATION_CHALLENGE:
+    case Tag::ATTESTATION_APPLICATION_ID:
+    case Tag::ATTESTATION_ID_BRAND:
+    case Tag::ATTESTATION_ID_DEVICE:
+    case Tag::ATTESTATION_ID_PRODUCT:
+    case Tag::ATTESTATION_ID_SERIAL:
+    case Tag::ATTESTATION_ID_IMEI:
+    case Tag::ATTESTATION_ID_MEID:
+    case Tag::ATTESTATION_ID_MANUFACTURER:
+    case Tag::ATTESTATION_ID_MODEL:
+    case Tag::CERTIFICATE_SERIAL:
+    case Tag::CERTIFICATE_SUBJECT:
+    case Tag::CERTIFICATE_NOT_BEFORE:
+    case Tag::CERTIFICATE_NOT_AFTER:
+    case Tag::INCLUDE_UNIQUE_ID:
+    case Tag::DEVICE_UNIQUE_ATTESTATION:
+        return true;
+    default:
+        return false;
+    }
+}
+
+// Returns true if this parameter may be passed to generate/importKey.
+bool isKeyCreationParameter(const KMV1::KeyParameter& param) {
+    switch (param.tag) {
+    case Tag::APPLICATION_ID:
+    case Tag::APPLICATION_DATA:
+    case Tag::CERTIFICATE_SERIAL:
+    case Tag::CERTIFICATE_SUBJECT:
+    case Tag::CERTIFICATE_NOT_BEFORE:
+    case Tag::CERTIFICATE_NOT_AFTER:
+    case Tag::PURPOSE:
+    case Tag::ALGORITHM:
+    case Tag::KEY_SIZE:
+    case Tag::BLOCK_MODE:
+    case Tag::DIGEST:
+    case Tag::PADDING:
+    case Tag::CALLER_NONCE:
+    case Tag::MIN_MAC_LENGTH:
+    case Tag::EC_CURVE:
+    case Tag::RSA_PUBLIC_EXPONENT:
+    case Tag::RSA_OAEP_MGF_DIGEST:
+    case Tag::BOOTLOADER_ONLY:
+    case Tag::ROLLBACK_RESISTANCE:
+    case Tag::EARLY_BOOT_ONLY:
+    case Tag::ACTIVE_DATETIME:
+    case Tag::ORIGINATION_EXPIRE_DATETIME:
+    case Tag::USAGE_EXPIRE_DATETIME:
+    case Tag::MIN_SECONDS_BETWEEN_OPS:
+    case Tag::MAX_USES_PER_BOOT:
+    case Tag::USAGE_COUNT_LIMIT:
+    case Tag::USER_ID:
+    case Tag::USER_SECURE_ID:
+    case Tag::NO_AUTH_REQUIRED:
+    case Tag::USER_AUTH_TYPE:
+    case Tag::AUTH_TIMEOUT:
+    case Tag::ALLOW_WHILE_ON_BODY:
+    case Tag::TRUSTED_USER_PRESENCE_REQUIRED:
+    case Tag::TRUSTED_CONFIRMATION_REQUIRED:
+    case Tag::UNLOCKED_DEVICE_REQUIRED:
+    case Tag::CREATION_DATETIME:
+    case Tag::UNIQUE_ID:
+    case Tag::IDENTITY_CREDENTIAL_KEY:
+    case Tag::STORAGE_KEY:
+    case Tag::MAC_LENGTH:
+        return true;
+    default:
+        return false;
+    }
+}
+
+// Size of prefix for blobs, see keyBlobPrefix().
+//
+const size_t kKeyBlobPrefixSize = 8;
+
+// Magic used in blob prefix, see keyBlobPrefix().
+//
+const uint8_t kKeyBlobMagic[7] = {'p', 'K', 'M', 'b', 'l', 'o', 'b'};
+
+// Prefixes a keyblob returned by e.g. generateKey() with information on whether it
+// originated from the real underlying KeyMaster HAL or from soft-KeyMint.
+//
+// When dealing with a keyblob, use prefixedKeyBlobRemovePrefix() to remove the
+// prefix and prefixedKeyBlobIsSoftKeyMint() to determine its origin.
+//
+// Note how the prefix itself has a magic marker ("pKMblob") which can be used
+// to identify if a blob has a prefix at all (it's assumed that any valid blob
+// from KeyMint or KeyMaster HALs never starts with the magic). This is needed
+// because blobs persisted to disk prior to using this code will not have the
+// prefix and in that case we want prefixedKeyBlobRemovePrefix() to still work.
+//
+std::vector<uint8_t> keyBlobPrefix(const std::vector<uint8_t>& blob, bool isSoftKeyMint) {
+    std::vector<uint8_t> result;
+    result.reserve(blob.size() + kKeyBlobPrefixSize);
+    result.insert(result.begin(), kKeyBlobMagic, kKeyBlobMagic + sizeof kKeyBlobMagic);
+    result.push_back(isSoftKeyMint ? 1 : 0);
+    std::copy(blob.begin(), blob.end(), std::back_inserter(result));
+    return result;
+}
+
+// Helper for prefixedKeyBlobRemovePrefix() and prefixedKeyBlobIsSoftKeyMint().
+//
+// First bool is whether there's a valid prefix. If there is, the second bool is
+// the |isSoftKeyMint| value of the prefix
+//
+std::pair<bool, bool> prefixedKeyBlobParsePrefix(const std::vector<uint8_t>& prefixedBlob) {
+    // Having a unprefixed blob is not that uncommon, for example all devices
+    // upgrading to keystore2 (so e.g. upgrading to Android 12) will have
+    // unprefixed blobs. So don't spew warnings/errors in this case...
+    if (prefixedBlob.size() < kKeyBlobPrefixSize) {
+        return std::make_pair(false, false);
+    }
+    if (std::memcmp(prefixedBlob.data(), kKeyBlobMagic, sizeof kKeyBlobMagic) != 0) {
+        return std::make_pair(false, false);
+    }
+    if (prefixedBlob[kKeyBlobPrefixSize - 1] != 0 && prefixedBlob[kKeyBlobPrefixSize - 1] != 1) {
+        return std::make_pair(false, false);
+    }
+    bool isSoftKeyMint = (prefixedBlob[kKeyBlobPrefixSize - 1] == 1);
+    return std::make_pair(true, isSoftKeyMint);
+}
+
+// Returns the prefix from a blob. If there's no prefix, returns the passed-in blob.
+//
+std::vector<uint8_t> prefixedKeyBlobRemovePrefix(const std::vector<uint8_t>& prefixedBlob) {
+    auto parsed = prefixedKeyBlobParsePrefix(prefixedBlob);
+    if (!parsed.first) {
+        // Not actually prefixed, blob was probably persisted to disk prior to the
+        // prefixing code being introduced.
+        return prefixedBlob;
+    }
+    return std::vector<uint8_t>(prefixedBlob.begin() + kKeyBlobPrefixSize, prefixedBlob.end());
+}
+
+// Returns true if the blob's origin is soft-KeyMint, false otherwise or if there
+// is no prefix on the passed-in blob.
+//
+bool prefixedKeyBlobIsSoftKeyMint(const std::vector<uint8_t>& prefixedBlob) {
+    auto parsed = prefixedKeyBlobParsePrefix(prefixedBlob);
+    return parsed.second;
+}
+
+/*
+ * Returns true if the parameter is not understood by KM 4.1 and older but can be enforced by
+ * Keystore. These parameters need to be included in the returned KeyCharacteristics, but will not
+ * be passed to the legacy backend.
+ */
+bool isNewAndKeystoreEnforceable(const KMV1::KeyParameter& param) {
+    switch (param.tag) {
+    case KMV1::Tag::MAX_BOOT_LEVEL:
+        return true;
+    case KMV1::Tag::USAGE_COUNT_LIMIT:
+        return true;
+    default:
+        return false;
+    }
+}
+
+std::vector<KMV1::KeyParameter>
+extractGenerationParams(const std::vector<KMV1::KeyParameter>& params) {
+    std::vector<KMV1::KeyParameter> result;
+    std::copy_if(params.begin(), params.end(), std::back_inserter(result), isKeyCreationParameter);
+    return result;
+}
+
+std::vector<KMV1::KeyParameter>
+extractAttestationParams(const std::vector<KMV1::KeyParameter>& params) {
+    std::vector<KMV1::KeyParameter> result;
+    std::copy_if(params.begin(), params.end(), std::back_inserter(result), isAttestationParameter);
+    return result;
+}
+
+std::vector<KMV1::KeyParameter>
+extractNewAndKeystoreEnforceableParams(const std::vector<KMV1::KeyParameter>& params) {
+    std::vector<KMV1::KeyParameter> result;
+    std::copy_if(params.begin(), params.end(), std::back_inserter(result),
+                 isNewAndKeystoreEnforceable);
+    return result;
+}
+
+ScopedAStatus convertErrorCode(KMV1::ErrorCode result) {
+    if (result == KMV1::ErrorCode::OK) {
+        return ScopedAStatus::ok();
+    }
+    return ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(result));
+}
+
+// Converts a V4 error code into a ScopedAStatus
+ScopedAStatus convertErrorCode(V4_0_ErrorCode result) {
+    return convertErrorCode(convert(result));
+}
+
+static KMV1::ErrorCode toErrorCode(const ScopedAStatus& status) {
+    if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+        return static_cast<KMV1::ErrorCode>(status.getServiceSpecificError());
+    } else {
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+}
+
+static std::vector<V4_0::KeyParameter>
+convertKeyParametersToLegacy(const std::vector<KeyParameter>& kps) {
+    std::vector<V4_0::KeyParameter> legacyKps;
+    legacyKps.reserve(kps.size());
+    for (const auto& kp : kps) {
+        auto p = convertKeyParameterToLegacy(kp);
+        if (p.tag != V4_0::Tag::INVALID) {
+            legacyKps.push_back(std::move(p));
+        }
+    }
+    return legacyKps;
+}
+
+static std::vector<KeyParameter>
+convertKeyParametersFromLegacy(const std::vector<V4_0_KeyParameter>& legacyKps) {
+    std::vector<KeyParameter> kps(legacyKps.size());
+    std::transform(legacyKps.begin(), legacyKps.end(), kps.begin(), convertKeyParameterFromLegacy);
+    return kps;
+}
+
+static std::vector<KeyCharacteristics>
+processLegacyCharacteristics(KeyMintSecurityLevel securityLevel,
+                             const std::vector<KeyParameter>& genParams,
+                             const V4_0_KeyCharacteristics& legacyKc) {
+
+    KeyCharacteristics keystoreEnforced{KeyMintSecurityLevel::KEYSTORE,
+                                        convertKeyParametersFromLegacy(legacyKc.softwareEnforced)};
+
+    // Add all parameters that we know can be enforced by keystore but not by the legacy backend.
+    auto unsupported_requested = extractNewAndKeystoreEnforceableParams(genParams);
+    std::copy(unsupported_requested.begin(), unsupported_requested.end(),
+              std::back_insert_iterator(keystoreEnforced.authorizations));
+
+    if (securityLevel == KeyMintSecurityLevel::SOFTWARE) {
+        // If the security level of the backend is `software` we expect the hardware enforced list
+        // to be empty. Log a warning otherwise.
+        if (legacyKc.hardwareEnforced.size() != 0) {
+            LOG(WARNING) << "Unexpected hardware enforced parameters.";
+        }
+        return {keystoreEnforced};
+    }
+
+    KeyCharacteristics hwEnforced{securityLevel,
+                                  convertKeyParametersFromLegacy(legacyKc.hardwareEnforced)};
+    return {hwEnforced, keystoreEnforced};
+}
+
+static V4_0_KeyFormat convertKeyFormatToLegacy(const KeyFormat& kf) {
+    return static_cast<V4_0_KeyFormat>(kf);
+}
+
+static V4_0_HardwareAuthToken convertAuthTokenToLegacy(const std::optional<HardwareAuthToken>& at) {
+    if (!at) return {};
+
+    V4_0_HardwareAuthToken legacyAt;
+    legacyAt.challenge = at->challenge;
+    legacyAt.userId = at->userId;
+    legacyAt.authenticatorId = at->authenticatorId;
+    legacyAt.authenticatorType =
+        static_cast<::android::hardware::keymaster::V4_0::HardwareAuthenticatorType>(
+            at->authenticatorType);
+    legacyAt.timestamp = at->timestamp.milliSeconds;
+    legacyAt.mac = at->mac;
+    return legacyAt;
+}
+
+static V4_0_VerificationToken
+convertTimestampTokenToLegacy(const std::optional<TimeStampToken>& tst) {
+    if (!tst) return {};
+
+    V4_0_VerificationToken legacyVt;
+    legacyVt.challenge = tst->challenge;
+    legacyVt.timestamp = tst->timestamp.milliSeconds;
+    // Legacy verification tokens were always minted by TEE.
+    legacyVt.securityLevel = V4_0::SecurityLevel::TRUSTED_ENVIRONMENT;
+    legacyVt.mac = tst->mac;
+    return legacyVt;
+}
+
+static V4_0_HmacSharingParameters
+convertSharedSecretParameterToLegacy(const SharedSecretParameters& ssp) {
+    V4_0_HmacSharingParameters legacyHsp;
+    legacyHsp.seed = ssp.seed;
+    std::copy(ssp.nonce.begin(), ssp.nonce.end(), legacyHsp.nonce.data());
+    return legacyHsp;
+}
+
+static std::vector<V4_0_HmacSharingParameters>
+convertSharedSecretParametersToLegacy(const std::vector<SharedSecretParameters>& legacySsps) {
+    std::vector<V4_0_HmacSharingParameters> ssps(legacySsps.size());
+    std::transform(legacySsps.begin(), legacySsps.end(), ssps.begin(),
+                   convertSharedSecretParameterToLegacy);
+    return ssps;
+}
+
+void OperationSlots::setNumFreeSlots(uint8_t numFreeSlots) {
+    std::lock_guard<std::mutex> lock(mNumFreeSlotsMutex);
+    mNumFreeSlots = numFreeSlots;
+}
+
+bool OperationSlots::claimSlot() {
+    std::lock_guard<std::mutex> lock(mNumFreeSlotsMutex);
+    if (mNumFreeSlots > 0) {
+        mNumFreeSlots--;
+        return true;
+    }
+    return false;
+}
+
+void OperationSlots::freeSlot() {
+    std::lock_guard<std::mutex> lock(mNumFreeSlotsMutex);
+    mNumFreeSlots++;
+}
+
+void OperationSlot::freeSlot() {
+    if (mIsActive) {
+        mOperationSlots->freeSlot();
+        mIsActive = false;
+    }
+}
+
+// KeyMintDevice implementation
+
+ScopedAStatus KeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* _aidl_return) {
+    auto result = mDevice->halVersion();
+    _aidl_return->versionNumber = result.majorVersion * 10 + result.minorVersion;
+    securityLevel_ = convert(result.securityLevel);
+    _aidl_return->securityLevel = securityLevel_;
+    _aidl_return->keyMintName = result.keymasterName;
+    _aidl_return->keyMintAuthorName = result.authorName;
+    _aidl_return->timestampTokenRequired = securityLevel_ == KMV1::SecurityLevel::STRONGBOX;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus KeyMintDevice::addRngEntropy(const std::vector<uint8_t>& in_data) {
+    auto result = mDevice->addRngEntropy(in_data);
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    return convertErrorCode(result);
+}
+
+ScopedAStatus KeyMintDevice::generateKey(const std::vector<KeyParameter>& inKeyParams,
+                                         const std::optional<AttestationKey>& in_attestationKey,
+                                         KeyCreationResult* out_creationResult) {
+
+    // Since KeyMaster doesn't support ECDH, route all key creation requests to
+    // soft-KeyMint if and only an ECDH key is requested.
+    //
+    // For this to work we'll need to also route begin() and deleteKey() calls to
+    // soft-KM. In order to do that, we'll prefix all keyblobs with whether it was
+    // created by the real underlying KeyMaster HAL or whether it was created by
+    // soft-KeyMint.
+    //
+    // See keyBlobPrefix() for more discussion.
+    //
+    for (const auto& keyParam : inKeyParams) {
+        if (keyParam.tag == Tag::PURPOSE &&
+            keyParam.value.get<KeyParameterValue::Tag::keyPurpose>() == KeyPurpose::AGREE_KEY) {
+            auto ret =
+                softKeyMintDevice_->generateKey(inKeyParams, in_attestationKey, out_creationResult);
+            if (ret.isOk()) {
+                out_creationResult->keyBlob = keyBlobPrefix(out_creationResult->keyBlob, true);
+            }
+            return ret;
+        }
+    }
+
+    auto legacyKeyGenParams = convertKeyParametersToLegacy(extractGenerationParams(inKeyParams));
+    KMV1::ErrorCode errorCode;
+    auto result = mDevice->generateKey(
+        legacyKeyGenParams, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+                                const V4_0_KeyCharacteristics& keyCharacteristics) {
+            errorCode = convert(error);
+            out_creationResult->keyBlob = keyBlobPrefix(keyBlob, false);
+            out_creationResult->keyCharacteristics =
+                processLegacyCharacteristics(securityLevel_, inKeyParams, keyCharacteristics);
+        });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    if (errorCode == KMV1::ErrorCode::OK) {
+        auto cert = getCertificate(inKeyParams, out_creationResult->keyBlob);
+        if (std::holds_alternative<KMV1::ErrorCode>(cert)) {
+            auto code = std::get<KMV1::ErrorCode>(cert);
+            // We return OK in successful cases that do not generate a certificate.
+            if (code != KMV1::ErrorCode::OK) {
+                errorCode = code;
+                deleteKey(out_creationResult->keyBlob);
+            }
+        } else {
+            out_creationResult->certificateChain = std::get<std::vector<Certificate>>(cert);
+        }
+    }
+    return convertErrorCode(errorCode);
+}
+
+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);
+    KMV1::ErrorCode errorCode;
+    auto result = mDevice->importKey(legacyKeyGENParams, legacyKeyFormat, in_inKeyData,
+                                     [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+                                         const V4_0_KeyCharacteristics& keyCharacteristics) {
+                                         errorCode = convert(error);
+                                         out_creationResult->keyBlob =
+                                             keyBlobPrefix(keyBlob, false);
+                                         out_creationResult->keyCharacteristics =
+                                             processLegacyCharacteristics(
+                                                 securityLevel_, inKeyParams, keyCharacteristics);
+                                     });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    if (errorCode == KMV1::ErrorCode::OK) {
+        auto cert = getCertificate(inKeyParams, out_creationResult->keyBlob);
+        if (std::holds_alternative<KMV1::ErrorCode>(cert)) {
+            auto code = std::get<KMV1::ErrorCode>(cert);
+            // We return OK in successful cases that do not generate a certificate.
+            if (code != KMV1::ErrorCode::OK) {
+                errorCode = code;
+                deleteKey(out_creationResult->keyBlob);
+            }
+        } else {
+            out_creationResult->certificateChain = std::get<std::vector<Certificate>>(cert);
+        }
+    }
+    return convertErrorCode(errorCode);
+}
+
+ScopedAStatus
+KeyMintDevice::importWrappedKey(const std::vector<uint8_t>& in_inWrappedKeyData,
+                                const std::vector<uint8_t>& in_inPrefixedWrappingKeyBlob,
+                                const std::vector<uint8_t>& in_inMaskingKey,
+                                const std::vector<KeyParameter>& in_inUnwrappingParams,
+                                int64_t in_inPasswordSid, int64_t in_inBiometricSid,
+                                KeyCreationResult* out_creationResult) {
+    const std::vector<uint8_t>& wrappingKeyBlob =
+        prefixedKeyBlobRemovePrefix(in_inPrefixedWrappingKeyBlob);
+    if (prefixedKeyBlobIsSoftKeyMint(in_inPrefixedWrappingKeyBlob)) {
+        return softKeyMintDevice_->importWrappedKey(
+            in_inWrappedKeyData, wrappingKeyBlob, in_inMaskingKey, in_inUnwrappingParams,
+            in_inPasswordSid, in_inBiometricSid, out_creationResult);
+    }
+
+    auto legacyUnwrappingParams = convertKeyParametersToLegacy(in_inUnwrappingParams);
+    KMV1::ErrorCode errorCode;
+    auto result = mDevice->importWrappedKey(
+        in_inWrappedKeyData, wrappingKeyBlob, in_inMaskingKey, legacyUnwrappingParams,
+        in_inPasswordSid, in_inBiometricSid,
+        [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+            const V4_0_KeyCharacteristics& keyCharacteristics) {
+            errorCode = convert(error);
+            out_creationResult->keyBlob = keyBlobPrefix(keyBlob, false);
+            out_creationResult->keyCharacteristics =
+                processLegacyCharacteristics(securityLevel_, {}, keyCharacteristics);
+        });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    return convertErrorCode(errorCode);
+}
+
+ScopedAStatus KeyMintDevice::upgradeKey(const std::vector<uint8_t>& in_inKeyBlobToUpgrade,
+                                        const std::vector<KeyParameter>& in_inUpgradeParams,
+                                        std::vector<uint8_t>* _aidl_return) {
+    auto legacyUpgradeParams = convertKeyParametersToLegacy(in_inUpgradeParams);
+    V4_0_ErrorCode errorCode;
+
+    auto result =
+        mDevice->upgradeKey(prefixedKeyBlobRemovePrefix(in_inKeyBlobToUpgrade), legacyUpgradeParams,
+                            [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& upgradedKeyBlob) {
+                                errorCode = error;
+                                *_aidl_return = keyBlobPrefix(upgradedKeyBlob, false);
+                            });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    return convertErrorCode(errorCode);
+}
+
+ScopedAStatus KeyMintDevice::deleteKey(const std::vector<uint8_t>& prefixedKeyBlob) {
+    const std::vector<uint8_t>& keyBlob = prefixedKeyBlobRemovePrefix(prefixedKeyBlob);
+    if (prefixedKeyBlobIsSoftKeyMint(prefixedKeyBlob)) {
+        return softKeyMintDevice_->deleteKey(keyBlob);
+    }
+
+    auto result = mDevice->deleteKey(keyBlob);
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    return convertErrorCode(result);
+}
+
+ScopedAStatus KeyMintDevice::deleteAllKeys() {
+    auto result = mDevice->deleteAllKeys();
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    return convertErrorCode(result);
+}
+
+// We're not implementing this.
+ScopedAStatus KeyMintDevice::destroyAttestationIds() {
+    return ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(V4_0_ErrorCode::UNIMPLEMENTED));
+}
+
+ScopedAStatus KeyMintDevice::begin(KeyPurpose in_inPurpose,
+                                   const std::vector<uint8_t>& prefixedKeyBlob,
+                                   const std::vector<KeyParameter>& in_inParams,
+                                   const std::optional<HardwareAuthToken>& in_inAuthToken,
+                                   BeginResult* _aidl_return) {
+    if (!mOperationSlots.claimSlot()) {
+        return convertErrorCode(V4_0_ErrorCode::TOO_MANY_OPERATIONS);
+    }
+
+    const std::vector<uint8_t>& in_inKeyBlob = prefixedKeyBlobRemovePrefix(prefixedKeyBlob);
+    if (prefixedKeyBlobIsSoftKeyMint(prefixedKeyBlob)) {
+        return softKeyMintDevice_->begin(in_inPurpose, in_inKeyBlob, in_inParams, in_inAuthToken,
+                                         _aidl_return);
+    }
+
+    auto legacyPurpose =
+        static_cast<::android::hardware::keymaster::V4_0::KeyPurpose>(in_inPurpose);
+    auto legacyParams = convertKeyParametersToLegacy(in_inParams);
+    auto legacyAuthToken = convertAuthTokenToLegacy(in_inAuthToken);
+    KMV1::ErrorCode errorCode;
+    auto result = mDevice->begin(
+        legacyPurpose, in_inKeyBlob, legacyParams, legacyAuthToken,
+        [&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams,
+            uint64_t operationHandle) {
+            errorCode = convert(error);
+            _aidl_return->challenge = operationHandle;
+            _aidl_return->params = convertKeyParametersFromLegacy(outParams);
+            _aidl_return->operation = ndk::SharedRefBase::make<KeyMintOperation>(
+                mDevice, operationHandle, &mOperationSlots, error == V4_0_ErrorCode::OK);
+        });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    if (errorCode != KMV1::ErrorCode::OK) {
+        mOperationSlots.freeSlot();
+    }
+    return convertErrorCode(errorCode);
+}
+
+ScopedAStatus KeyMintDevice::deviceLocked(bool passwordOnly,
+                                          const std::optional<TimeStampToken>& timestampToken) {
+    V4_0_VerificationToken token;
+    if (timestampToken.has_value()) {
+        token = convertTimestampTokenToLegacy(timestampToken.value());
+    }
+    auto ret = mDevice->deviceLocked(passwordOnly, token);
+    if (!ret.isOk()) {
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    } else {
+        return convertErrorCode(KMV1::ErrorCode::OK);
+    }
+}
+
+ScopedAStatus KeyMintDevice::earlyBootEnded() {
+    auto ret = mDevice->earlyBootEnded();
+    if (!ret.isOk()) {
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    } else {
+        return convertErrorCode(KMV1::ErrorCode::OK);
+    }
+}
+
+ScopedAStatus
+KeyMintDevice::convertStorageKeyToEphemeral(const std::vector<uint8_t>& prefixedStorageKeyBlob,
+                                            std::vector<uint8_t>* ephemeralKeyBlob) {
+    KMV1::ErrorCode km_error;
+
+    /*
+     * Wrapped storage keys cannot be emulated (and they don't need to, because if a platform
+     * supports wrapped storage keys, then the legacy backend will support it too. So error out
+     * if the wrapped storage key given is a soft keymint key.
+     */
+    if (prefixedKeyBlobIsSoftKeyMint(prefixedStorageKeyBlob)) {
+        return convertErrorCode(KMV1::ErrorCode::UNIMPLEMENTED);
+    }
+
+    const std::vector<uint8_t>& storageKeyBlob =
+        prefixedKeyBlobRemovePrefix(prefixedStorageKeyBlob);
+
+    auto hidlCb = [&](V4_0_ErrorCode ret, const hidl_vec<uint8_t>& exportedKeyBlob) {
+        km_error = convert(ret);
+        if (km_error != KMV1::ErrorCode::OK) return;
+        /*
+         * This must return the blob without the prefix since it will be used directly
+         * as a storage encryption key. But this is alright, since this wrapped ephemeral
+         * key shouldn't/won't ever be used with keymint.
+         */
+        *ephemeralKeyBlob = exportedKeyBlob;
+    };
+
+    auto ret = mDevice->exportKey(V4_0_KeyFormat::RAW, storageKeyBlob, {}, {}, hidlCb);
+    if (!ret.isOk()) {
+        LOG(ERROR) << __func__ << " export_key failed: " << ret.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    if (km_error != KMV1::ErrorCode::OK)
+        LOG(ERROR) << __func__ << " export_key failed, code " << int32_t(km_error);
+
+    return convertErrorCode(km_error);
+}
+
+ScopedAStatus
+KeyMintDevice::getKeyCharacteristics(const std::vector<uint8_t>& /* storageKeyBlob */,
+                                     const std::vector<uint8_t>& /* appId */,
+                                     const std::vector<uint8_t>& /* appData */,
+                                     std::vector<KeyCharacteristics>* /* keyCharacteristics */) {
+    return convertErrorCode(KMV1::ErrorCode::UNIMPLEMENTED);
+}
+
+ScopedAStatus KeyMintOperation::updateAad(const std::vector<uint8_t>& input,
+                                          const std::optional<HardwareAuthToken>& optAuthToken,
+                                          const std::optional<TimeStampToken>& optTimeStampToken) {
+    V4_0_HardwareAuthToken authToken = convertAuthTokenToLegacy(optAuthToken);
+    V4_0_VerificationToken verificationToken = convertTimestampTokenToLegacy(optTimeStampToken);
+
+    KMV1::ErrorCode errorCode;
+    auto result = mDevice->update(
+        mOperationHandle, {V4_0::makeKeyParameter(V4_0::TAG_ASSOCIATED_DATA, input)}, {}, authToken,
+        verificationToken,
+        [&](V4_0_ErrorCode error, auto, auto, auto) { errorCode = convert(error); });
+
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    if (errorCode != KMV1::ErrorCode::OK) mOperationSlot.freeSlot();
+
+    return convertErrorCode(errorCode);
+}
+
+ScopedAStatus KeyMintOperation::update(const std::vector<uint8_t>& input,
+                                       const std::optional<HardwareAuthToken>& optAuthToken,
+                                       const std::optional<TimeStampToken>& optTimeStampToken,
+                                       std::vector<uint8_t>* out_output) {
+    V4_0_HardwareAuthToken authToken = convertAuthTokenToLegacy(optAuthToken);
+    V4_0_VerificationToken verificationToken = convertTimestampTokenToLegacy(optTimeStampToken);
+
+    size_t inputPos = 0;
+    *out_output = {};
+    KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
+
+    while (inputPos < input.size() && errorCode == KMV1::ErrorCode::OK) {
+        auto result =
+            mDevice->update(mOperationHandle, {} /* inParams */,
+                            {input.begin() + inputPos, input.end()}, authToken, verificationToken,
+                            [&](V4_0_ErrorCode error, uint32_t inputConsumed, auto /* outParams */,
+                                const hidl_vec<uint8_t>& output) {
+                                errorCode = convert(error);
+                                out_output->insert(out_output->end(), output.begin(), output.end());
+                                inputPos += inputConsumed;
+                            });
+
+        if (!result.isOk()) {
+            LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+            errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
+        }
+    }
+
+    if (errorCode != KMV1::ErrorCode::OK) mOperationSlot.freeSlot();
+
+    return convertErrorCode(errorCode);
+}
+
+ScopedAStatus
+KeyMintOperation::finish(const std::optional<std::vector<uint8_t>>& in_input,
+                         const std::optional<std::vector<uint8_t>>& in_signature,
+                         const std::optional<HardwareAuthToken>& in_authToken,
+                         const std::optional<TimeStampToken>& in_timeStampToken,
+                         const std::optional<std::vector<uint8_t>>& in_confirmationToken,
+                         std::vector<uint8_t>* out_output) {
+    auto input = in_input.value_or(std::vector<uint8_t>());
+    auto signature = in_signature.value_or(std::vector<uint8_t>());
+    V4_0_HardwareAuthToken authToken = convertAuthTokenToLegacy(in_authToken);
+    V4_0_VerificationToken verificationToken = convertTimestampTokenToLegacy(in_timeStampToken);
+
+    std::vector<V4_0_KeyParameter> inParams;
+    if (in_confirmationToken) {
+        inParams.push_back(makeKeyParameter(V4_0::TAG_CONFIRMATION_TOKEN, *in_confirmationToken));
+    }
+
+    KMV1::ErrorCode errorCode;
+    auto result = mDevice->finish(
+        mOperationHandle, inParams, input, signature, authToken, verificationToken,
+        [&](V4_0_ErrorCode error, auto /* outParams */, const hidl_vec<uint8_t>& output) {
+            errorCode = convert(error);
+            *out_output = output;
+        });
+
+    mOperationSlot.freeSlot();
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    return convertErrorCode(errorCode);
+}
+
+ScopedAStatus KeyMintOperation::abort() {
+    auto result = mDevice->abort(mOperationHandle);
+    mOperationSlot.freeSlot();
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+    }
+    return convertErrorCode(result);
+}
+
+KeyMintOperation::~KeyMintOperation() {
+    if (mOperationSlot.hasSlot()) {
+        auto error = abort();
+        if (!error.isOk()) {
+            LOG(WARNING) << "Error calling abort in ~KeyMintOperation: " << error.getMessage();
+        }
+    }
+}
+
+// SecureClock implementation
+
+ScopedAStatus SecureClock::generateTimeStamp(int64_t in_challenge, TimeStampToken* _aidl_return) {
+    KMV1::ErrorCode errorCode;
+    auto result = mDevice->verifyAuthorization(
+        in_challenge, {}, V4_0_HardwareAuthToken(),
+        [&](V4_0_ErrorCode error, const V4_0_VerificationToken& token) {
+            errorCode = convert(error);
+            _aidl_return->challenge = token.challenge;
+            _aidl_return->timestamp.milliSeconds = token.timestamp;
+            _aidl_return->mac = token.mac;
+        });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    return convertErrorCode(errorCode);
+}
+
+// SharedSecret implementation
+
+ScopedAStatus SharedSecret::getSharedSecretParameters(SharedSecretParameters* _aidl_return) {
+    KMV1::ErrorCode errorCode;
+    auto result = mDevice->getHmacSharingParameters(
+        [&](V4_0_ErrorCode error, const V4_0_HmacSharingParameters& params) {
+            errorCode = convert(error);
+            _aidl_return->seed = params.seed;
+            std::copy(params.nonce.data(), params.nonce.data() + params.nonce.elementCount(),
+                      std::back_inserter(_aidl_return->nonce));
+        });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    return convertErrorCode(errorCode);
+}
+
+ScopedAStatus
+SharedSecret::computeSharedSecret(const std::vector<SharedSecretParameters>& in_params,
+                                  std::vector<uint8_t>* _aidl_return) {
+    KMV1::ErrorCode errorCode;
+    auto legacyParams = convertSharedSecretParametersToLegacy(in_params);
+    auto result = mDevice->computeSharedHmac(
+        legacyParams, [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& sharingCheck) {
+            errorCode = convert(error);
+            *_aidl_return = sharingCheck;
+        });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
+        errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    return convertErrorCode(errorCode);
+}
+
+// Certificate implementation
+
+template <KMV1::Tag tag, KMV1::TagType type>
+static auto getParam(const std::vector<KeyParameter>& keyParams, KMV1::TypedTag<type, tag> ttag)
+    -> decltype(authorizationValue(ttag, KeyParameter())) {
+    for (const auto& p : keyParams) {
+
+        if (auto v = authorizationValue(ttag, p)) {
+            return v;
+        }
+    }
+    return {};
+}
+
+template <typename T>
+static bool containsParam(const std::vector<KeyParameter>& keyParams, T ttag) {
+    return static_cast<bool>(getParam(keyParams, ttag));
+}
+
+// Prefer the smallest.
+// If no options are found, return the first.
+template <typename T>
+static typename KMV1::TypedTag2ValueType<T>::type
+getMaximum(const std::vector<KeyParameter>& keyParams, T tag,
+           std::vector<typename KMV1::TypedTag2ValueType<T>::type> sortedOptions) {
+    auto bestSoFar = sortedOptions.end();
+    for (const KeyParameter& kp : keyParams) {
+        if (auto value = authorizationValue(tag, kp)) {
+            auto candidate = std::find(sortedOptions.begin(), sortedOptions.end(), *value);
+            // sortedOptions is sorted from best to worst. `std::distance(first, last)` counts the
+            // hops from `first` to `last`. So a better `candidate` yields a positive distance to
+            // `bestSoFar`.
+            if (std::distance(candidate, bestSoFar) > 0) {
+                bestSoFar = candidate;
+            }
+        }
+    }
+    if (bestSoFar == sortedOptions.end()) {
+        return sortedOptions[0];
+    }
+    return *bestSoFar;
+}
+
+static std::variant<keystore::X509_Ptr, KMV1::ErrorCode>
+makeCert(::android::sp<Keymaster> mDevice, const std::vector<KeyParameter>& keyParams,
+         const std::vector<uint8_t>& keyBlob) {
+    // Start generating the certificate.
+    // Get public key for makeCert.
+    KMV1::ErrorCode errorCode;
+    std::vector<uint8_t> key;
+    static std::vector<uint8_t> empty_vector;
+    auto unwrapBlob = [&](auto b) -> const std::vector<uint8_t>& {
+        if (b)
+            return *b;
+        else
+            return empty_vector;
+    };
+    auto result = mDevice->exportKey(
+        V4_0_KeyFormat::X509, keyBlob, unwrapBlob(getParam(keyParams, KMV1::TAG_APPLICATION_ID)),
+        unwrapBlob(getParam(keyParams, KMV1::TAG_APPLICATION_DATA)),
+        [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) {
+            errorCode = convert(error);
+            key = keyMaterial;
+        });
+    if (!result.isOk()) {
+        LOG(ERROR) << __func__ << " exportKey transaction failed. " << result.description();
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    if (errorCode != KMV1::ErrorCode::OK) {
+        return errorCode;
+    }
+    // Get pkey for makeCert.
+    CBS cbs;
+    CBS_init(&cbs, key.data(), key.size());
+    auto pkey = EVP_parse_public_key(&cbs);
+
+    // makeCert
+    std::optional<std::reference_wrapper<const std::vector<uint8_t>>> subject;
+    if (auto blob = getParam(keyParams, KMV1::TAG_CERTIFICATE_SUBJECT)) {
+        subject = *blob;
+    }
+
+    std::optional<std::reference_wrapper<const std::vector<uint8_t>>> serial;
+    if (auto blob = getParam(keyParams, KMV1::TAG_CERTIFICATE_SERIAL)) {
+        serial = *blob;
+    }
+
+    int64_t activation;
+    if (auto date = getParam(keyParams, KMV1::TAG_CERTIFICATE_NOT_BEFORE)) {
+        activation = static_cast<int64_t>(*date);
+    } else {
+        return KMV1::ErrorCode::MISSING_NOT_BEFORE;
+    }
+
+    int64_t expiration;
+    if (auto date = getParam(keyParams, KMV1::TAG_CERTIFICATE_NOT_AFTER)) {
+        expiration = static_cast<int64_t>(*date);
+    } else {
+        return KMV1::ErrorCode::MISSING_NOT_AFTER;
+    }
+
+    auto certOrError = keystore::makeCert(
+        pkey, serial, subject, activation, expiration, false /* intentionally left blank */,
+        std::nullopt /* intentionally left blank */, std::nullopt /* intentionally left blank */);
+    if (std::holds_alternative<keystore::CertUtilsError>(certOrError)) {
+        LOG(ERROR) << __func__ << ": Failed to make certificate";
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    return std::move(std::get<keystore::X509_Ptr>(certOrError));
+}
+
+static std::variant<keystore::Algo, KMV1::ErrorCode> getKeystoreAlgorithm(Algorithm algorithm) {
+    switch (algorithm) {
+    case Algorithm::RSA:
+        return keystore::Algo::RSA;
+    case Algorithm::EC:
+        return keystore::Algo::ECDSA;
+    default:
+        LOG(ERROR) << __func__ << ": This should not be called with symmetric algorithm.";
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+}
+
+static std::variant<keystore::Padding, KMV1::ErrorCode> getKeystorePadding(PaddingMode padding) {
+    switch (padding) {
+    case PaddingMode::RSA_PKCS1_1_5_SIGN:
+        return keystore::Padding::PKCS1_5;
+    case PaddingMode::RSA_PSS:
+        return keystore::Padding::PSS;
+    default:
+        return keystore::Padding::Ignored;
+    }
+}
+
+static std::variant<keystore::Digest, KMV1::ErrorCode> getKeystoreDigest(Digest digest) {
+    switch (digest) {
+    case Digest::SHA1:
+        return keystore::Digest::SHA1;
+    case Digest::SHA_2_224:
+        return keystore::Digest::SHA224;
+    case Digest::SHA_2_256:
+    case Digest::NONE:
+        return keystore::Digest::SHA256;
+    case Digest::SHA_2_384:
+        return keystore::Digest::SHA384;
+    case Digest::SHA_2_512:
+        return keystore::Digest::SHA512;
+    default:
+        LOG(ERROR) << __func__ << ": Unknown digest.";
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+}
+
+std::optional<KMV1::ErrorCode>
+KeyMintDevice::signCertificate(const std::vector<KeyParameter>& keyParams,
+                               const std::vector<uint8_t>& prefixedKeyBlob, X509* cert) {
+
+    auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM);
+    auto algoOrError = getKeystoreAlgorithm(*algorithm);
+    if (std::holds_alternative<KMV1::ErrorCode>(algoOrError)) {
+        return std::get<KMV1::ErrorCode>(algoOrError);
+    }
+    auto algo = std::get<keystore::Algo>(algoOrError);
+    auto origPadding = getMaximum(keyParams, KMV1::TAG_PADDING,
+                                  {PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN});
+    auto paddingOrError = getKeystorePadding(origPadding);
+    if (std::holds_alternative<KMV1::ErrorCode>(paddingOrError)) {
+        return std::get<KMV1::ErrorCode>(paddingOrError);
+    }
+    auto padding = std::get<keystore::Padding>(paddingOrError);
+    auto origDigest = getMaximum(keyParams, KMV1::TAG_DIGEST,
+                                 {Digest::SHA_2_256, Digest::SHA_2_512, Digest::SHA_2_384,
+                                  Digest::SHA_2_224, Digest::SHA1, Digest::NONE});
+    auto digestOrError = getKeystoreDigest(origDigest);
+    if (std::holds_alternative<KMV1::ErrorCode>(digestOrError)) {
+        return std::get<KMV1::ErrorCode>(digestOrError);
+    }
+    auto digest = std::get<keystore::Digest>(digestOrError);
+
+    KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
+    auto error = keystore::signCertWith(
+        &*cert,
+        [&](const uint8_t* data, size_t len) {
+            std::vector<uint8_t> dataVec(data, data + len);
+            std::vector<KeyParameter> kps = {
+                KMV1::makeKeyParameter(KMV1::TAG_DIGEST, origDigest),
+            };
+            if (algorithm == KMV1::Algorithm::RSA) {
+                kps.push_back(KMV1::makeKeyParameter(KMV1::TAG_PADDING, origPadding));
+            }
+            BeginResult beginResult;
+            auto error =
+                begin(KeyPurpose::SIGN, prefixedKeyBlob, kps, HardwareAuthToken(), &beginResult);
+            if (!error.isOk()) {
+                errorCode = toErrorCode(error);
+                return std::vector<uint8_t>();
+            }
+
+            std::vector<uint8_t> result;
+            error = beginResult.operation->finish(dataVec,                     //
+                                                  {} /* signature */,          //
+                                                  {} /* authToken */,          //
+                                                  {} /* timestampToken */,     //
+                                                  {} /* confirmationToken */,  //
+                                                  &result);
+            if (!error.isOk()) {
+                errorCode = toErrorCode(error);
+                return std::vector<uint8_t>();
+            }
+            return result;
+        },
+        algo, padding, digest);
+    if (error) {
+        LOG(ERROR) << __func__
+                   << ": signCertWith failed. (Callback diagnosed: " << toString(errorCode) << ")";
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    if (errorCode != KMV1::ErrorCode::OK) {
+        return errorCode;
+    }
+    return std::nullopt;
+}
+
+std::variant<std::vector<Certificate>, KMV1::ErrorCode>
+KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
+                              const std::vector<uint8_t>& prefixedKeyBlob) {
+    const std::vector<uint8_t>& keyBlob = prefixedKeyBlobRemovePrefix(prefixedKeyBlob);
+
+    // There are no certificates for symmetric keys.
+    auto algorithm = getParam(keyParams, KMV1::TAG_ALGORITHM);
+    if (!algorithm) {
+        LOG(ERROR) << __func__ << ": Unable to determine key algorithm.";
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+    switch (*algorithm) {
+    case Algorithm::RSA:
+    case Algorithm::EC:
+        break;
+    default:
+        return KMV1::ErrorCode::OK;
+    }
+
+    // If attestation was requested, call and use attestKey.
+    if (containsParam(keyParams, KMV1::TAG_ATTESTATION_CHALLENGE)) {
+        auto legacyParams = convertKeyParametersToLegacy(extractAttestationParams(keyParams));
+        std::vector<Certificate> certs;
+        KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
+        auto result = mDevice->attestKey(
+            keyBlob, legacyParams,
+            [&](V4_0::ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
+                errorCode = convert(error);
+                for (const auto& cert : certChain) {
+                    Certificate certificate;
+                    certificate.encodedCertificate = cert;
+                    certs.push_back(certificate);
+                }
+            });
+        if (!result.isOk()) {
+            LOG(ERROR) << __func__ << ": Call to attestKey failed.";
+            return KMV1::ErrorCode::UNKNOWN_ERROR;
+        }
+        if (errorCode != KMV1::ErrorCode::OK) {
+            return errorCode;
+        }
+        return certs;
+    }
+
+    // makeCert
+    auto certOrError = makeCert(mDevice, keyParams, keyBlob);
+    if (std::holds_alternative<KMV1::ErrorCode>(certOrError)) {
+        return std::get<KMV1::ErrorCode>(certOrError);
+    }
+    auto cert = std::move(std::get<keystore::X509_Ptr>(certOrError));
+
+    // setIssuer
+    auto error = keystore::setIssuer(&*cert, &*cert, false);
+    if (error) {
+        LOG(ERROR) << __func__ << ": Set issuer failed.";
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+
+    // Signing
+    auto canSelfSign =
+        std::find_if(keyParams.begin(), keyParams.end(), [&](const KeyParameter& kp) {
+            if (auto v = KMV1::authorizationValue(KMV1::TAG_PURPOSE, kp)) {
+                return *v == KeyPurpose::SIGN;
+            }
+            return false;
+        }) != keyParams.end();
+    auto noAuthRequired = containsParam(keyParams, KMV1::TAG_NO_AUTH_REQUIRED);
+    // If we cannot sign because of purpose or authorization requirement,
+    if (!(canSelfSign && noAuthRequired)
+        // or if self signing fails for any other reason,
+        || signCertificate(keyParams, keyBlob, &*cert).has_value()) {
+        // we sign with ephemeral key.
+        keystore::EVP_PKEY_CTX_Ptr pkey_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL));
+        EVP_PKEY_keygen_init(pkey_ctx.get());
+        EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pkey_ctx.get(), NID_X9_62_prime256v1);
+        EVP_PKEY* pkey_ptr = nullptr;
+        EVP_PKEY_keygen(pkey_ctx.get(), &pkey_ptr);
+        error = keystore::signCert(&*cert, pkey_ptr);
+        if (error) {
+            LOG(ERROR) << __func__ << ": signCert failed.";
+            return KMV1::ErrorCode::UNKNOWN_ERROR;
+        }
+    }
+
+    // encodeCert
+    auto encodedCertOrError = keystore::encodeCert(&*cert);
+    if (std::holds_alternative<keystore::CertUtilsError>(encodedCertOrError)) {
+        LOG(ERROR) << __func__ << ": encodeCert failed.";
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+
+    Certificate certificate{.encodedCertificate =
+                                std::get<std::vector<uint8_t>>(encodedCertOrError)};
+    std::vector certificates = {certificate};
+    return certificates;
+}
+
+// Code to find the Keymaster devices (copied from existing code).
+
+// Copied from system/security/keystore/include/keystore/keymaster_types.h.
+
+// Changing this namespace alias will change the keymaster version.
+namespace keymasterNs = ::android::hardware::keymaster::V4_1;
+
+using keymasterNs::SecurityLevel;
+
+// Copied from system/security/keystore/KeyStore.h.
+
+using ::android::sp;
+using keymasterNs::support::Keymaster;
+
+template <typename T, size_t count> class Devices : public std::array<T, count> {
+  public:
+    T& operator[](SecurityLevel secLevel) {
+        static_assert(uint32_t(SecurityLevel::SOFTWARE) == 0 &&
+                          uint32_t(SecurityLevel::TRUSTED_ENVIRONMENT) == 1 &&
+                          uint32_t(SecurityLevel::STRONGBOX) == 2,
+                      "Numeric values of security levels have changed");
+        return std::array<T, count>::at(static_cast<uint32_t>(secLevel));
+    }
+    T operator[](SecurityLevel secLevel) const {
+        if (static_cast<uint32_t>(secLevel) > static_cast<uint32_t>(SecurityLevel::STRONGBOX)) {
+            LOG(ERROR) << "Invalid security level requested";
+            return {};
+        }
+        return (*const_cast<Devices*>(this))[secLevel];
+    }
+};
+
+using KeymasterDevices = Devices<sp<Keymaster>, 3>;
+
+// Copied from system/security/keystore/keystore_main.cpp.
+
+using ::android::hardware::hidl_string;
+using keymasterNs::support::Keymaster3;
+using keymasterNs::support::Keymaster4;
+
+template <typename Wrapper>
+KeymasterDevices enumerateKeymasterDevices(IServiceManager* serviceManager) {
+    KeymasterDevices result;
+    serviceManager->listManifestByInterface(
+        Wrapper::WrappedIKeymasterDevice::descriptor, [&](const hidl_vec<hidl_string>& names) {
+            auto try_get_device = [&](const auto& name, bool fail_silent) {
+                auto device = Wrapper::WrappedIKeymasterDevice::getService(name);
+                if (fail_silent && !device) return;
+                CHECK(device) << "Failed to get service for \""
+                              << Wrapper::WrappedIKeymasterDevice::descriptor
+                              << "\" with interface name \"" << name << "\"";
+
+                sp<Keymaster> kmDevice(new Wrapper(device, name));
+                auto halVersion = kmDevice->halVersion();
+                SecurityLevel securityLevel = halVersion.securityLevel;
+                LOG(INFO) << "found " << Wrapper::WrappedIKeymasterDevice::descriptor
+                          << " with interface name " << name << " and seclevel "
+                          << toString(securityLevel);
+                CHECK(static_cast<uint32_t>(securityLevel) < result.size())
+                    << "Security level of \"" << Wrapper::WrappedIKeymasterDevice::descriptor
+                    << "\" with interface name \"" << name << "\" out of range";
+                auto& deviceSlot = result[securityLevel];
+                if (deviceSlot) {
+                    if (!fail_silent) {
+                        LOG(WARNING) << "Implementation of \""
+                                     << Wrapper::WrappedIKeymasterDevice::descriptor
+                                     << "\" with interface name \"" << name
+                                     << "\" and security level: " << toString(securityLevel)
+                                     << " Masked by other implementation of Keymaster";
+                    }
+                } else {
+                    deviceSlot = kmDevice;
+                }
+            };
+            bool has_default = false;
+            for (auto& n : names) {
+                try_get_device(n, false);
+                if (n == "default") has_default = true;
+            }
+            // Make sure that we always check the default device. If we enumerate only what is
+            // known to hwservicemanager, we miss a possible passthrough HAL.
+            if (!has_default) {
+                try_get_device("default", true /* fail_silent */);
+            }
+        });
+    return result;
+}
+
+KeymasterDevices initializeKeymasters() {
+    auto serviceManager = IServiceManager::getService();
+    CHECK(serviceManager.get()) << "Failed to get ServiceManager";
+    auto result = enumerateKeymasterDevices<Keymaster4>(serviceManager.get());
+    auto softKeymaster = result[SecurityLevel::SOFTWARE];
+    if (!result[SecurityLevel::TRUSTED_ENVIRONMENT]) {
+        result = enumerateKeymasterDevices<Keymaster3>(serviceManager.get());
+    }
+    if (softKeymaster) result[SecurityLevel::SOFTWARE] = softKeymaster;
+    if (result[SecurityLevel::SOFTWARE] && !result[SecurityLevel::TRUSTED_ENVIRONMENT]) {
+        LOG(WARNING) << "No secure Keymaster implementation found, but device offers insecure"
+                        " Keymaster HAL. Using as default.";
+        result[SecurityLevel::TRUSTED_ENVIRONMENT] = result[SecurityLevel::SOFTWARE];
+        result[SecurityLevel::SOFTWARE] = nullptr;
+    }
+    // The software bit was removed since we do not need it.
+    return result;
+}
+
+void KeyMintDevice::setNumFreeSlots(uint8_t numFreeSlots) {
+    mOperationSlots.setNumFreeSlots(numFreeSlots);
+}
+
+// Constructors and helpers.
+
+KeyMintDevice::KeyMintDevice(sp<Keymaster> device, KeyMintSecurityLevel securityLevel)
+    : mDevice(device), securityLevel_(securityLevel) {
+    if (securityLevel == KeyMintSecurityLevel::STRONGBOX) {
+        setNumFreeSlots(3);
+    } else {
+        setNumFreeSlots(15);
+    }
+
+    softKeyMintDevice_.reset(CreateKeyMintDevice(KeyMintSecurityLevel::SOFTWARE));
+}
+
+sp<Keymaster> getDevice(KeyMintSecurityLevel securityLevel) {
+    static std::mutex mutex;
+    static sp<Keymaster> teeDevice;
+    static sp<Keymaster> sbDevice;
+    std::lock_guard<std::mutex> lock(mutex);
+    if (!teeDevice) {
+        auto devices = initializeKeymasters();
+        teeDevice = devices[V4_0::SecurityLevel::TRUSTED_ENVIRONMENT];
+        sbDevice = devices[V4_0::SecurityLevel::STRONGBOX];
+    }
+    switch (securityLevel) {
+    case KeyMintSecurityLevel::TRUSTED_ENVIRONMENT:
+        return teeDevice;
+    case KeyMintSecurityLevel::STRONGBOX:
+        return sbDevice;
+    default:
+        return {};
+    }
+}
+
+std::shared_ptr<KeyMintDevice>
+KeyMintDevice::createKeyMintDevice(KeyMintSecurityLevel securityLevel) {
+    if (auto dev = getDevice(securityLevel)) {
+        return ndk::SharedRefBase::make<KeyMintDevice>(std::move(dev), securityLevel);
+    }
+    return {};
+}
+
+std::shared_ptr<SharedSecret> SharedSecret::createSharedSecret(KeyMintSecurityLevel securityLevel) {
+    auto device = getDevice(securityLevel);
+    if (!device) {
+        return {};
+    }
+    return ndk::SharedRefBase::make<SharedSecret>(std::move(device));
+}
+
+std::shared_ptr<SecureClock> SecureClock::createSecureClock(KeyMintSecurityLevel securityLevel) {
+    auto device = getDevice(securityLevel);
+    if (!device) {
+        return {};
+    }
+    return ndk::SharedRefBase::make<SecureClock>(std::move(device));
+}
+
+ScopedAStatus
+KeystoreCompatService::getKeyMintDevice(KeyMintSecurityLevel in_securityLevel,
+                                        std::shared_ptr<IKeyMintDevice>* _aidl_return) {
+    auto i = mDeviceCache.find(in_securityLevel);
+    if (i == mDeviceCache.end()) {
+        auto device = KeyMintDevice::createKeyMintDevice(in_securityLevel);
+        if (!device) {
+            return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
+        }
+        bool inserted = false;
+        std::tie(i, inserted) = mDeviceCache.insert({in_securityLevel, std::move(device)});
+    }
+    *_aidl_return = i->second;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus KeystoreCompatService::getSharedSecret(KeyMintSecurityLevel in_securityLevel,
+                                                     std::shared_ptr<ISharedSecret>* _aidl_return) {
+    if (!mSharedSecret) {
+        auto secret = SharedSecret::createSharedSecret(in_securityLevel);
+        if (!secret) {
+            return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
+        }
+        mSharedSecret = std::move(secret);
+    }
+    *_aidl_return = mSharedSecret;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus KeystoreCompatService::getSecureClock(std::shared_ptr<ISecureClock>* _aidl_return) {
+    if (!mSecureClock) {
+        // The legacy verification service was always provided by the TEE variant.
+        auto clock = SecureClock::createSecureClock(KeyMintSecurityLevel::TRUSTED_ENVIRONMENT);
+        if (!clock) {
+            return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
+        }
+        mSecureClock = std::move(clock);
+    }
+    *_aidl_return = mSecureClock;
+    return ScopedAStatus::ok();
+}
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
new file mode 100644
index 0000000..09c9157
--- /dev/null
+++ b/keystore2/src/km_compat/km_compat.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/security/keymint/BnKeyMintDevice.h>
+#include <aidl/android/hardware/security/keymint/BnKeyMintOperation.h>
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
+#include <aidl/android/hardware/security/secureclock/BnSecureClock.h>
+#include <aidl/android/hardware/security/sharedsecret/BnSharedSecret.h>
+#include <aidl/android/security/compat/BnKeystoreCompatService.h>
+#include <keymasterV4_1/Keymaster4.h>
+#include <unordered_map>
+#include <variant>
+
+#include "certificate_utils.h"
+
+using ::aidl::android::hardware::security::keymint::AttestationKey;
+using ::aidl::android::hardware::security::keymint::BeginResult;
+using ::aidl::android::hardware::security::keymint::Certificate;
+using ::aidl::android::hardware::security::keymint::HardwareAuthToken;
+using ::aidl::android::hardware::security::keymint::KeyCharacteristics;
+using ::aidl::android::hardware::security::keymint::KeyCreationResult;
+using ::aidl::android::hardware::security::keymint::KeyFormat;
+using ::aidl::android::hardware::security::keymint::KeyMintHardwareInfo;
+using ::aidl::android::hardware::security::keymint::KeyParameter;
+using ::aidl::android::hardware::security::keymint::KeyPurpose;
+using KeyMintSecurityLevel = ::aidl::android::hardware::security::keymint::SecurityLevel;
+using V4_0_ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode;
+using ::aidl::android::hardware::security::keymint::IKeyMintDevice;
+using KMV1_ErrorCode = ::aidl::android::hardware::security::keymint::ErrorCode;
+using ::aidl::android::hardware::security::secureclock::ISecureClock;
+using ::aidl::android::hardware::security::secureclock::TimeStampToken;
+using ::aidl::android::hardware::security::sharedsecret::ISharedSecret;
+using ::aidl::android::hardware::security::sharedsecret::SharedSecretParameters;
+using ::aidl::android::security::compat::BnKeystoreCompatService;
+using ::android::hardware::keymaster::V4_1::support::Keymaster;
+using ::ndk::ScopedAStatus;
+
+class OperationSlots {
+  private:
+    uint8_t mNumFreeSlots;
+    std::mutex mNumFreeSlotsMutex;
+
+  public:
+    void setNumFreeSlots(uint8_t numFreeSlots);
+    bool claimSlot();
+    void freeSlot();
+};
+
+// An abstraction for a single operation slot.
+// This contains logic to ensure that we do not free the slot multiple times,
+// e.g., if we call abort twice on the same operation.
+class OperationSlot {
+  private:
+    OperationSlots* mOperationSlots;
+    bool mIsActive;
+
+  public:
+    OperationSlot(OperationSlots* slots, bool isActive)
+        : mOperationSlots(slots), mIsActive(isActive) {}
+
+    void freeSlot();
+    bool hasSlot() { return mIsActive; }
+};
+
+class KeyMintDevice : public aidl::android::hardware::security::keymint::BnKeyMintDevice {
+  private:
+    ::android::sp<Keymaster> mDevice;
+    OperationSlots mOperationSlots;
+
+  public:
+    explicit KeyMintDevice(::android::sp<Keymaster>, KeyMintSecurityLevel);
+    static std::shared_ptr<KeyMintDevice> createKeyMintDevice(KeyMintSecurityLevel securityLevel);
+
+    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,
+                                   const std::vector<uint8_t>& in_inMaskingKey,
+                                   const std::vector<KeyParameter>& in_inUnwrappingParams,
+                                   int64_t in_inPasswordSid, int64_t in_inBiometricSid,
+                                   KeyCreationResult* out_creationResult) override;
+    ScopedAStatus upgradeKey(const std::vector<uint8_t>& in_inKeyBlobToUpgrade,
+                             const std::vector<KeyParameter>& in_inUpgradeParams,
+                             std::vector<uint8_t>* _aidl_return) override;
+    ScopedAStatus deleteKey(const std::vector<uint8_t>& in_inKeyBlob) override;
+    ScopedAStatus deleteAllKeys() override;
+    ScopedAStatus destroyAttestationIds() override;
+    ScopedAStatus begin(KeyPurpose in_inPurpose, const std::vector<uint8_t>& in_inKeyBlob,
+                        const std::vector<KeyParameter>& in_inParams,
+                        const std::optional<HardwareAuthToken>& in_inAuthToken,
+                        BeginResult* _aidl_return) override;
+    ScopedAStatus deviceLocked(bool passwordOnly,
+                               const std::optional<TimeStampToken>& timestampToken) override;
+    ScopedAStatus earlyBootEnded() override;
+
+    ScopedAStatus convertStorageKeyToEphemeral(const std::vector<uint8_t>& storageKeyBlob,
+                                               std::vector<uint8_t>* ephemeralKeyBlob) override;
+
+    ScopedAStatus
+    getKeyCharacteristics(const std::vector<uint8_t>& storageKeyBlob,
+                          const std::vector<uint8_t>& appId, const std::vector<uint8_t>& appData,
+                          std::vector<KeyCharacteristics>* keyCharacteristics) override;
+
+    // These are public to allow testing code to use them directly.
+    // This class should not be used publicly anyway.
+    std::variant<std::vector<Certificate>, KMV1_ErrorCode>
+    getCertificate(const std::vector<KeyParameter>& keyParams, const std::vector<uint8_t>& keyBlob);
+
+    void setNumFreeSlots(uint8_t numFreeSlots);
+
+  private:
+    std::optional<KMV1_ErrorCode> signCertificate(const std::vector<KeyParameter>& keyParams,
+                                                  const std::vector<uint8_t>& keyBlob, X509* cert);
+    KeyMintSecurityLevel securityLevel_;
+
+    // Software-based KeyMint device used to implement ECDH.
+    std::shared_ptr<IKeyMintDevice> softKeyMintDevice_;
+};
+
+class KeyMintOperation : public aidl::android::hardware::security::keymint::BnKeyMintOperation {
+  private:
+    ::android::sp<Keymaster> mDevice;
+    uint64_t mOperationHandle;
+    OperationSlot mOperationSlot;
+
+  public:
+    KeyMintOperation(::android::sp<Keymaster> device, uint64_t operationHandle,
+                     OperationSlots* slots, bool isActive)
+        : mDevice(device), mOperationHandle(operationHandle), mOperationSlot(slots, isActive) {}
+    ~KeyMintOperation();
+
+    ScopedAStatus updateAad(const std::vector<uint8_t>& input,
+                            const std::optional<HardwareAuthToken>& authToken,
+                            const std::optional<TimeStampToken>& timestampToken) override;
+
+    ScopedAStatus update(const std::vector<uint8_t>& input,
+                         const std::optional<HardwareAuthToken>& authToken,
+                         const std::optional<TimeStampToken>& timestampToken,
+                         std::vector<uint8_t>* output) override;
+
+    ScopedAStatus finish(const std::optional<std::vector<uint8_t>>& input,
+                         const std::optional<std::vector<uint8_t>>& signature,
+                         const std::optional<HardwareAuthToken>& authToken,
+                         const std::optional<TimeStampToken>& timeStampToken,
+                         const std::optional<std::vector<uint8_t>>& confirmationToken,
+                         std::vector<uint8_t>* output) override;
+
+    ScopedAStatus abort();
+};
+
+class SharedSecret : public aidl::android::hardware::security::sharedsecret::BnSharedSecret {
+  private:
+    ::android::sp<Keymaster> mDevice;
+
+  public:
+    SharedSecret(::android::sp<Keymaster> device) : mDevice(device) {}
+    static std::shared_ptr<SharedSecret> createSharedSecret(KeyMintSecurityLevel securityLevel);
+
+    virtual ScopedAStatus getSharedSecretParameters(SharedSecretParameters* _aidl_return) override;
+    virtual ScopedAStatus computeSharedSecret(const std::vector<SharedSecretParameters>& in_params,
+                                              std::vector<uint8_t>* _aidl_return) override;
+};
+
+class SecureClock : public aidl::android::hardware::security::secureclock::BnSecureClock {
+  private:
+    ::android::sp<Keymaster> mDevice;
+
+  public:
+    SecureClock(::android::sp<Keymaster> device) : mDevice(device) {}
+    static std::shared_ptr<SecureClock> createSecureClock(KeyMintSecurityLevel securityLevel);
+
+    ScopedAStatus generateTimeStamp(int64_t in_challenge, TimeStampToken* _aidl_return) override;
+};
+
+class KeystoreCompatService : public BnKeystoreCompatService {
+  private:
+    std::unordered_map<KeyMintSecurityLevel, std::shared_ptr<IKeyMintDevice>> mDeviceCache;
+    std::shared_ptr<ISharedSecret> mSharedSecret;
+    std::shared_ptr<ISecureClock> mSecureClock;
+
+  public:
+    KeystoreCompatService() {}
+    ScopedAStatus getKeyMintDevice(KeyMintSecurityLevel in_securityLevel,
+                                   std::shared_ptr<IKeyMintDevice>* _aidl_return) override;
+    ScopedAStatus getSharedSecret(KeyMintSecurityLevel in_securityLevel,
+                                  std::shared_ptr<ISharedSecret>* _aidl_return) override;
+    ScopedAStatus getSecureClock(std::shared_ptr<ISecureClock>* _aidl_return) override;
+};
diff --git a/keystore2/src/km_compat/km_compat_service.cpp b/keystore2/src/km_compat/km_compat_service.cpp
new file mode 100644
index 0000000..d2ced49
--- /dev/null
+++ b/keystore2/src/km_compat/km_compat_service.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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 "km_compat.h"
+#include <android/binder_manager.h>
+
+#include <mutex>
+
+extern "C" {
+
+// Create a KeyMintDevice and add it as a service.
+int32_t addKeyMintDeviceService() {
+    static std::mutex mutex;
+    std::lock_guard<std::mutex> lock(mutex);
+    static std::shared_ptr<KeystoreCompatService> ti;
+    binder_status_t status = STATUS_OK;
+    if (!ti) {
+        ti = ndk::SharedRefBase::make<KeystoreCompatService>();
+        const auto instanceName = "android.security.compat";
+        status = AServiceManager_addService(ti->asBinder().get(), instanceName);
+        if (status != STATUS_OK) {
+            ti.reset();
+        }
+    }
+    return status;
+}
+}
diff --git a/keystore2/src/km_compat/km_compat_type_conversion.h b/keystore2/src/km_compat/km_compat_type_conversion.h
new file mode 100644
index 0000000..de09477
--- /dev/null
+++ b/keystore2/src/km_compat/km_compat_type_conversion.h
@@ -0,0 +1,1067 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
+#include <keymasterV4_1/keymaster_tags.h>
+#include <keymint_support/keymint_tags.h>
+
+namespace V4_0 = ::android::hardware::keymaster::V4_0;
+namespace V4_1 = ::android::hardware::keymaster::V4_1;
+namespace KMV1 = ::aidl::android::hardware::security::keymint;
+
+static KMV1::ErrorCode convert(V4_0::ErrorCode error) {
+    switch (error) {
+    case V4_0::ErrorCode::OK:
+        return KMV1::ErrorCode::OK;
+    case V4_0::ErrorCode::ROOT_OF_TRUST_ALREADY_SET:
+        return KMV1::ErrorCode::ROOT_OF_TRUST_ALREADY_SET;
+    case V4_0::ErrorCode::UNSUPPORTED_PURPOSE:
+        return KMV1::ErrorCode::UNSUPPORTED_PURPOSE;
+    case V4_0::ErrorCode::INCOMPATIBLE_PURPOSE:
+        return KMV1::ErrorCode::INCOMPATIBLE_PURPOSE;
+    case V4_0::ErrorCode::UNSUPPORTED_ALGORITHM:
+        return KMV1::ErrorCode::UNSUPPORTED_ALGORITHM;
+    case V4_0::ErrorCode::INCOMPATIBLE_ALGORITHM:
+        return KMV1::ErrorCode::INCOMPATIBLE_ALGORITHM;
+    case V4_0::ErrorCode::UNSUPPORTED_KEY_SIZE:
+        return KMV1::ErrorCode::UNSUPPORTED_KEY_SIZE;
+    case V4_0::ErrorCode::UNSUPPORTED_BLOCK_MODE:
+        return KMV1::ErrorCode::UNSUPPORTED_BLOCK_MODE;
+    case V4_0::ErrorCode::INCOMPATIBLE_BLOCK_MODE:
+        return KMV1::ErrorCode::INCOMPATIBLE_BLOCK_MODE;
+    case V4_0::ErrorCode::UNSUPPORTED_MAC_LENGTH:
+        return KMV1::ErrorCode::UNSUPPORTED_MAC_LENGTH;
+    case V4_0::ErrorCode::UNSUPPORTED_PADDING_MODE:
+        return KMV1::ErrorCode::UNSUPPORTED_PADDING_MODE;
+    case V4_0::ErrorCode::INCOMPATIBLE_PADDING_MODE:
+        return KMV1::ErrorCode::INCOMPATIBLE_PADDING_MODE;
+    case V4_0::ErrorCode::UNSUPPORTED_DIGEST:
+        return KMV1::ErrorCode::UNSUPPORTED_DIGEST;
+    case V4_0::ErrorCode::INCOMPATIBLE_DIGEST:
+        return KMV1::ErrorCode::INCOMPATIBLE_DIGEST;
+    case V4_0::ErrorCode::INVALID_EXPIRATION_TIME:
+        return KMV1::ErrorCode::INVALID_EXPIRATION_TIME;
+    case V4_0::ErrorCode::INVALID_USER_ID:
+        return KMV1::ErrorCode::INVALID_USER_ID;
+    case V4_0::ErrorCode::INVALID_AUTHORIZATION_TIMEOUT:
+        return KMV1::ErrorCode::INVALID_AUTHORIZATION_TIMEOUT;
+    case V4_0::ErrorCode::UNSUPPORTED_KEY_FORMAT:
+        return KMV1::ErrorCode::UNSUPPORTED_KEY_FORMAT;
+    case V4_0::ErrorCode::INCOMPATIBLE_KEY_FORMAT:
+        return KMV1::ErrorCode::INCOMPATIBLE_KEY_FORMAT;
+    case V4_0::ErrorCode::UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM:
+        return KMV1::ErrorCode::UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM;
+    case V4_0::ErrorCode::UNSUPPORTED_KEY_VERIFICATION_ALGORITHM:
+        return KMV1::ErrorCode::UNSUPPORTED_KEY_VERIFICATION_ALGORITHM;
+    case V4_0::ErrorCode::INVALID_INPUT_LENGTH:
+        return KMV1::ErrorCode::INVALID_INPUT_LENGTH;
+    case V4_0::ErrorCode::KEY_EXPORT_OPTIONS_INVALID:
+        return KMV1::ErrorCode::KEY_EXPORT_OPTIONS_INVALID;
+    case V4_0::ErrorCode::DELEGATION_NOT_ALLOWED:
+        return KMV1::ErrorCode::DELEGATION_NOT_ALLOWED;
+    case V4_0::ErrorCode::KEY_NOT_YET_VALID:
+        return KMV1::ErrorCode::KEY_NOT_YET_VALID;
+    case V4_0::ErrorCode::KEY_EXPIRED:
+        return KMV1::ErrorCode::KEY_EXPIRED;
+    case V4_0::ErrorCode::KEY_USER_NOT_AUTHENTICATED:
+        return KMV1::ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+    case V4_0::ErrorCode::OUTPUT_PARAMETER_NULL:
+        return KMV1::ErrorCode::OUTPUT_PARAMETER_NULL;
+    case V4_0::ErrorCode::INVALID_OPERATION_HANDLE:
+        return KMV1::ErrorCode::INVALID_OPERATION_HANDLE;
+    case V4_0::ErrorCode::INSUFFICIENT_BUFFER_SPACE:
+        return KMV1::ErrorCode::INSUFFICIENT_BUFFER_SPACE;
+    case V4_0::ErrorCode::VERIFICATION_FAILED:
+        return KMV1::ErrorCode::VERIFICATION_FAILED;
+    case V4_0::ErrorCode::TOO_MANY_OPERATIONS:
+        return KMV1::ErrorCode::TOO_MANY_OPERATIONS;
+    case V4_0::ErrorCode::UNEXPECTED_NULL_POINTER:
+        return KMV1::ErrorCode::UNEXPECTED_NULL_POINTER;
+    case V4_0::ErrorCode::INVALID_KEY_BLOB:
+        return KMV1::ErrorCode::INVALID_KEY_BLOB;
+    case V4_0::ErrorCode::IMPORTED_KEY_NOT_ENCRYPTED:
+        return KMV1::ErrorCode::IMPORTED_KEY_NOT_ENCRYPTED;
+    case V4_0::ErrorCode::IMPORTED_KEY_DECRYPTION_FAILED:
+        return KMV1::ErrorCode::IMPORTED_KEY_DECRYPTION_FAILED;
+    case V4_0::ErrorCode::IMPORTED_KEY_NOT_SIGNED:
+        return KMV1::ErrorCode::IMPORTED_KEY_NOT_SIGNED;
+    case V4_0::ErrorCode::IMPORTED_KEY_VERIFICATION_FAILED:
+        return KMV1::ErrorCode::IMPORTED_KEY_VERIFICATION_FAILED;
+    case V4_0::ErrorCode::INVALID_ARGUMENT:
+        return KMV1::ErrorCode::INVALID_ARGUMENT;
+    case V4_0::ErrorCode::UNSUPPORTED_TAG:
+        return KMV1::ErrorCode::UNSUPPORTED_TAG;
+    case V4_0::ErrorCode::INVALID_TAG:
+        return KMV1::ErrorCode::INVALID_TAG;
+    case V4_0::ErrorCode::MEMORY_ALLOCATION_FAILED:
+        return KMV1::ErrorCode::MEMORY_ALLOCATION_FAILED;
+    case V4_0::ErrorCode::IMPORT_PARAMETER_MISMATCH:
+        return KMV1::ErrorCode::IMPORT_PARAMETER_MISMATCH;
+    case V4_0::ErrorCode::SECURE_HW_ACCESS_DENIED:
+        return KMV1::ErrorCode::SECURE_HW_ACCESS_DENIED;
+    case V4_0::ErrorCode::OPERATION_CANCELLED:
+        return KMV1::ErrorCode::OPERATION_CANCELLED;
+    case V4_0::ErrorCode::CONCURRENT_ACCESS_CONFLICT:
+        return KMV1::ErrorCode::CONCURRENT_ACCESS_CONFLICT;
+    case V4_0::ErrorCode::SECURE_HW_BUSY:
+        return KMV1::ErrorCode::SECURE_HW_BUSY;
+    case V4_0::ErrorCode::SECURE_HW_COMMUNICATION_FAILED:
+        return KMV1::ErrorCode::SECURE_HW_COMMUNICATION_FAILED;
+    case V4_0::ErrorCode::UNSUPPORTED_EC_FIELD:
+        return KMV1::ErrorCode::UNSUPPORTED_EC_FIELD;
+    case V4_0::ErrorCode::MISSING_NONCE:
+        return KMV1::ErrorCode::MISSING_NONCE;
+    case V4_0::ErrorCode::INVALID_NONCE:
+        return KMV1::ErrorCode::INVALID_NONCE;
+    case V4_0::ErrorCode::MISSING_MAC_LENGTH:
+        return KMV1::ErrorCode::MISSING_MAC_LENGTH;
+    case V4_0::ErrorCode::KEY_RATE_LIMIT_EXCEEDED:
+        return KMV1::ErrorCode::KEY_RATE_LIMIT_EXCEEDED;
+    case V4_0::ErrorCode::CALLER_NONCE_PROHIBITED:
+        return KMV1::ErrorCode::CALLER_NONCE_PROHIBITED;
+    case V4_0::ErrorCode::KEY_MAX_OPS_EXCEEDED:
+        return KMV1::ErrorCode::KEY_MAX_OPS_EXCEEDED;
+    case V4_0::ErrorCode::INVALID_MAC_LENGTH:
+        return KMV1::ErrorCode::INVALID_MAC_LENGTH;
+    case V4_0::ErrorCode::MISSING_MIN_MAC_LENGTH:
+        return KMV1::ErrorCode::MISSING_MIN_MAC_LENGTH;
+    case V4_0::ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH:
+        return KMV1::ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH;
+    case V4_0::ErrorCode::UNSUPPORTED_KDF:
+        return KMV1::ErrorCode::UNSUPPORTED_KDF;
+    case V4_0::ErrorCode::UNSUPPORTED_EC_CURVE:
+        return KMV1::ErrorCode::UNSUPPORTED_EC_CURVE;
+    case V4_0::ErrorCode::KEY_REQUIRES_UPGRADE:
+        return KMV1::ErrorCode::KEY_REQUIRES_UPGRADE;
+    case V4_0::ErrorCode::ATTESTATION_CHALLENGE_MISSING:
+        return KMV1::ErrorCode::ATTESTATION_CHALLENGE_MISSING;
+    case V4_0::ErrorCode::KEYMASTER_NOT_CONFIGURED:
+        return KMV1::ErrorCode::KEYMINT_NOT_CONFIGURED;
+    case V4_0::ErrorCode::ATTESTATION_APPLICATION_ID_MISSING:
+        return KMV1::ErrorCode::ATTESTATION_APPLICATION_ID_MISSING;
+    case V4_0::ErrorCode::CANNOT_ATTEST_IDS:
+        return KMV1::ErrorCode::CANNOT_ATTEST_IDS;
+    case V4_0::ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE:
+        return KMV1::ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE;
+    case V4_0::ErrorCode::HARDWARE_TYPE_UNAVAILABLE:
+        return KMV1::ErrorCode::HARDWARE_TYPE_UNAVAILABLE;
+    case V4_0::ErrorCode::PROOF_OF_PRESENCE_REQUIRED:
+        return KMV1::ErrorCode::PROOF_OF_PRESENCE_REQUIRED;
+    case V4_0::ErrorCode::CONCURRENT_PROOF_OF_PRESENCE_REQUESTED:
+        return KMV1::ErrorCode::CONCURRENT_PROOF_OF_PRESENCE_REQUESTED;
+    case V4_0::ErrorCode::NO_USER_CONFIRMATION:
+        return KMV1::ErrorCode::NO_USER_CONFIRMATION;
+    case V4_0::ErrorCode::DEVICE_LOCKED:
+        return KMV1::ErrorCode::DEVICE_LOCKED;
+    case V4_0::ErrorCode::UNIMPLEMENTED:
+        return KMV1::ErrorCode::UNIMPLEMENTED;
+    case V4_0::ErrorCode::VERSION_MISMATCH:
+        return KMV1::ErrorCode::VERSION_MISMATCH;
+    case V4_0::ErrorCode::UNKNOWN_ERROR:
+        return KMV1::ErrorCode::UNKNOWN_ERROR;
+    }
+}
+
+static std::optional<V4_0::KeyPurpose> convert(KMV1::KeyPurpose p) {
+    switch (p) {
+    case KMV1::KeyPurpose::ENCRYPT:
+        return V4_0::KeyPurpose::ENCRYPT;
+    case KMV1::KeyPurpose::DECRYPT:
+        return V4_0::KeyPurpose::DECRYPT;
+    case KMV1::KeyPurpose::SIGN:
+        return V4_0::KeyPurpose::SIGN;
+    case KMV1::KeyPurpose::VERIFY:
+        return V4_0::KeyPurpose::VERIFY;
+    case KMV1::KeyPurpose::WRAP_KEY:
+        return V4_0::KeyPurpose::WRAP_KEY;
+    default:
+        // Can end up here because KeyMint may have KeyPurpose values not in KM4.
+        return {};
+    }
+}
+
+static KMV1::KeyPurpose convert(V4_0::KeyPurpose p) {
+    switch (p) {
+    case V4_0::KeyPurpose::ENCRYPT:
+        return KMV1::KeyPurpose::ENCRYPT;
+    case V4_0::KeyPurpose::DECRYPT:
+        return KMV1::KeyPurpose::DECRYPT;
+    case V4_0::KeyPurpose::SIGN:
+        return KMV1::KeyPurpose::SIGN;
+    case V4_0::KeyPurpose::VERIFY:
+        return KMV1::KeyPurpose::VERIFY;
+    case V4_0::KeyPurpose::WRAP_KEY:
+        return KMV1::KeyPurpose::WRAP_KEY;
+    }
+}
+
+static V4_0::Algorithm convert(KMV1::Algorithm a) {
+    switch (a) {
+    case KMV1::Algorithm::RSA:
+        return V4_0::Algorithm::RSA;
+    case KMV1::Algorithm::EC:
+        return V4_0::Algorithm::EC;
+    case KMV1::Algorithm::AES:
+        return V4_0::Algorithm::AES;
+    case KMV1::Algorithm::TRIPLE_DES:
+        return V4_0::Algorithm::TRIPLE_DES;
+    case KMV1::Algorithm::HMAC:
+        return V4_0::Algorithm::HMAC;
+    }
+}
+
+static KMV1::Algorithm convert(V4_0::Algorithm a) {
+    switch (a) {
+    case V4_0::Algorithm::RSA:
+        return KMV1::Algorithm::RSA;
+    case V4_0::Algorithm::EC:
+        return KMV1::Algorithm::EC;
+    case V4_0::Algorithm::AES:
+        return KMV1::Algorithm::AES;
+    case V4_0::Algorithm::TRIPLE_DES:
+        return KMV1::Algorithm::TRIPLE_DES;
+    case V4_0::Algorithm::HMAC:
+        return KMV1::Algorithm::HMAC;
+    }
+}
+
+static V4_0::Digest convert(KMV1::Digest d) {
+    switch (d) {
+    case KMV1::Digest::NONE:
+        return V4_0::Digest::NONE;
+    case KMV1::Digest::MD5:
+        return V4_0::Digest::MD5;
+    case KMV1::Digest::SHA1:
+        return V4_0::Digest::SHA1;
+    case KMV1::Digest::SHA_2_224:
+        return V4_0::Digest::SHA_2_224;
+    case KMV1::Digest::SHA_2_256:
+        return V4_0::Digest::SHA_2_256;
+    case KMV1::Digest::SHA_2_384:
+        return V4_0::Digest::SHA_2_384;
+    case KMV1::Digest::SHA_2_512:
+        return V4_0::Digest::SHA_2_512;
+    }
+}
+
+static KMV1::Digest convert(V4_0::Digest d) {
+    switch (d) {
+    case V4_0::Digest::NONE:
+        return KMV1::Digest::NONE;
+    case V4_0::Digest::MD5:
+        return KMV1::Digest::MD5;
+    case V4_0::Digest::SHA1:
+        return KMV1::Digest::SHA1;
+    case V4_0::Digest::SHA_2_224:
+        return KMV1::Digest::SHA_2_224;
+    case V4_0::Digest::SHA_2_256:
+        return KMV1::Digest::SHA_2_256;
+    case V4_0::Digest::SHA_2_384:
+        return KMV1::Digest::SHA_2_384;
+    case V4_0::Digest::SHA_2_512:
+        return KMV1::Digest::SHA_2_512;
+    }
+}
+
+static V4_0::EcCurve convert(KMV1::EcCurve e) {
+    switch (e) {
+    case KMV1::EcCurve::P_224:
+        return V4_0::EcCurve::P_224;
+    case KMV1::EcCurve::P_256:
+        return V4_0::EcCurve::P_256;
+    case KMV1::EcCurve::P_384:
+        return V4_0::EcCurve::P_384;
+    case KMV1::EcCurve::P_521:
+        return V4_0::EcCurve::P_521;
+    }
+}
+
+static KMV1::EcCurve convert(V4_0::EcCurve e) {
+    switch (e) {
+    case V4_0::EcCurve::P_224:
+        return KMV1::EcCurve::P_224;
+    case V4_0::EcCurve::P_256:
+        return KMV1::EcCurve::P_256;
+    case V4_0::EcCurve::P_384:
+        return KMV1::EcCurve::P_384;
+    case V4_0::EcCurve::P_521:
+        return KMV1::EcCurve::P_521;
+    }
+}
+
+static V4_0::BlockMode convert(KMV1::BlockMode b) {
+    switch (b) {
+    case KMV1::BlockMode::ECB:
+        return V4_0::BlockMode::ECB;
+    case KMV1::BlockMode::CBC:
+        return V4_0::BlockMode::CBC;
+    case KMV1::BlockMode::CTR:
+        return V4_0::BlockMode::CTR;
+    case KMV1::BlockMode::GCM:
+        return V4_0::BlockMode::GCM;
+    }
+}
+
+static KMV1::BlockMode convert(V4_0::BlockMode b) {
+    switch (b) {
+    case V4_0::BlockMode::ECB:
+        return KMV1::BlockMode::ECB;
+    case V4_0::BlockMode::CBC:
+        return KMV1::BlockMode::CBC;
+    case V4_0::BlockMode::CTR:
+        return KMV1::BlockMode::CTR;
+    case V4_0::BlockMode::GCM:
+        return KMV1::BlockMode::GCM;
+    }
+}
+
+static V4_0::PaddingMode convert(KMV1::PaddingMode p) {
+    switch (p) {
+    case KMV1::PaddingMode::NONE:
+        return V4_0::PaddingMode::NONE;
+    case KMV1::PaddingMode::RSA_OAEP:
+        return V4_0::PaddingMode::RSA_OAEP;
+    case KMV1::PaddingMode::RSA_PSS:
+        return V4_0::PaddingMode::RSA_PSS;
+    case KMV1::PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
+        return V4_0::PaddingMode::RSA_PKCS1_1_5_ENCRYPT;
+    case KMV1::PaddingMode::RSA_PKCS1_1_5_SIGN:
+        return V4_0::PaddingMode::RSA_PKCS1_1_5_SIGN;
+    case KMV1::PaddingMode::PKCS7:
+        return V4_0::PaddingMode::PKCS7;
+    }
+}
+
+static KMV1::PaddingMode convert(V4_0::PaddingMode p) {
+    switch (p) {
+    case V4_0::PaddingMode::NONE:
+        return KMV1::PaddingMode::NONE;
+    case V4_0::PaddingMode::RSA_OAEP:
+        return KMV1::PaddingMode::RSA_OAEP;
+    case V4_0::PaddingMode::RSA_PSS:
+        return KMV1::PaddingMode::RSA_PSS;
+    case V4_0::PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
+        return KMV1::PaddingMode::RSA_PKCS1_1_5_ENCRYPT;
+    case V4_0::PaddingMode::RSA_PKCS1_1_5_SIGN:
+        return KMV1::PaddingMode::RSA_PKCS1_1_5_SIGN;
+    case V4_0::PaddingMode::PKCS7:
+        return KMV1::PaddingMode::PKCS7;
+    }
+}
+
+static V4_0::HardwareAuthenticatorType convert(KMV1::HardwareAuthenticatorType h) {
+    uint32_t result = 0;
+    uint32_t hat = static_cast<uint32_t>(h);
+    if (hat & static_cast<uint32_t>(KMV1::HardwareAuthenticatorType::PASSWORD)) {
+        result |= static_cast<uint32_t>(V4_0::HardwareAuthenticatorType::PASSWORD);
+    }
+    if (hat & static_cast<uint32_t>(KMV1::HardwareAuthenticatorType::FINGERPRINT)) {
+        result |= static_cast<uint32_t>(V4_0::HardwareAuthenticatorType::FINGERPRINT);
+    }
+    return static_cast<V4_0::HardwareAuthenticatorType>(result);
+}
+
+static KMV1::HardwareAuthenticatorType convert(V4_0::HardwareAuthenticatorType h) {
+    uint32_t result = 0;
+    if ((uint32_t)h & (uint32_t)V4_0::HardwareAuthenticatorType::PASSWORD) {
+        result |= (uint32_t)KMV1::HardwareAuthenticatorType::PASSWORD;
+    }
+    if ((uint32_t)h & (uint32_t)V4_0::HardwareAuthenticatorType::FINGERPRINT) {
+        result |= (uint32_t)KMV1::HardwareAuthenticatorType::FINGERPRINT;
+    }
+    return static_cast<KMV1::HardwareAuthenticatorType>(result);
+}
+
+static V4_0::SecurityLevel convert(KMV1::SecurityLevel s) {
+    switch (s) {
+    case KMV1::SecurityLevel::SOFTWARE:
+        return V4_0::SecurityLevel::SOFTWARE;
+    case KMV1::SecurityLevel::TRUSTED_ENVIRONMENT:
+        return V4_0::SecurityLevel::TRUSTED_ENVIRONMENT;
+    case KMV1::SecurityLevel::STRONGBOX:
+        return V4_0::SecurityLevel::STRONGBOX;
+    case KMV1::SecurityLevel::KEYSTORE:
+        return V4_0::SecurityLevel::SOFTWARE;
+    }
+}
+
+static KMV1::SecurityLevel convert(V4_0::SecurityLevel s) {
+    switch (s) {
+    case V4_0::SecurityLevel::SOFTWARE:
+        return KMV1::SecurityLevel::SOFTWARE;
+    case V4_0::SecurityLevel::TRUSTED_ENVIRONMENT:
+        return KMV1::SecurityLevel::TRUSTED_ENVIRONMENT;
+    case V4_0::SecurityLevel::STRONGBOX:
+        return KMV1::SecurityLevel::STRONGBOX;
+    }
+}
+
+static V4_0::KeyOrigin convert(KMV1::KeyOrigin o) {
+    switch (o) {
+    case KMV1::KeyOrigin::GENERATED:
+        return V4_0::KeyOrigin::GENERATED;
+    case KMV1::KeyOrigin::DERIVED:
+        return V4_0::KeyOrigin::DERIVED;
+    case KMV1::KeyOrigin::IMPORTED:
+        return V4_0::KeyOrigin::IMPORTED;
+    case KMV1::KeyOrigin::RESERVED:
+        return V4_0::KeyOrigin::UNKNOWN;
+    case KMV1::KeyOrigin::SECURELY_IMPORTED:
+        return V4_0::KeyOrigin::SECURELY_IMPORTED;
+    }
+}
+
+static KMV1::KeyOrigin convert(V4_0::KeyOrigin o) {
+    switch (o) {
+    case V4_0::KeyOrigin::GENERATED:
+        return KMV1::KeyOrigin::GENERATED;
+    case V4_0::KeyOrigin::DERIVED:
+        return KMV1::KeyOrigin::DERIVED;
+    case V4_0::KeyOrigin::IMPORTED:
+        return KMV1::KeyOrigin::IMPORTED;
+    case V4_0::KeyOrigin::UNKNOWN:
+        return KMV1::KeyOrigin::RESERVED;
+    case V4_0::KeyOrigin::SECURELY_IMPORTED:
+        return KMV1::KeyOrigin::SECURELY_IMPORTED;
+    }
+}
+
+static V4_0::KeyParameter convertKeyParameterToLegacy(const KMV1::KeyParameter& kp) {
+    switch (kp.tag) {
+    case KMV1::Tag::INVALID:
+        break;
+    case KMV1::Tag::PURPOSE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_PURPOSE, kp)) {
+            std::optional<V4_0::KeyPurpose> purpose = convert(v->get());
+            if (purpose) {
+                return V4_0::makeKeyParameter(V4_0::TAG_PURPOSE, purpose.value());
+            }
+        }
+        break;
+    case KMV1::Tag::ALGORITHM:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ALGORITHM, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ALGORITHM, convert(v->get()));
+        }
+        break;
+    case KMV1::Tag::KEY_SIZE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_KEY_SIZE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_KEY_SIZE, v->get());
+        }
+        break;
+    case KMV1::Tag::BLOCK_MODE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_BLOCK_MODE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_BLOCK_MODE, convert(v->get()));
+        }
+        break;
+    case KMV1::Tag::DIGEST:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_DIGEST, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_DIGEST, convert(v->get()));
+        }
+        break;
+    case KMV1::Tag::PADDING:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_PADDING, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_PADDING, convert(v->get()));
+        }
+        break;
+    case KMV1::Tag::CALLER_NONCE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_CALLER_NONCE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_CALLER_NONCE, v->get());
+        }
+        break;
+    case KMV1::Tag::MIN_MAC_LENGTH:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_MIN_MAC_LENGTH, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_MIN_MAC_LENGTH, v->get());
+        }
+        break;
+    case KMV1::Tag::EC_CURVE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_EC_CURVE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_EC_CURVE, convert(v->get()));
+        }
+        break;
+    case KMV1::Tag::RSA_PUBLIC_EXPONENT:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_RSA_PUBLIC_EXPONENT, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_RSA_PUBLIC_EXPONENT, v->get());
+        }
+        break;
+    case KMV1::Tag::INCLUDE_UNIQUE_ID:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_INCLUDE_UNIQUE_ID, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_INCLUDE_UNIQUE_ID, v->get());
+        }
+        break;
+    case KMV1::Tag::BOOTLOADER_ONLY:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_BOOTLOADER_ONLY, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_BOOTLOADER_ONLY, v->get());
+        }
+        break;
+    case KMV1::Tag::ROLLBACK_RESISTANCE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ROLLBACK_RESISTANCE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ROLLBACK_RESISTANCE, v->get());
+        }
+        break;
+    case KMV1::Tag::HARDWARE_TYPE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_HARDWARE_TYPE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_HARDWARE_TYPE, convert(v->get()));
+        }
+        break;
+    case KMV1::Tag::EARLY_BOOT_ONLY:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_EARLY_BOOT_ONLY, kp)) {
+            return V4_0::makeKeyParameter(V4_1::TAG_EARLY_BOOT_ONLY, v->get());
+        }
+        break;
+    case KMV1::Tag::ACTIVE_DATETIME:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ACTIVE_DATETIME, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ACTIVE_DATETIME, v->get());
+        }
+        break;
+    case KMV1::Tag::ORIGINATION_EXPIRE_DATETIME:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ORIGINATION_EXPIRE_DATETIME, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ORIGINATION_EXPIRE_DATETIME, v->get());
+        }
+        break;
+    case KMV1::Tag::USAGE_EXPIRE_DATETIME:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_USAGE_EXPIRE_DATETIME, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_USAGE_EXPIRE_DATETIME, v->get());
+        }
+        break;
+    case KMV1::Tag::MIN_SECONDS_BETWEEN_OPS:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_MIN_SECONDS_BETWEEN_OPS, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_MIN_SECONDS_BETWEEN_OPS, v->get());
+        }
+        break;
+    case KMV1::Tag::MAX_USES_PER_BOOT:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_MAX_USES_PER_BOOT, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_MAX_USES_PER_BOOT, v->get());
+        }
+        break;
+    case KMV1::Tag::USAGE_COUNT_LIMIT:
+        // Does not exist in KM < KeyMint 1.0.
+        break;
+    case KMV1::Tag::USER_ID:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_USER_ID, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_USER_ID, v->get());
+        }
+        break;
+    case KMV1::Tag::USER_SECURE_ID:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_USER_SECURE_ID, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_USER_SECURE_ID, v->get());
+        }
+        break;
+    case KMV1::Tag::NO_AUTH_REQUIRED:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_NO_AUTH_REQUIRED, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_NO_AUTH_REQUIRED, v->get());
+        }
+        break;
+    case KMV1::Tag::USER_AUTH_TYPE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_USER_AUTH_TYPE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_USER_AUTH_TYPE, convert(v->get()));
+        }
+        break;
+    case KMV1::Tag::AUTH_TIMEOUT:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_AUTH_TIMEOUT, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_AUTH_TIMEOUT, v->get());
+        }
+        break;
+    case KMV1::Tag::ALLOW_WHILE_ON_BODY:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ALLOW_WHILE_ON_BODY, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ALLOW_WHILE_ON_BODY, v->get());
+        }
+        break;
+    case KMV1::Tag::TRUSTED_USER_PRESENCE_REQUIRED:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_TRUSTED_USER_PRESENCE_REQUIRED, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_TRUSTED_USER_PRESENCE_REQUIRED, v->get());
+        }
+        break;
+    case KMV1::Tag::TRUSTED_CONFIRMATION_REQUIRED:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_TRUSTED_CONFIRMATION_REQUIRED, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_TRUSTED_CONFIRMATION_REQUIRED, v->get());
+        }
+        break;
+    case KMV1::Tag::UNLOCKED_DEVICE_REQUIRED:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_UNLOCKED_DEVICE_REQUIRED, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_UNLOCKED_DEVICE_REQUIRED, v->get());
+        }
+        break;
+    case KMV1::Tag::APPLICATION_ID:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_APPLICATION_ID, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_APPLICATION_ID, v->get());
+        }
+        break;
+    case KMV1::Tag::APPLICATION_DATA:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_APPLICATION_DATA, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_APPLICATION_DATA, v->get());
+        }
+        break;
+    case KMV1::Tag::CREATION_DATETIME:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_CREATION_DATETIME, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_CREATION_DATETIME, v->get());
+        }
+        break;
+    case KMV1::Tag::ORIGIN:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ORIGIN, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ORIGIN, convert(v->get()));
+        }
+        break;
+    case KMV1::Tag::ROOT_OF_TRUST:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ROOT_OF_TRUST, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ROOT_OF_TRUST, v->get());
+        }
+        break;
+    case KMV1::Tag::OS_VERSION:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_OS_VERSION, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_OS_VERSION, v->get());
+        }
+        break;
+    case KMV1::Tag::OS_PATCHLEVEL:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_OS_PATCHLEVEL, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_OS_PATCHLEVEL, v->get());
+        }
+        break;
+    case KMV1::Tag::UNIQUE_ID:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_UNIQUE_ID, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_UNIQUE_ID, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_CHALLENGE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_CHALLENGE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_CHALLENGE, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_APPLICATION_ID:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_APPLICATION_ID, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_APPLICATION_ID, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_ID_BRAND:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_BRAND, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_BRAND, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_ID_DEVICE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_DEVICE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_DEVICE, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_ID_PRODUCT:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_PRODUCT, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_PRODUCT, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_ID_SERIAL:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_SERIAL, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_SERIAL, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_ID_IMEI:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_IMEI, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_IMEI, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_ID_MEID:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_MEID, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_MEID, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_ID_MANUFACTURER:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_MANUFACTURER, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, v->get());
+        }
+        break;
+    case KMV1::Tag::ATTESTATION_ID_MODEL:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ATTESTATION_ID_MODEL, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ATTESTATION_ID_MODEL, v->get());
+        }
+        break;
+    case KMV1::Tag::VENDOR_PATCHLEVEL:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_VENDOR_PATCHLEVEL, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_VENDOR_PATCHLEVEL, v->get());
+        }
+        break;
+    case KMV1::Tag::BOOT_PATCHLEVEL:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_BOOT_PATCHLEVEL, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_BOOT_PATCHLEVEL, v->get());
+        }
+        break;
+    case KMV1::Tag::DEVICE_UNIQUE_ATTESTATION:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_DEVICE_UNIQUE_ATTESTATION, kp)) {
+            return V4_0::makeKeyParameter(V4_1::TAG_DEVICE_UNIQUE_ATTESTATION, v->get());
+        }
+        break;
+    case KMV1::Tag::IDENTITY_CREDENTIAL_KEY:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_IDENTITY_CREDENTIAL_KEY, kp)) {
+            return V4_0::makeKeyParameter(V4_1::TAG_IDENTITY_CREDENTIAL_KEY, v->get());
+        }
+        break;
+    case KMV1::Tag::STORAGE_KEY:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_STORAGE_KEY, kp)) {
+            return V4_0::makeKeyParameter(V4_1::TAG_STORAGE_KEY, v->get());
+        }
+        break;
+    case KMV1::Tag::ASSOCIATED_DATA:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_ASSOCIATED_DATA, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_ASSOCIATED_DATA, v->get());
+        }
+        break;
+    case KMV1::Tag::NONCE:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_NONCE, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_NONCE, v->get());
+        }
+        break;
+    case KMV1::Tag::MAC_LENGTH:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_MAC_LENGTH, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_MAC_LENGTH, v->get());
+        }
+        break;
+    case KMV1::Tag::RESET_SINCE_ID_ROTATION:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_RESET_SINCE_ID_ROTATION, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_RESET_SINCE_ID_ROTATION, v->get());
+        }
+        break;
+    case KMV1::Tag::CONFIRMATION_TOKEN:
+        if (auto v = KMV1::authorizationValue(KMV1::TAG_CONFIRMATION_TOKEN, kp)) {
+            return V4_0::makeKeyParameter(V4_0::TAG_CONFIRMATION_TOKEN, v->get());
+        }
+        break;
+    case KMV1::Tag::RSA_OAEP_MGF_DIGEST:
+    case KMV1::Tag::CERTIFICATE_SERIAL:
+    case KMV1::Tag::CERTIFICATE_SUBJECT:
+    case KMV1::Tag::CERTIFICATE_NOT_BEFORE:
+    case KMV1::Tag::CERTIFICATE_NOT_AFTER:
+        // These tags do not exist in KM < KeyMint 1.0.
+        break;
+    case KMV1::Tag::MAX_BOOT_LEVEL:
+        // Does not exist in API level 30 or below.
+        break;
+    }
+    return V4_0::KeyParameter{.tag = V4_0::Tag::INVALID};
+}
+
+static KMV1::KeyParameter convertKeyParameterFromLegacy(const V4_0::KeyParameter& kp) {
+    auto unwrapper = [](auto v) -> auto {
+        if (v.isOk()) {
+            return std::optional(std::reference_wrapper(v.value()));
+        } else {
+            return std::optional<decltype(std::reference_wrapper(v.value()))>{};
+        }
+    };
+    switch (kp.tag) {
+    case V4_0::Tag::INVALID:
+        break;
+    case V4_0::Tag::PURPOSE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_PURPOSE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::ALGORITHM:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ALGORITHM, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::KEY_SIZE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_KEY_SIZE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, v->get());
+        }
+        break;
+    case V4_0::Tag::BLOCK_MODE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_BLOCK_MODE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_BLOCK_MODE, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::DIGEST:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_DIGEST, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_DIGEST, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::PADDING:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_PADDING, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_PADDING, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::CALLER_NONCE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_CALLER_NONCE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_CALLER_NONCE, v->get());
+        }
+        break;
+    case V4_0::Tag::MIN_MAC_LENGTH:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_MIN_MAC_LENGTH, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_MIN_MAC_LENGTH, v->get());
+        }
+        break;
+    case V4_0::Tag::EC_CURVE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_EC_CURVE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_EC_CURVE, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::RSA_PUBLIC_EXPONENT:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_RSA_PUBLIC_EXPONENT, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_RSA_PUBLIC_EXPONENT, v->get());
+        }
+        break;
+    case V4_0::Tag::INCLUDE_UNIQUE_ID:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_INCLUDE_UNIQUE_ID, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_INCLUDE_UNIQUE_ID, v->get());
+        }
+        break;
+    case V4_0::Tag::BLOB_USAGE_REQUIREMENTS:
+        // This tag has been removed. Mapped on invalid.
+        break;
+    case V4_0::Tag::BOOTLOADER_ONLY:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_BOOTLOADER_ONLY, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_BOOTLOADER_ONLY, v->get());
+        }
+        break;
+    case V4_0::Tag::ROLLBACK_RESISTANCE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ROLLBACK_RESISTANCE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ROLLBACK_RESISTANCE, v->get());
+        }
+        break;
+    case V4_0::Tag::HARDWARE_TYPE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_HARDWARE_TYPE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_HARDWARE_TYPE, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::ACTIVE_DATETIME:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ACTIVE_DATETIME, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ACTIVE_DATETIME, v->get());
+        }
+        break;
+    case V4_0::Tag::ORIGINATION_EXPIRE_DATETIME:
+        if (auto v =
+                unwrapper(V4_0::authorizationValue(V4_0::TAG_ORIGINATION_EXPIRE_DATETIME, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ORIGINATION_EXPIRE_DATETIME, v->get());
+        }
+        break;
+    case V4_0::Tag::USAGE_EXPIRE_DATETIME:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_USAGE_EXPIRE_DATETIME, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_USAGE_EXPIRE_DATETIME, v->get());
+        }
+        break;
+    case V4_0::Tag::MIN_SECONDS_BETWEEN_OPS:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_MIN_SECONDS_BETWEEN_OPS, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_MIN_SECONDS_BETWEEN_OPS, v->get());
+        }
+        break;
+    case V4_0::Tag::MAX_USES_PER_BOOT:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_MAX_USES_PER_BOOT, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_MAX_USES_PER_BOOT, v->get());
+        }
+        break;
+    case V4_0::Tag::USER_ID:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_USER_ID, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_USER_ID, v->get());
+        }
+        break;
+    case V4_0::Tag::USER_SECURE_ID:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_USER_SECURE_ID, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_USER_SECURE_ID, v->get());
+        }
+        break;
+    case V4_0::Tag::NO_AUTH_REQUIRED:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_NO_AUTH_REQUIRED, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED, v->get());
+        }
+        break;
+    case V4_0::Tag::USER_AUTH_TYPE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_USER_AUTH_TYPE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_USER_AUTH_TYPE, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::AUTH_TIMEOUT:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_AUTH_TIMEOUT, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_AUTH_TIMEOUT, v->get());
+        }
+        break;
+    case V4_0::Tag::ALLOW_WHILE_ON_BODY:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ALLOW_WHILE_ON_BODY, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ALLOW_WHILE_ON_BODY, v->get());
+        }
+        break;
+    case V4_0::Tag::TRUSTED_USER_PRESENCE_REQUIRED:
+        if (auto v =
+                unwrapper(V4_0::authorizationValue(V4_0::TAG_TRUSTED_USER_PRESENCE_REQUIRED, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_TRUSTED_USER_PRESENCE_REQUIRED, v->get());
+        }
+        break;
+    case V4_0::Tag::TRUSTED_CONFIRMATION_REQUIRED:
+        if (auto v =
+                unwrapper(V4_0::authorizationValue(V4_0::TAG_TRUSTED_CONFIRMATION_REQUIRED, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_TRUSTED_CONFIRMATION_REQUIRED, v->get());
+        }
+        break;
+    case V4_0::Tag::UNLOCKED_DEVICE_REQUIRED:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_UNLOCKED_DEVICE_REQUIRED, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_UNLOCKED_DEVICE_REQUIRED, v->get());
+        }
+        break;
+    case V4_0::Tag::APPLICATION_ID:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_APPLICATION_ID, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_APPLICATION_ID, v->get());
+        }
+        break;
+    case V4_0::Tag::APPLICATION_DATA:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_APPLICATION_DATA, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_APPLICATION_DATA, v->get());
+        }
+        break;
+    case V4_0::Tag::CREATION_DATETIME:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_CREATION_DATETIME, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_CREATION_DATETIME, v->get());
+        }
+        break;
+    case V4_0::Tag::ORIGIN:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ORIGIN, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ORIGIN, convert(v->get()));
+        }
+        break;
+    case V4_0::Tag::ROOT_OF_TRUST:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ROOT_OF_TRUST, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ROOT_OF_TRUST, v->get());
+        }
+        break;
+    case V4_0::Tag::OS_VERSION:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_OS_VERSION, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_OS_VERSION, v->get());
+        }
+        break;
+    case V4_0::Tag::OS_PATCHLEVEL:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_OS_PATCHLEVEL, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_OS_PATCHLEVEL, v->get());
+        }
+        break;
+    case V4_0::Tag::UNIQUE_ID:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_UNIQUE_ID, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_UNIQUE_ID, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_CHALLENGE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_CHALLENGE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_CHALLENGE, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_APPLICATION_ID:
+        if (auto v =
+                unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_APPLICATION_ID, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_APPLICATION_ID, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_ID_BRAND:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_BRAND, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_BRAND, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_ID_DEVICE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_DEVICE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_DEVICE, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_ID_PRODUCT:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_PRODUCT, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_PRODUCT, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_ID_SERIAL:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_SERIAL, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_SERIAL, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_ID_IMEI:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_IMEI, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_IMEI, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_ID_MEID:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_MEID, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_MEID, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_ID_MANUFACTURER:
+        if (auto v =
+                unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_MANUFACTURER, v->get());
+        }
+        break;
+    case V4_0::Tag::ATTESTATION_ID_MODEL:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ATTESTATION_ID_MODEL, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ATTESTATION_ID_MODEL, v->get());
+        }
+        break;
+    case V4_0::Tag::VENDOR_PATCHLEVEL:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_VENDOR_PATCHLEVEL, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_VENDOR_PATCHLEVEL, v->get());
+        }
+        break;
+    case V4_0::Tag::BOOT_PATCHLEVEL:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_BOOT_PATCHLEVEL, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_BOOT_PATCHLEVEL, v->get());
+        }
+        break;
+    case V4_0::Tag::ASSOCIATED_DATA:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_ASSOCIATED_DATA, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_ASSOCIATED_DATA, v->get());
+        }
+        break;
+    case V4_0::Tag::NONCE:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_NONCE, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_NONCE, v->get());
+        }
+        break;
+    case V4_0::Tag::MAC_LENGTH:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_MAC_LENGTH, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_MAC_LENGTH, v->get());
+        }
+        break;
+    case V4_0::Tag::RESET_SINCE_ID_ROTATION:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_RESET_SINCE_ID_ROTATION, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_RESET_SINCE_ID_ROTATION, v->get());
+        }
+        break;
+    case V4_0::Tag::CONFIRMATION_TOKEN:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_0::TAG_CONFIRMATION_TOKEN, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_CONFIRMATION_TOKEN, v->get());
+        }
+        break;
+    default:
+        break;
+    }
+
+    switch (static_cast<V4_1::Tag>(kp.tag)) {
+    case V4_1::Tag::EARLY_BOOT_ONLY:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_1::TAG_EARLY_BOOT_ONLY, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_EARLY_BOOT_ONLY, v->get());
+        }
+        break;
+    case V4_1::Tag::DEVICE_UNIQUE_ATTESTATION:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_1::TAG_DEVICE_UNIQUE_ATTESTATION, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_DEVICE_UNIQUE_ATTESTATION, v->get());
+        }
+        break;
+    case V4_1::Tag::IDENTITY_CREDENTIAL_KEY:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_1::TAG_IDENTITY_CREDENTIAL_KEY, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_IDENTITY_CREDENTIAL_KEY, v->get());
+        }
+        break;
+    case V4_1::Tag::STORAGE_KEY:
+        if (auto v = unwrapper(V4_0::authorizationValue(V4_1::TAG_STORAGE_KEY, kp))) {
+            return KMV1::makeKeyParameter(KMV1::TAG_STORAGE_KEY, v->get());
+        }
+        break;
+    default:
+        break;
+    }
+
+    return KMV1::makeKeyParameter(KMV1::TAG_INVALID);
+}
diff --git a/keystore2/src/km_compat/lib.rs b/keystore2/src/km_compat/lib.rs
new file mode 100644
index 0000000..eddd684
--- /dev/null
+++ b/keystore2/src/km_compat/lib.rs
@@ -0,0 +1,378 @@
+// Copyright 2020, 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.
+
+//! Export into Rust a function to create a KeyMintDevice and add it as a service.
+
+#[allow(missing_docs)] // TODO remove this
+extern "C" {
+    fn addKeyMintDeviceService() -> i32;
+}
+
+#[allow(missing_docs)] // TODO remove this
+pub fn add_keymint_device_service() -> i32 {
+    unsafe { addKeyMintDeviceService() }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+        Algorithm::Algorithm, BeginResult::BeginResult, BlockMode::BlockMode, Digest::Digest,
+        ErrorCode::ErrorCode, IKeyMintDevice::IKeyMintDevice, KeyCreationResult::KeyCreationResult,
+        KeyFormat::KeyFormat, KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue,
+        KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
+    };
+    use android_hardware_security_keymint::binder::{self, Strong};
+    use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
+
+    static COMPAT_NAME: &str = "android.security.compat";
+
+    fn get_device() -> Option<Strong<dyn IKeyMintDevice>> {
+        add_keymint_device_service();
+        let compat_service: Strong<dyn IKeystoreCompatService> =
+            binder::get_interface(COMPAT_NAME).ok()?;
+        compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).ok()
+    }
+
+    macro_rules! get_device_or_skip_test {
+        () => {
+            match get_device() {
+                Some(dev) => dev,
+                None => return,
+            }
+        };
+    }
+
+    #[test]
+    fn test_get_hardware_info() {
+        let legacy = get_device_or_skip_test!();
+        let hinfo = legacy.getHardwareInfo();
+        assert!(hinfo.is_ok());
+    }
+
+    #[test]
+    fn test_add_rng_entropy() {
+        let legacy = get_device_or_skip_test!();
+        let result = legacy.addRngEntropy(&[42; 16]);
+        assert!(result.is_ok(), "{:?}", result);
+    }
+
+    // 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, None /* attest_key */).expect("Failed to generate key");
+        assert_ne!(creation_result.keyBlob.len(), 0);
+        creation_result
+    }
+
+    // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to GeneralizedTime
+    // 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
+    const UNDEFINED_NOT_AFTER: i64 = 253402300799000i64;
+
+    fn generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8> {
+        let mut kps = vec![
+            KeyParameter {
+                tag: Tag::ALGORITHM,
+                value: KeyParameterValue::Algorithm(Algorithm::RSA),
+            },
+            KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) },
+            KeyParameter {
+                tag: Tag::RSA_PUBLIC_EXPONENT,
+                value: KeyParameterValue::LongInteger(65537),
+            },
+            KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) },
+            KeyParameter {
+                tag: Tag::PADDING,
+                value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
+            },
+            KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
+            KeyParameter {
+                tag: Tag::PURPOSE,
+                value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
+            },
+            KeyParameter {
+                tag: Tag::CERTIFICATE_NOT_BEFORE,
+                value: KeyParameterValue::DateTime(0),
+            },
+            KeyParameter {
+                tag: Tag::CERTIFICATE_NOT_AFTER,
+                value: KeyParameterValue::DateTime(UNDEFINED_NOT_AFTER),
+            },
+        ];
+        if encrypt {
+            kps.push(KeyParameter {
+                tag: Tag::PURPOSE,
+                value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
+            });
+        }
+        if attest {
+            kps.push(KeyParameter {
+                tag: Tag::ATTESTATION_CHALLENGE,
+                value: KeyParameterValue::Blob(vec![42; 8]),
+            });
+            kps.push(KeyParameter {
+                tag: Tag::ATTESTATION_APPLICATION_ID,
+                value: KeyParameterValue::Blob(vec![42; 8]),
+            });
+        }
+        let creation_result = generate_key(legacy, kps);
+        if attest {
+            // TODO: Will this always be greater than 1?
+            assert!(creation_result.certificateChain.len() > 1);
+        } else {
+            assert_eq!(creation_result.certificateChain.len(), 1);
+        }
+        creation_result.keyBlob
+    }
+
+    #[test]
+    fn test_generate_key_no_encrypt() {
+        let legacy = get_device_or_skip_test!();
+        generate_rsa_key(legacy.as_ref(), false, false);
+    }
+
+    #[test]
+    fn test_generate_key_encrypt() {
+        let legacy = get_device_or_skip_test!();
+        generate_rsa_key(legacy.as_ref(), true, false);
+    }
+
+    #[test]
+    fn test_generate_key_attested() {
+        let legacy = get_device_or_skip_test!();
+        generate_rsa_key(legacy.as_ref(), false, true);
+    }
+
+    #[test]
+    fn test_import_key() {
+        let legacy = get_device_or_skip_test!();
+        let kps = [KeyParameter {
+            tag: Tag::ALGORITHM,
+            value: KeyParameterValue::Algorithm(Algorithm::AES),
+        }];
+        let kf = KeyFormat::RAW;
+        let kd = [0; 16];
+        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);
+    }
+
+    #[test]
+    fn test_import_wrapped_key() {
+        let legacy = get_device_or_skip_test!();
+        let result = legacy.importWrappedKey(&[], &[], &[], &[], 0, 0);
+        // For this test we only care that there was no crash.
+        assert!(result.is_ok() || result.is_err());
+    }
+
+    #[test]
+    fn test_upgrade_key() {
+        let legacy = get_device_or_skip_test!();
+        let blob = generate_rsa_key(legacy.as_ref(), false, false);
+        let result = legacy.upgradeKey(&blob, &[]);
+        // For this test we only care that there was no crash.
+        assert!(result.is_ok() || result.is_err());
+    }
+
+    #[test]
+    fn test_delete_key() {
+        let legacy = get_device_or_skip_test!();
+        let blob = generate_rsa_key(legacy.as_ref(), false, false);
+        let result = legacy.deleteKey(&blob);
+        assert!(result.is_ok(), "{:?}", result);
+    }
+
+    #[test]
+    fn test_delete_all_keys() {
+        let legacy = get_device_or_skip_test!();
+        let result = legacy.deleteAllKeys();
+        assert!(result.is_ok(), "{:?}", result);
+    }
+
+    #[test]
+    fn test_destroy_attestation_ids() {
+        let legacy = get_device_or_skip_test!();
+        let result = legacy.destroyAttestationIds();
+        assert!(result.is_err());
+        assert_eq!(result.unwrap_err().service_specific_error(), ErrorCode::UNIMPLEMENTED.0,);
+    }
+
+    fn generate_aes_key(legacy: &dyn IKeyMintDevice) -> Vec<u8> {
+        let kps = vec![
+            KeyParameter {
+                tag: Tag::ALGORITHM,
+                value: KeyParameterValue::Algorithm(Algorithm::AES),
+            },
+            KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
+            KeyParameter {
+                tag: Tag::BLOCK_MODE,
+                value: KeyParameterValue::BlockMode(BlockMode::CBC),
+            },
+            KeyParameter {
+                tag: Tag::PADDING,
+                value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
+            },
+            KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
+            KeyParameter {
+                tag: Tag::PURPOSE,
+                value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
+            },
+            KeyParameter {
+                tag: Tag::PURPOSE,
+                value: KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
+            },
+        ];
+        let creation_result = generate_key(legacy, kps);
+        assert_eq!(creation_result.certificateChain.len(), 0);
+        creation_result.keyBlob
+    }
+
+    fn begin(
+        legacy: &dyn IKeyMintDevice,
+        blob: &[u8],
+        purpose: KeyPurpose,
+        extra_params: Option<Vec<KeyParameter>>,
+    ) -> BeginResult {
+        let mut kps = vec![
+            KeyParameter {
+                tag: Tag::BLOCK_MODE,
+                value: KeyParameterValue::BlockMode(BlockMode::CBC),
+            },
+            KeyParameter {
+                tag: Tag::PADDING,
+                value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
+            },
+        ];
+        if let Some(mut extras) = extra_params {
+            kps.append(&mut extras);
+        }
+        let result = legacy.begin(purpose, &blob, &kps, None);
+        assert!(result.is_ok(), "{:?}", result);
+        result.unwrap()
+    }
+
+    #[test]
+    fn test_begin_abort() {
+        let legacy = get_device_or_skip_test!();
+        let blob = generate_aes_key(legacy.as_ref());
+        let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
+        let operation = begin_result.operation.unwrap();
+        let result = operation.abort();
+        assert!(result.is_ok(), "{:?}", result);
+        let result = operation.abort();
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn test_begin_update_finish() {
+        let legacy = get_device_or_skip_test!();
+        let blob = generate_aes_key(legacy.as_ref());
+
+        let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
+        let operation = begin_result.operation.unwrap();
+
+        let update_aad_result = operation.updateAad(
+            &b"foobar".to_vec(),
+            None, /* authToken */
+            None, /* timestampToken */
+        );
+        assert!(update_aad_result.is_ok(), "{:?}", update_aad_result);
+
+        let message = [42; 128];
+        let result = operation.finish(
+            Some(&message),
+            None, /* signature */
+            None, /* authToken */
+            None, /* timestampToken */
+            None, /* confirmationToken */
+        );
+        assert!(result.is_ok(), "{:?}", result);
+        let ciphertext = result.unwrap();
+        assert!(!ciphertext.is_empty());
+
+        let begin_result =
+            begin(legacy.as_ref(), &blob, KeyPurpose::DECRYPT, Some(begin_result.params));
+
+        let operation = begin_result.operation.unwrap();
+
+        let update_aad_result = operation.updateAad(
+            &b"foobar".to_vec(),
+            None, /* authToken */
+            None, /* timestampToken */
+        );
+        assert!(update_aad_result.is_ok(), "{:?}", update_aad_result);
+
+        let result = operation.update(
+            &ciphertext,
+            None, /* authToken */
+            None, /* timestampToken */
+        );
+        assert!(result.is_ok(), "{:?}", result);
+        assert_eq!(result.unwrap(), message);
+        let result = operation.finish(
+            None, /* input */
+            None, /* signature */
+            None, /* authToken */
+            None, /* timestampToken */
+            None, /* confirmationToken */
+        );
+        assert!(result.is_ok(), "{:?}", result);
+    }
+
+    #[test]
+    fn test_secure_clock() {
+        add_keymint_device_service();
+        let compat_service: binder::Strong<dyn IKeystoreCompatService> =
+            match binder::get_interface(COMPAT_NAME) {
+                Ok(cs) => cs,
+                _ => return,
+            };
+        let secure_clock = match compat_service.getSecureClock() {
+            Ok(sc) => sc,
+            _ => return,
+        };
+
+        let challenge = 42;
+        let result = secure_clock.generateTimeStamp(challenge);
+        assert!(result.is_ok(), "{:?}", result);
+        let result = result.unwrap();
+        assert_eq!(result.challenge, challenge);
+        assert_eq!(result.mac.len(), 32);
+    }
+
+    #[test]
+    fn test_shared_secret() {
+        add_keymint_device_service();
+        let compat_service: binder::Strong<dyn IKeystoreCompatService> =
+            match binder::get_interface(COMPAT_NAME) {
+                Ok(cs) => cs,
+                _ => return,
+            };
+        let shared_secret = match compat_service.getSharedSecret(SecurityLevel::TRUSTED_ENVIRONMENT)
+        {
+            Ok(ss) => ss,
+            _ => return,
+        };
+
+        let result = shared_secret.getSharedSecretParameters();
+        assert!(result.is_ok(), "{:?}", result);
+        let params = result.unwrap();
+
+        let result = shared_secret.computeSharedSecret(&[params]);
+        assert!(result.is_ok(), "{:?}", result);
+        assert_ne!(result.unwrap().len(), 0);
+    }
+}
diff --git a/keystore2/src/km_compat/parameter_conversion_test.cpp b/keystore2/src/km_compat/parameter_conversion_test.cpp
new file mode 100644
index 0000000..48af20c
--- /dev/null
+++ b/keystore2/src/km_compat/parameter_conversion_test.cpp
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2020, 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 <gtest/gtest.h>
+
+#include "km_compat_type_conversion.h"
+
+#define TEST_ENUM_CONVERSION(type, variant)                                                        \
+    ASSERT_EQ(KMV1::type::variant, convert(V4_0::type::variant));                                  \
+    ASSERT_EQ(V4_0::type::variant, convert(KMV1::type::variant))
+
+TEST(KmCompatTypeConversionTest, testEnumCoversion) {
+    TEST_ENUM_CONVERSION(KeyPurpose, ENCRYPT);
+    TEST_ENUM_CONVERSION(KeyPurpose, DECRYPT);
+    TEST_ENUM_CONVERSION(KeyPurpose, SIGN);
+    TEST_ENUM_CONVERSION(KeyPurpose, VERIFY);
+    TEST_ENUM_CONVERSION(KeyPurpose, WRAP_KEY);
+    TEST_ENUM_CONVERSION(Algorithm, RSA);
+    TEST_ENUM_CONVERSION(Algorithm, EC);
+    TEST_ENUM_CONVERSION(Algorithm, AES);
+    TEST_ENUM_CONVERSION(Algorithm, TRIPLE_DES);
+    TEST_ENUM_CONVERSION(Algorithm, HMAC);
+    TEST_ENUM_CONVERSION(Digest, NONE);
+    TEST_ENUM_CONVERSION(Digest, MD5);
+    TEST_ENUM_CONVERSION(Digest, SHA1);
+    TEST_ENUM_CONVERSION(Digest, SHA_2_224);
+    TEST_ENUM_CONVERSION(Digest, SHA_2_256);
+    TEST_ENUM_CONVERSION(Digest, SHA_2_384);
+    TEST_ENUM_CONVERSION(Digest, SHA_2_512);
+    TEST_ENUM_CONVERSION(EcCurve, P_224);
+    TEST_ENUM_CONVERSION(EcCurve, P_256);
+    TEST_ENUM_CONVERSION(EcCurve, P_384);
+    TEST_ENUM_CONVERSION(EcCurve, P_521);
+    TEST_ENUM_CONVERSION(BlockMode, ECB);
+    TEST_ENUM_CONVERSION(BlockMode, CBC);
+    TEST_ENUM_CONVERSION(BlockMode, CTR);
+    TEST_ENUM_CONVERSION(BlockMode, GCM);
+    TEST_ENUM_CONVERSION(PaddingMode, NONE);
+    TEST_ENUM_CONVERSION(PaddingMode, RSA_OAEP);
+    TEST_ENUM_CONVERSION(PaddingMode, RSA_PSS);
+    TEST_ENUM_CONVERSION(PaddingMode, RSA_PKCS1_1_5_ENCRYPT);
+    TEST_ENUM_CONVERSION(PaddingMode, RSA_PKCS1_1_5_SIGN);
+    TEST_ENUM_CONVERSION(PaddingMode, PKCS7);
+    TEST_ENUM_CONVERSION(HardwareAuthenticatorType, PASSWORD);
+    TEST_ENUM_CONVERSION(HardwareAuthenticatorType, FINGERPRINT);
+    TEST_ENUM_CONVERSION(SecurityLevel, SOFTWARE);
+    TEST_ENUM_CONVERSION(SecurityLevel, TRUSTED_ENVIRONMENT);
+    TEST_ENUM_CONVERSION(SecurityLevel, STRONGBOX);
+    TEST_ENUM_CONVERSION(KeyOrigin, GENERATED);
+    TEST_ENUM_CONVERSION(KeyOrigin, DERIVED);
+    TEST_ENUM_CONVERSION(KeyOrigin, IMPORTED);
+    TEST_ENUM_CONVERSION(KeyOrigin, GENERATED);
+    TEST_ENUM_CONVERSION(KeyOrigin, SECURELY_IMPORTED);
+
+    // RESERVED and UNKNOWN correspond but changed their names.
+    ASSERT_EQ(KMV1::KeyOrigin::RESERVED, convert(V4_0::KeyOrigin::UNKNOWN));
+    ASSERT_EQ(V4_0::KeyOrigin::UNKNOWN, convert(KMV1::KeyOrigin::RESERVED));
+}
+
+#define TEST_KEY_PARAMETER_CONVERSION_V4_0(tag)                                                    \
+    do {                                                                                           \
+        auto kmv1_param = KMV1::makeKeyParameter(                                                  \
+            KMV1::tag, KMV1::TypedTag2ValueType<decltype(KMV1::tag)>::type{});                     \
+        auto legacy_param = V4_0::makeKeyParameter(                                                \
+            V4_0::tag, V4_0::TypedTag2ValueType<decltype(V4_0::tag)>::type{});                     \
+        ASSERT_EQ(legacy_param, convertKeyParameterToLegacy(kmv1_param));                          \
+        ASSERT_EQ(kmv1_param, convertKeyParameterFromLegacy(legacy_param));                        \
+    } while (false)
+
+#define TEST_KEY_PARAMETER_CONVERSION_V4_1(tag)                                                    \
+    do {                                                                                           \
+        auto kmv1_param = KMV1::makeKeyParameter(                                                  \
+            KMV1::tag, KMV1::TypedTag2ValueType<decltype(KMV1::tag)>::type{});                     \
+        auto legacy_param = V4_0::makeKeyParameter(                                                \
+            V4_1::tag, V4_0::TypedTag2ValueType<decltype(V4_1::tag)>::type{});                     \
+        ASSERT_EQ(legacy_param, convertKeyParameterToLegacy(kmv1_param));                          \
+        ASSERT_EQ(kmv1_param, convertKeyParameterFromLegacy(legacy_param));                        \
+    } while (false)
+
+TEST(KmCompatTypeConversionTest, testKeyParameterConversion) {
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ACTIVE_DATETIME);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ALGORITHM);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ALLOW_WHILE_ON_BODY);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_APPLICATION_DATA);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_APPLICATION_ID);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ASSOCIATED_DATA);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_APPLICATION_ID);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_CHALLENGE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_BRAND);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_DEVICE);
+    //    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_IMEI);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_MANUFACTURER);
+    //    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_MEID);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_PRODUCT);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_MODEL);
+    //    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ATTESTATION_ID_SERIAL);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_AUTH_TIMEOUT);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_BLOCK_MODE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_BOOTLOADER_ONLY);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_BOOT_PATCHLEVEL);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_CALLER_NONCE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_CONFIRMATION_TOKEN);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_CREATION_DATETIME);
+    TEST_KEY_PARAMETER_CONVERSION_V4_1(TAG_DEVICE_UNIQUE_ATTESTATION);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_DIGEST);
+    TEST_KEY_PARAMETER_CONVERSION_V4_1(TAG_EARLY_BOOT_ONLY);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_EC_CURVE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_HARDWARE_TYPE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_1(TAG_IDENTITY_CREDENTIAL_KEY);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_INCLUDE_UNIQUE_ID);
+    //    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_INVALID);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_KEY_SIZE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_MAC_LENGTH);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_MAX_USES_PER_BOOT);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_MIN_MAC_LENGTH);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_MIN_SECONDS_BETWEEN_OPS);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_NONCE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_NO_AUTH_REQUIRED);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ORIGIN);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ORIGINATION_EXPIRE_DATETIME);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_OS_PATCHLEVEL);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_OS_VERSION);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_PADDING);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_PURPOSE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_RESET_SINCE_ID_ROTATION);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ROLLBACK_RESISTANCE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_ROOT_OF_TRUST);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_RSA_PUBLIC_EXPONENT);
+    TEST_KEY_PARAMETER_CONVERSION_V4_1(TAG_STORAGE_KEY);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_TRUSTED_CONFIRMATION_REQUIRED);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_TRUSTED_USER_PRESENCE_REQUIRED);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_UNIQUE_ID);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_UNLOCKED_DEVICE_REQUIRED);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USAGE_EXPIRE_DATETIME);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_AUTH_TYPE);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_ID);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_USER_SECURE_ID);
+    TEST_KEY_PARAMETER_CONVERSION_V4_0(TAG_VENDOR_PATCHLEVEL);
+}
+
+#define TEST_ERROR_CODE_CONVERSION(variant)                                                        \
+    ASSERT_EQ(KMV1::ErrorCode::variant, convert(V4_0::ErrorCode::variant))
+
+TEST(KmCompatTypeConversionTest, testErrorCodeConversion) {
+    TEST_ERROR_CODE_CONVERSION(OK);
+    TEST_ERROR_CODE_CONVERSION(ROOT_OF_TRUST_ALREADY_SET);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_PURPOSE);
+    TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_PURPOSE);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_ALGORITHM);
+    TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_ALGORITHM);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KEY_SIZE);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_BLOCK_MODE);
+    TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_BLOCK_MODE);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_MAC_LENGTH);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_PADDING_MODE);
+    TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_PADDING_MODE);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_DIGEST);
+    TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_DIGEST);
+    TEST_ERROR_CODE_CONVERSION(INVALID_EXPIRATION_TIME);
+    TEST_ERROR_CODE_CONVERSION(INVALID_USER_ID);
+    TEST_ERROR_CODE_CONVERSION(INVALID_AUTHORIZATION_TIMEOUT);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KEY_FORMAT);
+    TEST_ERROR_CODE_CONVERSION(INCOMPATIBLE_KEY_FORMAT);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KEY_VERIFICATION_ALGORITHM);
+    TEST_ERROR_CODE_CONVERSION(INVALID_INPUT_LENGTH);
+    TEST_ERROR_CODE_CONVERSION(KEY_EXPORT_OPTIONS_INVALID);
+    TEST_ERROR_CODE_CONVERSION(DELEGATION_NOT_ALLOWED);
+    TEST_ERROR_CODE_CONVERSION(KEY_NOT_YET_VALID);
+    TEST_ERROR_CODE_CONVERSION(KEY_EXPIRED);
+    TEST_ERROR_CODE_CONVERSION(KEY_USER_NOT_AUTHENTICATED);
+    TEST_ERROR_CODE_CONVERSION(OUTPUT_PARAMETER_NULL);
+    TEST_ERROR_CODE_CONVERSION(INVALID_OPERATION_HANDLE);
+    TEST_ERROR_CODE_CONVERSION(INSUFFICIENT_BUFFER_SPACE);
+    TEST_ERROR_CODE_CONVERSION(VERIFICATION_FAILED);
+    TEST_ERROR_CODE_CONVERSION(TOO_MANY_OPERATIONS);
+    TEST_ERROR_CODE_CONVERSION(UNEXPECTED_NULL_POINTER);
+    TEST_ERROR_CODE_CONVERSION(INVALID_KEY_BLOB);
+    TEST_ERROR_CODE_CONVERSION(IMPORTED_KEY_NOT_ENCRYPTED);
+    TEST_ERROR_CODE_CONVERSION(IMPORTED_KEY_DECRYPTION_FAILED);
+    TEST_ERROR_CODE_CONVERSION(IMPORTED_KEY_NOT_SIGNED);
+    TEST_ERROR_CODE_CONVERSION(IMPORTED_KEY_VERIFICATION_FAILED);
+    TEST_ERROR_CODE_CONVERSION(INVALID_ARGUMENT);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_TAG);
+    TEST_ERROR_CODE_CONVERSION(INVALID_TAG);
+    TEST_ERROR_CODE_CONVERSION(MEMORY_ALLOCATION_FAILED);
+    TEST_ERROR_CODE_CONVERSION(IMPORT_PARAMETER_MISMATCH);
+    TEST_ERROR_CODE_CONVERSION(SECURE_HW_ACCESS_DENIED);
+    TEST_ERROR_CODE_CONVERSION(OPERATION_CANCELLED);
+    TEST_ERROR_CODE_CONVERSION(CONCURRENT_ACCESS_CONFLICT);
+    TEST_ERROR_CODE_CONVERSION(SECURE_HW_BUSY);
+    TEST_ERROR_CODE_CONVERSION(SECURE_HW_COMMUNICATION_FAILED);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_EC_FIELD);
+    TEST_ERROR_CODE_CONVERSION(MISSING_NONCE);
+    TEST_ERROR_CODE_CONVERSION(INVALID_NONCE);
+    TEST_ERROR_CODE_CONVERSION(MISSING_MAC_LENGTH);
+    TEST_ERROR_CODE_CONVERSION(KEY_RATE_LIMIT_EXCEEDED);
+    TEST_ERROR_CODE_CONVERSION(CALLER_NONCE_PROHIBITED);
+    TEST_ERROR_CODE_CONVERSION(KEY_MAX_OPS_EXCEEDED);
+    TEST_ERROR_CODE_CONVERSION(INVALID_MAC_LENGTH);
+    TEST_ERROR_CODE_CONVERSION(MISSING_MIN_MAC_LENGTH);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_MIN_MAC_LENGTH);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_KDF);
+    TEST_ERROR_CODE_CONVERSION(UNSUPPORTED_EC_CURVE);
+    TEST_ERROR_CODE_CONVERSION(KEY_REQUIRES_UPGRADE);
+    TEST_ERROR_CODE_CONVERSION(ATTESTATION_CHALLENGE_MISSING);
+    ASSERT_EQ(KMV1::ErrorCode::KEYMINT_NOT_CONFIGURED,
+              convert(V4_0::ErrorCode::KEYMASTER_NOT_CONFIGURED));
+    TEST_ERROR_CODE_CONVERSION(ATTESTATION_APPLICATION_ID_MISSING);
+    TEST_ERROR_CODE_CONVERSION(CANNOT_ATTEST_IDS);
+    TEST_ERROR_CODE_CONVERSION(ROLLBACK_RESISTANCE_UNAVAILABLE);
+    TEST_ERROR_CODE_CONVERSION(HARDWARE_TYPE_UNAVAILABLE);
+    TEST_ERROR_CODE_CONVERSION(PROOF_OF_PRESENCE_REQUIRED);
+    TEST_ERROR_CODE_CONVERSION(CONCURRENT_PROOF_OF_PRESENCE_REQUESTED);
+    TEST_ERROR_CODE_CONVERSION(NO_USER_CONFIRMATION);
+    TEST_ERROR_CODE_CONVERSION(DEVICE_LOCKED);
+    TEST_ERROR_CODE_CONVERSION(UNIMPLEMENTED);
+    TEST_ERROR_CODE_CONVERSION(VERSION_MISMATCH);
+    TEST_ERROR_CODE_CONVERSION(UNKNOWN_ERROR);
+}
diff --git a/keystore2/src/km_compat/slot_test.cpp b/keystore2/src/km_compat/slot_test.cpp
new file mode 100644
index 0000000..43f3bc6
--- /dev/null
+++ b/keystore2/src/km_compat/slot_test.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2020, 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 <gtest/gtest.h>
+
+#include "km_compat.h"
+#include <keymint_support/keymint_tags.h>
+
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
+#include <aidl/android/hardware/security/keymint/IKeyMintOperation.h>
+
+using ::aidl::android::hardware::security::keymint::Algorithm;
+using ::aidl::android::hardware::security::keymint::BlockMode;
+using ::aidl::android::hardware::security::keymint::Certificate;
+using ::aidl::android::hardware::security::keymint::Digest;
+using ::aidl::android::hardware::security::keymint::ErrorCode;
+using ::aidl::android::hardware::security::keymint::IKeyMintOperation;
+using ::aidl::android::hardware::security::keymint::KeyCharacteristics;
+using ::aidl::android::hardware::security::keymint::KeyPurpose;
+using ::aidl::android::hardware::security::keymint::PaddingMode;
+using ::aidl::android::hardware::security::keymint::SecurityLevel;
+
+namespace KMV1 = ::aidl::android::hardware::security::keymint;
+
+static std::vector<uint8_t> generateAESKey(std::shared_ptr<KeyMintDevice> device) {
+    auto keyParams = std::vector<KeyParameter>({
+        KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, Algorithm::AES),
+        KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, 128),
+        KMV1::makeKeyParameter(KMV1::TAG_BLOCK_MODE, BlockMode::CBC),
+        KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::NONE),
+        KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED, true),
+        KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::ENCRYPT),
+        KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::DECRYPT),
+    });
+    KeyCreationResult creationResult;
+    auto status = device->generateKey(keyParams, std::nullopt /* attest_key */, &creationResult);
+    if (!status.isOk()) {
+        return {};
+    }
+    return creationResult.keyBlob;
+}
+
+static std::variant<BeginResult, ScopedAStatus> begin(std::shared_ptr<KeyMintDevice> device,
+                                                      bool valid) {
+    auto blob = generateAESKey(device);
+    std::vector<KeyParameter> kps;
+    if (valid) {
+        kps.push_back(KMV1::makeKeyParameter(KMV1::TAG_BLOCK_MODE, BlockMode::CBC));
+        kps.push_back(KMV1::makeKeyParameter(KMV1::TAG_PADDING, PaddingMode::NONE));
+    }
+    BeginResult beginResult;
+    auto status = device->begin(KeyPurpose::ENCRYPT, blob, kps, HardwareAuthToken(), &beginResult);
+    if (!status.isOk()) {
+        return status;
+    }
+    return beginResult;
+}
+
+static const int NUM_SLOTS = 2;
+
+TEST(SlotTest, TestSlots) {
+    static std::shared_ptr<KeyMintDevice> device =
+        KeyMintDevice::createKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
+    device->setNumFreeSlots(NUM_SLOTS);
+
+    // A begin() that returns a failure should not use a slot.
+    auto result = begin(device, false);
+    ASSERT_TRUE(std::holds_alternative<ScopedAStatus>(result));
+
+    // Fill up all the slots.
+    std::vector<std::shared_ptr<IKeyMintOperation>> operations;
+    for (int i = 0; i < NUM_SLOTS; i++) {
+        auto result = begin(device, true);
+        ASSERT_TRUE(std::holds_alternative<BeginResult>(result));
+        operations.push_back(std::get<BeginResult>(result).operation);
+    }
+
+    // We should not be able to create a new operation.
+    result = begin(device, true);
+    ASSERT_TRUE(std::holds_alternative<ScopedAStatus>(result));
+    ASSERT_EQ(std::get<ScopedAStatus>(result).getServiceSpecificError(),
+              static_cast<int32_t>(ErrorCode::TOO_MANY_OPERATIONS));
+
+    // TODO: I'm not sure how to generate a failing update call to test that.
+
+    // Calling finish should free up a slot.
+    auto last = operations.back();
+    operations.pop_back();
+    std::vector<uint8_t> byteVec;
+    auto status = last->finish(std::nullopt /* input */, std::nullopt /* signature */,
+                               std::nullopt /* authToken */, std::nullopt /* timestampToken */,
+                               std::nullopt /* confirmationToken */, &byteVec);
+    ASSERT_TRUE(status.isOk());
+    result = begin(device, true);
+    ASSERT_TRUE(std::holds_alternative<BeginResult>(result));
+    operations.push_back(std::get<BeginResult>(result).operation);
+
+    // Calling finish and abort on an already-finished operation should not free up another slot.
+    status = last->finish(std::nullopt /* input */, std::nullopt /* signature */,
+                          std::nullopt /* authToken */, std::nullopt /* timestampToken */,
+                          std::nullopt /* confirmationToken */, &byteVec);
+    ASSERT_TRUE(!status.isOk());
+    status = last->abort();
+    ASSERT_TRUE(!status.isOk());
+    result = begin(device, true);
+    ASSERT_TRUE(std::holds_alternative<ScopedAStatus>(result));
+    ASSERT_EQ(std::get<ScopedAStatus>(result).getServiceSpecificError(),
+              static_cast<int32_t>(ErrorCode::TOO_MANY_OPERATIONS));
+
+    // Calling abort should free up a slot.
+    last = operations.back();
+    operations.pop_back();
+    status = last->abort();
+    ASSERT_TRUE(status.isOk());
+    result = begin(device, true);
+    ASSERT_TRUE(std::holds_alternative<BeginResult>(result));
+    operations.push_back(std::get<BeginResult>(result).operation);
+
+    // Calling finish and abort on an already-aborted operation should not free up another slot.
+    status = last->finish(std::nullopt /* input */, std::nullopt /* signature */,
+                          std::nullopt /* authToken */, std::nullopt /* timestampToken */,
+                          std::nullopt /* confirmationToken */, &byteVec);
+    ASSERT_TRUE(!status.isOk());
+    status = last->abort();
+    ASSERT_TRUE(!status.isOk());
+    result = begin(device, true);
+    ASSERT_TRUE(std::holds_alternative<ScopedAStatus>(result));
+    ASSERT_EQ(std::get<ScopedAStatus>(result).getServiceSpecificError(),
+              static_cast<int32_t>(ErrorCode::TOO_MANY_OPERATIONS));
+
+    // Generating a certificate with signWith uses a slot but falls back to not using one.
+    auto kps = std::vector<KeyParameter>({
+        KMV1::makeKeyParameter(KMV1::TAG_ALGORITHM, Algorithm::RSA),
+        KMV1::makeKeyParameter(KMV1::TAG_KEY_SIZE, 2048),
+        KMV1::makeKeyParameter(KMV1::TAG_RSA_PUBLIC_EXPONENT, 65537),
+        KMV1::makeKeyParameter(KMV1::TAG_DIGEST, Digest::SHA_2_256),
+        KMV1::makeKeyParameter(KMV1::TAG_PURPOSE, KeyPurpose::SIGN),
+        KMV1::makeKeyParameter(KMV1::TAG_CERTIFICATE_NOT_BEFORE, 0),
+        KMV1::makeKeyParameter(KMV1::TAG_CERTIFICATE_NOT_AFTER, 253402300799000),
+        KMV1::makeKeyParameter(KMV1::TAG_NO_AUTH_REQUIRED, true),
+    });
+    KeyCreationResult creationResult;
+    status = device->generateKey(kps, std::nullopt /* attest_key */, &creationResult);
+    ASSERT_TRUE(status.isOk());
+    // But generating a certificate with signCert does not use a slot.
+    kps.pop_back();
+    status = device->generateKey(kps, std::nullopt /* attest_key */, &creationResult);
+    ASSERT_TRUE(status.isOk());
+
+    // Destructing operations should free up their slots.
+    operations.clear();
+    result = begin(device, true);
+    ASSERT_TRUE(std::holds_alternative<BeginResult>(result));
+}
diff --git a/keystore2/src/legacy_blob.rs b/keystore2/src/legacy_blob.rs
new file mode 100644
index 0000000..29d46ad
--- /dev/null
+++ b/keystore2/src/legacy_blob.rs
@@ -0,0 +1,1391 @@
+// Copyright 2020, 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.
+
+//! This module implements methods to load legacy keystore key blob files.
+
+#![allow(clippy::redundant_slicing)]
+
+use crate::{
+    error::{Error as KsError, ResponseCode},
+    key_parameter::{KeyParameter, KeyParameterValue},
+    super_key::SuperKeyManager,
+    utils::uid_to_android_user,
+};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    SecurityLevel::SecurityLevel, Tag::Tag, TagType::TagType,
+};
+use anyhow::{Context, Result};
+use keystore2_crypto::{aes_gcm_decrypt, Password, ZVec};
+use std::collections::{HashMap, HashSet};
+use std::{convert::TryInto, fs::File, path::Path, path::PathBuf};
+use std::{
+    fs,
+    io::{ErrorKind, Read, Result as IoResult},
+};
+
+const SUPPORTED_LEGACY_BLOB_VERSION: u8 = 3;
+
+mod flags {
+    /// This flag is deprecated. It is here to support keys that have been written with this flag
+    /// set, but we don't create any new keys with this flag.
+    pub const ENCRYPTED: u8 = 1 << 0;
+    /// This flag is deprecated. It indicates that the blob was generated and thus owned by a
+    /// software fallback Keymaster implementation. Keymaster 1.0 was the last Keymaster version
+    /// that could be accompanied by a software fallback. With the removal of Keymaster 1.0
+    /// support, this flag is obsolete.
+    pub const FALLBACK: u8 = 1 << 1;
+    /// KEYSTORE_FLAG_SUPER_ENCRYPTED is for blobs that are already encrypted by KM but have
+    /// an additional layer of password-based encryption applied. The same encryption scheme is used
+    /// as KEYSTORE_FLAG_ENCRYPTED. The latter is deprecated.
+    pub const SUPER_ENCRYPTED: u8 = 1 << 2;
+    /// KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION is for blobs that are part of device encryption
+    /// flow so it receives special treatment from keystore. For example this blob will not be super
+    /// encrypted, and it will be stored separately under a unique UID instead. This flag should
+    /// only be available to system uid.
+    pub const CRITICAL_TO_DEVICE_ENCRYPTION: u8 = 1 << 3;
+    /// The blob is associated with the security level Strongbox as opposed to TEE.
+    pub const STRONGBOX: u8 = 1 << 4;
+}
+
+/// Lagacy key blob types.
+mod blob_types {
+    /// A generic blob used for non sensitive unstructured blobs.
+    pub const GENERIC: u8 = 1;
+    /// This key is a super encryption key encrypted with AES128
+    /// and a password derived key.
+    pub const SUPER_KEY: u8 = 2;
+    // Used to be the KEY_PAIR type.
+    const _RESERVED: u8 = 3;
+    /// A KM key blob.
+    pub const KM_BLOB: u8 = 4;
+    /// A legacy key characteristics file. This has only a single list of Authorizations.
+    pub const KEY_CHARACTERISTICS: u8 = 5;
+    /// A key characteristics cache has both a hardware enforced and a software enforced list
+    /// of authorizations.
+    pub const KEY_CHARACTERISTICS_CACHE: u8 = 6;
+    /// Like SUPER_KEY but encrypted with AES256.
+    pub const SUPER_KEY_AES256: u8 = 7;
+}
+
+/// Error codes specific to the legacy blob module.
+#[derive(thiserror::Error, Debug, Eq, PartialEq)]
+pub enum Error {
+    /// Returned by the legacy blob module functions if an input stream
+    /// did not have enough bytes to read.
+    #[error("Input stream had insufficient bytes to read.")]
+    BadLen,
+    /// This error code is returned by `Blob::decode_alias` if it encounters
+    /// an invalid alias filename encoding.
+    #[error("Invalid alias filename encoding.")]
+    BadEncoding,
+}
+
+/// The blob payload, optionally with all information required to decrypt it.
+#[derive(Debug, Eq, PartialEq)]
+pub enum BlobValue {
+    /// A generic blob used for non sensitive unstructured blobs.
+    Generic(Vec<u8>),
+    /// A legacy key characteristics file. This has only a single list of Authorizations.
+    Characteristics(Vec<u8>),
+    /// A key characteristics cache has both a hardware enforced and a software enforced list
+    /// of authorizations.
+    CharacteristicsCache(Vec<u8>),
+    /// A password encrypted blob. Includes the initialization vector, the aead tag, the
+    /// ciphertext data, a salt, and a key size. The latter two are used for key derivation.
+    PwEncrypted {
+        /// Initialization vector.
+        iv: Vec<u8>,
+        /// Aead tag for integrity verification.
+        tag: Vec<u8>,
+        /// Ciphertext.
+        data: Vec<u8>,
+        /// Salt for key derivation.
+        salt: Vec<u8>,
+        /// Key sise for key derivation. This selects between AES128 GCM and AES256 GCM.
+        key_size: usize,
+    },
+    /// An encrypted blob. Includes the initialization vector, the aead tag, and the
+    /// ciphertext data. The key can be selected from context, i.e., the owner of the key
+    /// blob.
+    Encrypted {
+        /// Initialization vector.
+        iv: Vec<u8>,
+        /// Aead tag for integrity verification.
+        tag: Vec<u8>,
+        /// Ciphertext.
+        data: Vec<u8>,
+    },
+    /// Holds the plaintext key blob either after unwrapping an encrypted blob or when the
+    /// blob was stored in "plaintext" on disk. The "plaintext" of a key blob is not actual
+    /// plaintext because all KeyMint blobs are encrypted with a device bound key. The key
+    /// blob in this Variant is decrypted only with respect to any extra layer of encryption
+    /// that Keystore added.
+    Decrypted(ZVec),
+}
+
+/// Represents a loaded legacy key blob file.
+#[derive(Debug, Eq, PartialEq)]
+pub struct Blob {
+    flags: u8,
+    value: BlobValue,
+}
+
+/// This object represents a path that holds a legacy Keystore blob database.
+pub struct LegacyBlobLoader {
+    path: PathBuf,
+}
+
+fn read_bool(stream: &mut dyn Read) -> Result<bool> {
+    const SIZE: usize = std::mem::size_of::<bool>();
+    let mut buffer: [u8; SIZE] = [0; SIZE];
+    stream.read_exact(&mut buffer).map(|_| buffer[0] != 0).context("In read_ne_bool.")
+}
+
+fn read_ne_u32(stream: &mut dyn Read) -> Result<u32> {
+    const SIZE: usize = std::mem::size_of::<u32>();
+    let mut buffer: [u8; SIZE] = [0; SIZE];
+    stream.read_exact(&mut buffer).map(|_| u32::from_ne_bytes(buffer)).context("In read_ne_u32.")
+}
+
+fn read_ne_i32(stream: &mut dyn Read) -> Result<i32> {
+    const SIZE: usize = std::mem::size_of::<i32>();
+    let mut buffer: [u8; SIZE] = [0; SIZE];
+    stream.read_exact(&mut buffer).map(|_| i32::from_ne_bytes(buffer)).context("In read_ne_i32.")
+}
+
+fn read_ne_i64(stream: &mut dyn Read) -> Result<i64> {
+    const SIZE: usize = std::mem::size_of::<i64>();
+    let mut buffer: [u8; SIZE] = [0; SIZE];
+    stream.read_exact(&mut buffer).map(|_| i64::from_ne_bytes(buffer)).context("In read_ne_i64.")
+}
+
+impl Blob {
+    /// This blob was generated with a fallback software KM device.
+    pub fn is_fallback(&self) -> bool {
+        self.flags & flags::FALLBACK != 0
+    }
+
+    /// This blob is encrypted and needs to be decrypted with the user specific master key
+    /// before use.
+    pub fn is_encrypted(&self) -> bool {
+        self.flags & (flags::SUPER_ENCRYPTED | flags::ENCRYPTED) != 0
+    }
+
+    /// This blob is critical to device encryption. It cannot be encrypted with the super key
+    /// because it is itself part of the key derivation process for the key encrypting the
+    /// super key.
+    pub fn is_critical_to_device_encryption(&self) -> bool {
+        self.flags & flags::CRITICAL_TO_DEVICE_ENCRYPTION != 0
+    }
+
+    /// This blob is associated with the Strongbox security level.
+    pub fn is_strongbox(&self) -> bool {
+        self.flags & flags::STRONGBOX != 0
+    }
+
+    /// Returns the payload data of this blob file.
+    pub fn value(&self) -> &BlobValue {
+        &self.value
+    }
+
+    /// Consume this blob structure and extract the payload.
+    pub fn take_value(self) -> BlobValue {
+        self.value
+    }
+}
+
+impl LegacyBlobLoader {
+    const IV_SIZE: usize = keystore2_crypto::LEGACY_IV_LENGTH;
+    const GCM_TAG_LENGTH: usize = keystore2_crypto::TAG_LENGTH;
+    const SALT_SIZE: usize = keystore2_crypto::SALT_LENGTH;
+
+    // The common header has the following structure:
+    // version (1 Byte)
+    // blob_type (1 Byte)
+    // flags (1 Byte)
+    // info (1 Byte)
+    // initialization_vector (16 Bytes)
+    // integrity (MD5 digest or gcm tag) (16 Bytes)
+    // length (4 Bytes)
+    const COMMON_HEADER_SIZE: usize = 4 + Self::IV_SIZE + Self::GCM_TAG_LENGTH + 4;
+
+    const VERSION_OFFSET: usize = 0;
+    const TYPE_OFFSET: usize = 1;
+    const FLAGS_OFFSET: usize = 2;
+    const SALT_SIZE_OFFSET: usize = 3;
+    const LENGTH_OFFSET: usize = 4 + Self::IV_SIZE + Self::GCM_TAG_LENGTH;
+    const IV_OFFSET: usize = 4;
+    const AEAD_TAG_OFFSET: usize = Self::IV_OFFSET + Self::IV_SIZE;
+    const _DIGEST_OFFSET: usize = Self::IV_OFFSET + Self::IV_SIZE;
+
+    /// Construct a new LegacyBlobLoader with a root path of `path` relative to which it will
+    /// expect legacy key blob files.
+    pub fn new(path: &Path) -> Self {
+        Self { path: path.to_owned() }
+    }
+
+    /// Encodes an alias string as ascii character sequence in the range
+    /// ['+' .. '.'] and ['0' .. '~'].
+    /// Bytes with values in the range ['0' .. '~'] are represented as they are.
+    /// All other bytes are split into two characters as follows:
+    ///
+    ///      msb a a | b b b b b b
+    ///
+    /// The most significant bits (a) are encoded:
+    ///   a a  character
+    ///   0 0     '+'
+    ///   0 1     ','
+    ///   1 0     '-'
+    ///   1 1     '.'
+    ///
+    /// The 6 lower bits are represented with the range ['0' .. 'o']:
+    ///   b(hex)  character
+    ///   0x00     '0'
+    ///       ...
+    ///   0x3F     'o'
+    ///
+    /// The function cannot fail because we have a representation for each
+    /// of the 256 possible values of each byte.
+    pub fn encode_alias(name: &str) -> String {
+        let mut acc = String::new();
+        for c in name.bytes() {
+            match c {
+                b'0'..=b'~' => {
+                    acc.push(c as char);
+                }
+                c => {
+                    acc.push((b'+' + (c as u8 >> 6)) as char);
+                    acc.push((b'0' + (c & 0x3F)) as char);
+                }
+            };
+        }
+        acc
+    }
+
+    /// This function reverses the encoding described in `encode_alias`.
+    /// This function can fail, because not all possible character
+    /// sequences are valid code points. And even if the encoding is valid,
+    /// the result may not be a valid UTF-8 sequence.
+    pub fn decode_alias(name: &str) -> Result<String> {
+        let mut multi: Option<u8> = None;
+        let mut s = Vec::<u8>::new();
+        for c in name.bytes() {
+            multi = match (c, multi) {
+                // m is set, we are processing the second part of a multi byte sequence
+                (b'0'..=b'o', Some(m)) => {
+                    s.push(m | (c - b'0'));
+                    None
+                }
+                (b'+'..=b'.', None) => Some((c - b'+') << 6),
+                (b'0'..=b'~', None) => {
+                    s.push(c);
+                    None
+                }
+                _ => {
+                    return Err(Error::BadEncoding)
+                        .context("In decode_alias: could not decode filename.")
+                }
+            };
+        }
+        if multi.is_some() {
+            return Err(Error::BadEncoding).context("In decode_alias: could not decode filename.");
+        }
+
+        String::from_utf8(s).context("In decode_alias: encoded alias was not valid UTF-8.")
+    }
+
+    fn new_from_stream(stream: &mut dyn Read) -> Result<Blob> {
+        let mut buffer = Vec::new();
+        stream.read_to_end(&mut buffer).context("In new_from_stream.")?;
+
+        if buffer.len() < Self::COMMON_HEADER_SIZE {
+            return Err(Error::BadLen).context("In new_from_stream.")?;
+        }
+
+        let version: u8 = buffer[Self::VERSION_OFFSET];
+
+        let flags: u8 = buffer[Self::FLAGS_OFFSET];
+        let blob_type: u8 = buffer[Self::TYPE_OFFSET];
+        let is_encrypted = flags & (flags::ENCRYPTED | flags::SUPER_ENCRYPTED) != 0;
+        let salt = match buffer[Self::SALT_SIZE_OFFSET] as usize {
+            Self::SALT_SIZE => Some(&buffer[buffer.len() - Self::SALT_SIZE..buffer.len()]),
+            _ => None,
+        };
+
+        if version != SUPPORTED_LEGACY_BLOB_VERSION {
+            return Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED))
+                .context(format!("In new_from_stream: Unknown blob version: {}.", version));
+        }
+
+        let length = u32::from_be_bytes(
+            buffer[Self::LENGTH_OFFSET..Self::LENGTH_OFFSET + 4].try_into().unwrap(),
+        ) as usize;
+        if buffer.len() < Self::COMMON_HEADER_SIZE + length {
+            return Err(Error::BadLen).context(format!(
+                "In new_from_stream. Expected: {} got: {}.",
+                Self::COMMON_HEADER_SIZE + length,
+                buffer.len()
+            ));
+        }
+        let value = &buffer[Self::COMMON_HEADER_SIZE..Self::COMMON_HEADER_SIZE + length];
+        let iv = &buffer[Self::IV_OFFSET..Self::IV_OFFSET + Self::IV_SIZE];
+        let tag = &buffer[Self::AEAD_TAG_OFFSET..Self::AEAD_TAG_OFFSET + Self::GCM_TAG_LENGTH];
+
+        match (blob_type, is_encrypted, salt) {
+            (blob_types::GENERIC, _, _) => {
+                Ok(Blob { flags, value: BlobValue::Generic(value.to_vec()) })
+            }
+            (blob_types::KEY_CHARACTERISTICS, _, _) => {
+                Ok(Blob { flags, value: BlobValue::Characteristics(value.to_vec()) })
+            }
+            (blob_types::KEY_CHARACTERISTICS_CACHE, _, _) => {
+                Ok(Blob { flags, value: BlobValue::CharacteristicsCache(value.to_vec()) })
+            }
+            (blob_types::SUPER_KEY, _, Some(salt)) => Ok(Blob {
+                flags,
+                value: BlobValue::PwEncrypted {
+                    iv: iv.to_vec(),
+                    tag: tag.to_vec(),
+                    data: value.to_vec(),
+                    key_size: keystore2_crypto::AES_128_KEY_LENGTH,
+                    salt: salt.to_vec(),
+                },
+            }),
+            (blob_types::SUPER_KEY_AES256, _, Some(salt)) => Ok(Blob {
+                flags,
+                value: BlobValue::PwEncrypted {
+                    iv: iv.to_vec(),
+                    tag: tag.to_vec(),
+                    data: value.to_vec(),
+                    key_size: keystore2_crypto::AES_256_KEY_LENGTH,
+                    salt: salt.to_vec(),
+                },
+            }),
+            (blob_types::KM_BLOB, true, _) => Ok(Blob {
+                flags,
+                value: BlobValue::Encrypted {
+                    iv: iv.to_vec(),
+                    tag: tag.to_vec(),
+                    data: value.to_vec(),
+                },
+            }),
+            (blob_types::KM_BLOB, false, _) => Ok(Blob {
+                flags,
+                value: BlobValue::Decrypted(value.try_into().context("In new_from_stream.")?),
+            }),
+            (blob_types::SUPER_KEY, _, None) | (blob_types::SUPER_KEY_AES256, _, None) => {
+                Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED))
+                    .context("In new_from_stream: Super key without salt for key derivation.")
+            }
+            _ => Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
+                "In new_from_stream: Unknown blob type. {} {}",
+                blob_type, is_encrypted
+            )),
+        }
+    }
+
+    /// Parses a legacy key blob file read from `stream`. A `decrypt` closure
+    /// must be supplied, that is primed with the appropriate key.
+    /// The callback takes the following arguments:
+    ///  * ciphertext: &[u8] - The to-be-deciphered message.
+    ///  * iv: &[u8] - The initialization vector.
+    ///  * tag: Option<&[u8]> - AEAD tag if AES GCM is selected.
+    ///  * salt: Option<&[u8]> - An optional salt. Used for password key derivation.
+    ///  * key_size: Option<usize> - An optional key size. Used for pw key derivation.
+    ///
+    /// If no super key is available, the callback must return
+    /// `Err(KsError::Rc(ResponseCode::LOCKED))`. The callback is only called
+    /// if the to-be-read blob is encrypted.
+    pub fn new_from_stream_decrypt_with<F>(mut stream: impl Read, decrypt: F) -> Result<Blob>
+    where
+        F: FnOnce(&[u8], &[u8], &[u8], Option<&[u8]>, Option<usize>) -> Result<ZVec>,
+    {
+        let blob =
+            Self::new_from_stream(&mut stream).context("In new_from_stream_decrypt_with.")?;
+
+        match blob.value() {
+            BlobValue::Encrypted { iv, tag, data } => Ok(Blob {
+                flags: blob.flags,
+                value: BlobValue::Decrypted(
+                    decrypt(&data, &iv, &tag, None, None)
+                        .context("In new_from_stream_decrypt_with.")?,
+                ),
+            }),
+            BlobValue::PwEncrypted { iv, tag, data, salt, key_size } => Ok(Blob {
+                flags: blob.flags,
+                value: BlobValue::Decrypted(
+                    decrypt(&data, &iv, &tag, Some(salt), Some(*key_size))
+                        .context("In new_from_stream_decrypt_with.")?,
+                ),
+            }),
+            _ => Ok(blob),
+        }
+    }
+
+    fn tag_type(tag: Tag) -> TagType {
+        TagType((tag.0 as u32 & 0xFF000000u32) as i32)
+    }
+
+    /// Read legacy key parameter file content.
+    /// Depending on the file type a key characteristics file stores one (TYPE_KEY_CHARACTERISTICS)
+    /// or two (TYPE_KEY_CHARACTERISTICS_CACHE) key parameter lists. The format of the list is as
+    /// follows:
+    ///
+    /// +------------------------------+
+    /// | 32 bit indirect_size         |
+    /// +------------------------------+
+    /// | indirect_size bytes of data  |     This is where the blob data is stored
+    /// +------------------------------+
+    /// | 32 bit element_count         |     Number of key parameter entries.
+    /// | 32 bit elements_size         |     Total bytes used by entries.
+    /// +------------------------------+
+    /// | elements_size bytes of data  |     This is where the elements are stored.
+    /// +------------------------------+
+    ///
+    /// Elements have a 32 bit header holding the tag with a tag type encoded in the
+    /// four most significant bits (see android/hardware/secruity/keymint/TagType.aidl).
+    /// The header is immediately followed by the payload. The payload size depends on
+    /// the encoded tag type in the header:
+    ///      BOOLEAN                          :    1 byte
+    ///      ENUM, ENUM_REP, UINT, UINT_REP   :    4 bytes
+    ///      ULONG, ULONG_REP, DATETIME       :    8 bytes
+    ///      BLOB, BIGNUM                     :    8 bytes see below.
+    ///
+    /// Bignum and blob payload format:
+    /// +------------------------+
+    /// | 32 bit blob_length     |    Length of the indirect payload in bytes.
+    /// | 32 bit indirect_offset |    Offset from the beginning of the indirect section.
+    /// +------------------------+
+    pub fn read_key_parameters(stream: &mut &[u8]) -> Result<Vec<KeyParameterValue>> {
+        let indirect_size =
+            read_ne_u32(stream).context("In read_key_parameters: While reading indirect size.")?;
+
+        let indirect_buffer = stream
+            .get(0..indirect_size as usize)
+            .ok_or(KsError::Rc(ResponseCode::VALUE_CORRUPTED))
+            .context("In read_key_parameters: While reading indirect buffer.")?;
+
+        // update the stream position.
+        *stream = &stream[indirect_size as usize..];
+
+        let element_count =
+            read_ne_u32(stream).context("In read_key_parameters: While reading element count.")?;
+        let element_size =
+            read_ne_u32(stream).context("In read_key_parameters: While reading element size.")?;
+
+        let elements_buffer = stream
+            .get(0..element_size as usize)
+            .ok_or(KsError::Rc(ResponseCode::VALUE_CORRUPTED))
+            .context("In read_key_parameters: While reading elements buffer.")?;
+
+        // update the stream position.
+        *stream = &stream[element_size as usize..];
+
+        let mut element_stream = &elements_buffer[..];
+
+        let mut params: Vec<KeyParameterValue> = Vec::new();
+        for _ in 0..element_count {
+            let tag = Tag(read_ne_i32(&mut element_stream).context("In read_key_parameters.")?);
+            let param = match Self::tag_type(tag) {
+                TagType::ENUM | TagType::ENUM_REP | TagType::UINT | TagType::UINT_REP => {
+                    KeyParameterValue::new_from_tag_primitive_pair(
+                        tag,
+                        read_ne_i32(&mut element_stream).context("While reading integer.")?,
+                    )
+                    .context("Trying to construct integer/enum KeyParameterValue.")
+                }
+                TagType::ULONG | TagType::ULONG_REP | TagType::DATE => {
+                    KeyParameterValue::new_from_tag_primitive_pair(
+                        tag,
+                        read_ne_i64(&mut element_stream).context("While reading long integer.")?,
+                    )
+                    .context("Trying to construct long KeyParameterValue.")
+                }
+                TagType::BOOL => {
+                    if read_bool(&mut element_stream).context("While reading long integer.")? {
+                        KeyParameterValue::new_from_tag_primitive_pair(tag, 1)
+                            .context("Trying to construct boolean KeyParameterValue.")
+                    } else {
+                        Err(anyhow::anyhow!("Invalid."))
+                    }
+                }
+                TagType::BYTES | TagType::BIGNUM => {
+                    let blob_size = read_ne_u32(&mut element_stream)
+                        .context("While reading blob size.")?
+                        as usize;
+                    let indirect_offset = read_ne_u32(&mut element_stream)
+                        .context("While reading indirect offset.")?
+                        as usize;
+                    KeyParameterValue::new_from_tag_primitive_pair(
+                        tag,
+                        indirect_buffer
+                            .get(indirect_offset..indirect_offset + blob_size)
+                            .context("While reading blob value.")?
+                            .to_vec(),
+                    )
+                    .context("Trying to construct blob KeyParameterValue.")
+                }
+                TagType::INVALID => Err(anyhow::anyhow!("Invalid.")),
+                _ => {
+                    return Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED))
+                        .context("In read_key_parameters: Encountered bogus tag type.");
+                }
+            };
+            if let Ok(p) = param {
+                params.push(p);
+            }
+        }
+
+        Ok(params)
+    }
+
+    fn read_characteristics_file(
+        &self,
+        uid: u32,
+        prefix: &str,
+        alias: &str,
+        hw_sec_level: SecurityLevel,
+    ) -> Result<Vec<KeyParameter>> {
+        let blob = Self::read_generic_blob(&self.make_chr_filename(uid, alias, prefix))
+            .context("In read_characteristics_file")?;
+
+        let blob = match blob {
+            None => return Ok(Vec::new()),
+            Some(blob) => blob,
+        };
+
+        let mut stream = match blob.value() {
+            BlobValue::Characteristics(data) => &data[..],
+            BlobValue::CharacteristicsCache(data) => &data[..],
+            _ => {
+                return Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED)).context(concat!(
+                    "In read_characteristics_file: ",
+                    "Characteristics file does not hold key characteristics."
+                ))
+            }
+        };
+
+        let hw_list = match blob.value() {
+            // The characteristics cache file has two lists and the first is
+            // the hardware enforced list.
+            BlobValue::CharacteristicsCache(_) => Some(
+                Self::read_key_parameters(&mut stream)
+                    .context("In read_characteristics_file.")?
+                    .into_iter()
+                    .map(|value| KeyParameter::new(value, hw_sec_level)),
+            ),
+            _ => None,
+        };
+
+        let sw_list = Self::read_key_parameters(&mut stream)
+            .context("In read_characteristics_file.")?
+            .into_iter()
+            .map(|value| KeyParameter::new(value, SecurityLevel::KEYSTORE));
+
+        Ok(hw_list.into_iter().flatten().chain(sw_list).collect())
+    }
+
+    // This is a list of known prefixes that the Keystore 1.0 SPI used to use.
+    //  * USRPKEY was used for private and secret key material, i.e., KM blobs.
+    //  * USRSKEY was used for secret key material, i.e., KM blobs, before Android P.
+    //  * CACERT  was used for key chains or free standing public certificates.
+    //  * USRCERT was used for public certificates of USRPKEY entries. But KeyChain also
+    //            used this for user installed certificates without private key material.
+
+    fn read_km_blob_file(&self, uid: u32, alias: &str) -> Result<Option<(Blob, String)>> {
+        let mut iter = ["USRPKEY", "USRSKEY"].iter();
+
+        let (blob, prefix) = loop {
+            if let Some(prefix) = iter.next() {
+                if let Some(blob) =
+                    Self::read_generic_blob(&self.make_blob_filename(uid, alias, prefix))
+                        .context("In read_km_blob_file.")?
+                {
+                    break (blob, prefix);
+                }
+            } else {
+                return Ok(None);
+            }
+        };
+
+        Ok(Some((blob, prefix.to_string())))
+    }
+
+    fn read_generic_blob(path: &Path) -> Result<Option<Blob>> {
+        let mut file = match Self::with_retry_interrupted(|| File::open(path)) {
+            Ok(file) => file,
+            Err(e) => match e.kind() {
+                ErrorKind::NotFound => return Ok(None),
+                _ => return Err(e).context("In read_generic_blob."),
+            },
+        };
+
+        Ok(Some(Self::new_from_stream(&mut file).context("In read_generic_blob.")?))
+    }
+
+    /// Read a legacy vpn profile blob.
+    pub fn read_vpn_profile(&self, uid: u32, alias: &str) -> Result<Option<Vec<u8>>> {
+        let path = match self.make_vpn_profile_filename(uid, alias) {
+            Some(path) => path,
+            None => return Ok(None),
+        };
+
+        let blob =
+            Self::read_generic_blob(&path).context("In read_vpn_profile: Failed to read blob.")?;
+
+        Ok(blob.and_then(|blob| match blob.value {
+            BlobValue::Generic(blob) => Some(blob),
+            _ => {
+                log::info!("Unexpected vpn profile blob type. Ignoring");
+                None
+            }
+        }))
+    }
+
+    /// Remove a vpn profile by the name alias with owner uid.
+    pub fn remove_vpn_profile(&self, uid: u32, alias: &str) -> Result<()> {
+        let path = match self.make_vpn_profile_filename(uid, alias) {
+            Some(path) => path,
+            None => return Ok(()),
+        };
+
+        if let Err(e) = Self::with_retry_interrupted(|| fs::remove_file(path.as_path())) {
+            match e.kind() {
+                ErrorKind::NotFound => return Ok(()),
+                _ => return Err(e).context("In remove_vpn_profile."),
+            }
+        }
+
+        let user_id = uid_to_android_user(uid);
+        self.remove_user_dir_if_empty(user_id)
+            .context("In remove_vpn_profile: Trying to remove empty user dir.")
+    }
+
+    fn is_vpn_profile(encoded_alias: &str) -> bool {
+        // We can check the encoded alias because the prefixes we are interested
+        // in are all in the printable range that don't get mangled.
+        encoded_alias.starts_with("VPN_")
+            || encoded_alias.starts_with("PLATFORM_VPN_")
+            || encoded_alias == "LOCKDOWN_VPN"
+    }
+
+    /// List all profiles belonging to the given uid.
+    pub fn list_vpn_profiles(&self, uid: u32) -> Result<Vec<String>> {
+        let mut path = self.path.clone();
+        let user_id = uid_to_android_user(uid);
+        path.push(format!("user_{}", user_id));
+        let uid_str = uid.to_string();
+        let dir = match Self::with_retry_interrupted(|| fs::read_dir(path.as_path())) {
+            Ok(dir) => dir,
+            Err(e) => match e.kind() {
+                ErrorKind::NotFound => return Ok(Default::default()),
+                _ => {
+                    return Err(e).context(format!(
+                        "In list_vpn_profiles: Failed to open legacy blob database. {:?}",
+                        path
+                    ))
+                }
+            },
+        };
+        let mut result: Vec<String> = Vec::new();
+        for entry in dir {
+            let file_name =
+                entry.context("In list_vpn_profiles: Trying to access dir entry")?.file_name();
+            if let Some(f) = file_name.to_str() {
+                let encoded_alias = &f[uid_str.len() + 1..];
+                if f.starts_with(&uid_str) && Self::is_vpn_profile(encoded_alias) {
+                    result.push(
+                        Self::decode_alias(encoded_alias)
+                            .context("In list_vpn_profiles: Trying to decode alias.")?,
+                    )
+                }
+            }
+        }
+        Ok(result)
+    }
+
+    /// This function constructs the vpn_profile file name which has the form:
+    /// user_<android user id>/<uid>_<alias>.
+    fn make_vpn_profile_filename(&self, uid: u32, alias: &str) -> Option<PathBuf> {
+        // legacy vpn entries must start with VPN_ or PLATFORM_VPN_ or are literally called
+        // LOCKDOWN_VPN.
+        if !Self::is_vpn_profile(alias) {
+            return None;
+        }
+
+        let mut path = self.path.clone();
+        let user_id = uid_to_android_user(uid);
+        let encoded_alias = Self::encode_alias(alias);
+        path.push(format!("user_{}", user_id));
+        path.push(format!("{}_{}", uid, encoded_alias));
+        Some(path)
+    }
+
+    /// This function constructs the blob file name which has the form:
+    /// user_<android user id>/<uid>_<prefix>_<alias>.
+    fn make_blob_filename(&self, uid: u32, alias: &str, prefix: &str) -> PathBuf {
+        let user_id = uid_to_android_user(uid);
+        let encoded_alias = Self::encode_alias(&format!("{}_{}", prefix, alias));
+        let mut path = self.make_user_path_name(user_id);
+        path.push(format!("{}_{}", uid, encoded_alias));
+        path
+    }
+
+    /// This function constructs the characteristics file name which has the form:
+    /// user_<android user id>/.<uid>_chr_<prefix>_<alias>.
+    fn make_chr_filename(&self, uid: u32, alias: &str, prefix: &str) -> PathBuf {
+        let user_id = uid_to_android_user(uid);
+        let encoded_alias = Self::encode_alias(&format!("{}_{}", prefix, alias));
+        let mut path = self.make_user_path_name(user_id);
+        path.push(format!(".{}_chr_{}", uid, encoded_alias));
+        path
+    }
+
+    fn make_super_key_filename(&self, user_id: u32) -> PathBuf {
+        let mut path = self.make_user_path_name(user_id);
+        path.push(".masterkey");
+        path
+    }
+
+    fn make_user_path_name(&self, user_id: u32) -> PathBuf {
+        let mut path = self.path.clone();
+        path.push(&format!("user_{}", user_id));
+        path
+    }
+
+    /// Returns if the legacy blob database is empty, i.e., there are no entries matching "user_*"
+    /// in the database dir.
+    pub fn is_empty(&self) -> Result<bool> {
+        let dir = Self::with_retry_interrupted(|| fs::read_dir(self.path.as_path()))
+            .context("In is_empty: Failed to open legacy blob database.")?;
+        for entry in dir {
+            if (*entry.context("In is_empty: Trying to access dir entry")?.file_name())
+                .to_str()
+                .map_or(false, |f| f.starts_with("user_"))
+            {
+                return Ok(false);
+            }
+        }
+        Ok(true)
+    }
+
+    /// Returns if the legacy blob database is empty for a given user, i.e., there are no entries
+    /// matching "user_*" in the database dir.
+    pub fn is_empty_user(&self, user_id: u32) -> Result<bool> {
+        let mut user_path = self.path.clone();
+        user_path.push(format!("user_{}", user_id));
+        if !user_path.as_path().is_dir() {
+            return Ok(true);
+        }
+        Ok(Self::with_retry_interrupted(|| user_path.read_dir())
+            .context("In is_empty_user: Failed to open legacy user dir.")?
+            .next()
+            .is_none())
+    }
+
+    fn extract_alias(encoded_alias: &str) -> Option<String> {
+        // We can check the encoded alias because the prefixes we are interested
+        // in are all in the printable range that don't get mangled.
+        for prefix in &["USRPKEY_", "USRSKEY_", "USRCERT_", "CACERT_"] {
+            if let Some(alias) = encoded_alias.strip_prefix(prefix) {
+                return Self::decode_alias(&alias).ok();
+            }
+        }
+        None
+    }
+
+    /// List all entries for a given user. The strings are unchanged file names, i.e.,
+    /// encoded with UID prefix.
+    fn list_user(&self, user_id: u32) -> Result<Vec<String>> {
+        let path = self.make_user_path_name(user_id);
+        let dir = match Self::with_retry_interrupted(|| fs::read_dir(path.as_path())) {
+            Ok(dir) => dir,
+            Err(e) => match e.kind() {
+                ErrorKind::NotFound => return Ok(Default::default()),
+                _ => {
+                    return Err(e).context(format!(
+                        "In list_user: Failed to open legacy blob database. {:?}",
+                        path
+                    ))
+                }
+            },
+        };
+        let mut result: Vec<String> = Vec::new();
+        for entry in dir {
+            let file_name = entry.context("In list_user: Trying to access dir entry")?.file_name();
+            if let Some(f) = file_name.to_str() {
+                result.push(f.to_string())
+            }
+        }
+        Ok(result)
+    }
+
+    /// List all keystore entries belonging to the given user. Returns a map of UIDs
+    /// to sets of decoded aliases.
+    pub fn list_keystore_entries_for_user(
+        &self,
+        user_id: u32,
+    ) -> Result<HashMap<u32, HashSet<String>>> {
+        let user_entries = self
+            .list_user(user_id)
+            .context("In list_keystore_entries_for_user: Trying to list user.")?;
+
+        let result =
+            user_entries.into_iter().fold(HashMap::<u32, HashSet<String>>::new(), |mut acc, v| {
+                if let Some(sep_pos) = v.find('_') {
+                    if let Ok(uid) = v[0..sep_pos].parse::<u32>() {
+                        if let Some(alias) = Self::extract_alias(&v[sep_pos + 1..]) {
+                            let entry = acc.entry(uid).or_default();
+                            entry.insert(alias);
+                        }
+                    }
+                }
+                acc
+            });
+        Ok(result)
+    }
+
+    /// List all keystore entries belonging to the given uid.
+    pub fn list_keystore_entries_for_uid(&self, uid: u32) -> Result<Vec<String>> {
+        let user_id = uid_to_android_user(uid);
+
+        let user_entries = self
+            .list_user(user_id)
+            .context("In list_keystore_entries_for_uid: Trying to list user.")?;
+
+        let uid_str = format!("{}_", uid);
+
+        let mut result: Vec<String> = user_entries
+            .into_iter()
+            .filter_map(|v| {
+                if !v.starts_with(&uid_str) {
+                    return None;
+                }
+                let encoded_alias = &v[uid_str.len()..];
+                Self::extract_alias(encoded_alias)
+            })
+            .collect();
+
+        result.sort_unstable();
+        result.dedup();
+        Ok(result)
+    }
+
+    fn with_retry_interrupted<F, T>(f: F) -> IoResult<T>
+    where
+        F: Fn() -> IoResult<T>,
+    {
+        loop {
+            match f() {
+                Ok(v) => return Ok(v),
+                Err(e) => match e.kind() {
+                    ErrorKind::Interrupted => continue,
+                    _ => return Err(e),
+                },
+            }
+        }
+    }
+
+    /// Deletes a keystore entry. Also removes the user_<uid> directory on the
+    /// last migration.
+    pub fn remove_keystore_entry(&self, uid: u32, alias: &str) -> Result<bool> {
+        let mut something_was_deleted = false;
+        let prefixes = ["USRPKEY", "USRSKEY"];
+        for prefix in &prefixes {
+            let path = self.make_blob_filename(uid, alias, prefix);
+            if let Err(e) = Self::with_retry_interrupted(|| fs::remove_file(path.as_path())) {
+                match e.kind() {
+                    // Only a subset of keys are expected.
+                    ErrorKind::NotFound => continue,
+                    // Log error but ignore.
+                    _ => log::error!("Error while deleting key blob entries. {:?}", e),
+                }
+            }
+            let path = self.make_chr_filename(uid, alias, prefix);
+            if let Err(e) = Self::with_retry_interrupted(|| fs::remove_file(path.as_path())) {
+                match e.kind() {
+                    ErrorKind::NotFound => {
+                        log::info!("No characteristics file found for legacy key blob.")
+                    }
+                    // Log error but ignore.
+                    _ => log::error!("Error while deleting key blob entries. {:?}", e),
+                }
+            }
+            something_was_deleted = true;
+            // Only one of USRPKEY and USRSKEY can be present. So we can end the loop
+            // if we reach this point.
+            break;
+        }
+
+        let prefixes = ["USRCERT", "CACERT"];
+        for prefix in &prefixes {
+            let path = self.make_blob_filename(uid, alias, prefix);
+            if let Err(e) = Self::with_retry_interrupted(|| fs::remove_file(path.as_path())) {
+                match e.kind() {
+                    // USRCERT and CACERT are optional either or both may or may not be present.
+                    ErrorKind::NotFound => continue,
+                    // Log error but ignore.
+                    _ => log::error!("Error while deleting key blob entries. {:?}", e),
+                }
+                something_was_deleted = true;
+            }
+        }
+
+        if something_was_deleted {
+            let user_id = uid_to_android_user(uid);
+            self.remove_user_dir_if_empty(user_id)
+                .context("In remove_keystore_entry: Trying to remove empty user dir.")?;
+        }
+
+        Ok(something_was_deleted)
+    }
+
+    fn remove_user_dir_if_empty(&self, user_id: u32) -> Result<()> {
+        if self
+            .is_empty_user(user_id)
+            .context("In remove_user_dir_if_empty: Trying to check for empty user dir.")?
+        {
+            let user_path = self.make_user_path_name(user_id);
+            Self::with_retry_interrupted(|| fs::remove_dir(user_path.as_path())).ok();
+        }
+        Ok(())
+    }
+
+    /// Load a legacy key blob entry by uid and alias.
+    pub fn load_by_uid_alias(
+        &self,
+        uid: u32,
+        alias: &str,
+        key_manager: Option<&SuperKeyManager>,
+    ) -> Result<(Option<(Blob, Vec<KeyParameter>)>, Option<Vec<u8>>, Option<Vec<u8>>)> {
+        let km_blob = self.read_km_blob_file(uid, alias).context("In load_by_uid_alias.")?;
+
+        let km_blob = match km_blob {
+            Some((km_blob, prefix)) => {
+                let km_blob = match km_blob {
+                    Blob { flags: _, value: BlobValue::Decrypted(_) } => km_blob,
+                    // Unwrap the key blob if required and if we have key_manager.
+                    Blob { flags, value: BlobValue::Encrypted { ref iv, ref tag, ref data } } => {
+                        if let Some(key_manager) = key_manager {
+                            let decrypted = match key_manager
+                                .get_per_boot_key_by_user_id(uid_to_android_user(uid))
+                            {
+                                Some(key) => key.aes_gcm_decrypt(data, iv, tag).context(
+                                    "In load_by_uid_alias: while trying to decrypt legacy blob.",
+                                )?,
+                                None => {
+                                    return Err(KsError::Rc(ResponseCode::LOCKED)).context(format!(
+                                        concat!(
+                                            "In load_by_uid_alias: ",
+                                            "User {} has not unlocked the keystore yet.",
+                                        ),
+                                        uid_to_android_user(uid)
+                                    ))
+                                }
+                            };
+                            Blob { flags, value: BlobValue::Decrypted(decrypted) }
+                        } else {
+                            km_blob
+                        }
+                    }
+                    _ => {
+                        return Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED)).context(
+                            "In load_by_uid_alias: Found wrong blob type in legacy key blob file.",
+                        )
+                    }
+                };
+
+                let hw_sec_level = match km_blob.is_strongbox() {
+                    true => SecurityLevel::STRONGBOX,
+                    false => SecurityLevel::TRUSTED_ENVIRONMENT,
+                };
+                let key_parameters = self
+                    .read_characteristics_file(uid, &prefix, alias, hw_sec_level)
+                    .context("In load_by_uid_alias.")?;
+                Some((km_blob, key_parameters))
+            }
+            None => None,
+        };
+
+        let user_cert =
+            match Self::read_generic_blob(&self.make_blob_filename(uid, alias, "USRCERT"))
+                .context("In load_by_uid_alias: While loading user cert.")?
+            {
+                Some(Blob { value: BlobValue::Generic(data), .. }) => Some(data),
+                None => None,
+                _ => {
+                    return Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED)).context(
+                        "In load_by_uid_alias: Found unexpected blob type in USRCERT file",
+                    )
+                }
+            };
+
+        let ca_cert = match Self::read_generic_blob(&self.make_blob_filename(uid, alias, "CACERT"))
+            .context("In load_by_uid_alias: While loading ca cert.")?
+        {
+            Some(Blob { value: BlobValue::Generic(data), .. }) => Some(data),
+            None => None,
+            _ => {
+                return Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED))
+                    .context("In load_by_uid_alias: Found unexpected blob type in CACERT file")
+            }
+        };
+
+        Ok((km_blob, user_cert, ca_cert))
+    }
+
+    /// Returns true if the given user has a super key.
+    pub fn has_super_key(&self, user_id: u32) -> bool {
+        self.make_super_key_filename(user_id).is_file()
+    }
+
+    /// Load and decrypt legacy super key blob.
+    pub fn load_super_key(&self, user_id: u32, pw: &Password) -> Result<Option<ZVec>> {
+        let path = self.make_super_key_filename(user_id);
+        let blob = Self::read_generic_blob(&path)
+            .context("In load_super_key: While loading super key.")?;
+
+        let blob = match blob {
+            Some(blob) => match blob {
+                Blob { flags, value: BlobValue::PwEncrypted { iv, tag, data, salt, key_size } } => {
+                    if (flags & flags::ENCRYPTED) != 0 {
+                        let key = pw
+                            .derive_key(Some(&salt), key_size)
+                            .context("In load_super_key: Failed to derive key from password.")?;
+                        let blob = aes_gcm_decrypt(&data, &iv, &tag, &key).context(
+                            "In load_super_key: while trying to decrypt legacy super key blob.",
+                        )?;
+                        Some(blob)
+                    } else {
+                        // In 2019 we had some unencrypted super keys due to b/141955555.
+                        Some(
+                            data.try_into()
+                                .context("In load_super_key: Trying to convert key into ZVec")?,
+                        )
+                    }
+                }
+                _ => {
+                    return Err(KsError::Rc(ResponseCode::VALUE_CORRUPTED)).context(
+                        "In load_super_key: Found wrong blob type in legacy super key blob file.",
+                    )
+                }
+            },
+            None => None,
+        };
+
+        Ok(blob)
+    }
+
+    /// Removes the super key for the given user from the legacy database.
+    /// If this was the last entry in the user's database, this function removes
+    /// the user_<uid> directory as well.
+    pub fn remove_super_key(&self, user_id: u32) {
+        let path = self.make_super_key_filename(user_id);
+        Self::with_retry_interrupted(|| fs::remove_file(path.as_path())).ok();
+        if self.is_empty_user(user_id).ok().unwrap_or(false) {
+            let path = self.make_user_path_name(user_id);
+            Self::with_retry_interrupted(|| fs::remove_dir(path.as_path())).ok();
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use anyhow::anyhow;
+    use keystore2_crypto::aes_gcm_decrypt;
+    use rand::Rng;
+    use std::string::FromUtf8Error;
+    mod legacy_blob_test_vectors;
+    use crate::error;
+    use crate::legacy_blob::test::legacy_blob_test_vectors::*;
+    use keystore2_test_utils::TempDir;
+
+    #[test]
+    fn decode_encode_alias_test() {
+        static ALIAS: &str = "#({}test[])😗";
+        static ENCODED_ALIAS: &str = "+S+X{}test[]+Y.`-O-H-G";
+        // Second multi byte out of range ------v
+        static ENCODED_ALIAS_ERROR1: &str = "+S+{}test[]+Y";
+        // Incomplete multi byte ------------------------v
+        static ENCODED_ALIAS_ERROR2: &str = "+S+X{}test[]+";
+        // Our encoding: ".`-O-H-G"
+        // is UTF-8: 0xF0 0x9F 0x98 0x97
+        // is UNICODE: U+1F617
+        // is 😗
+        // But +H below is a valid encoding for 0x18 making this sequence invalid UTF-8.
+        static ENCODED_ALIAS_ERROR_UTF8: &str = ".`-O+H-G";
+
+        assert_eq!(ENCODED_ALIAS, &LegacyBlobLoader::encode_alias(ALIAS));
+        assert_eq!(ALIAS, &LegacyBlobLoader::decode_alias(ENCODED_ALIAS).unwrap());
+        assert_eq!(
+            Some(&Error::BadEncoding),
+            LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR1)
+                .unwrap_err()
+                .root_cause()
+                .downcast_ref::<Error>()
+        );
+        assert_eq!(
+            Some(&Error::BadEncoding),
+            LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR2)
+                .unwrap_err()
+                .root_cause()
+                .downcast_ref::<Error>()
+        );
+        assert!(LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR_UTF8)
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<FromUtf8Error>()
+            .is_some());
+
+        for _i in 0..100 {
+            // Any valid UTF-8 string should be en- and decoded without loss.
+            let alias_str = rand::thread_rng().gen::<[char; 20]>().iter().collect::<String>();
+            let random_alias = alias_str.as_bytes();
+            let encoded = LegacyBlobLoader::encode_alias(&alias_str);
+            let decoded = match LegacyBlobLoader::decode_alias(&encoded) {
+                Ok(d) => d,
+                Err(_) => panic!("random_alias: {:x?}\nencoded {}", random_alias, encoded),
+            };
+            assert_eq!(random_alias.to_vec(), decoded.bytes().collect::<Vec<u8>>());
+        }
+    }
+
+    #[test]
+    fn read_golden_key_blob_test() -> anyhow::Result<()> {
+        let blob = LegacyBlobLoader::new_from_stream_decrypt_with(&mut &*BLOB, |_, _, _, _, _| {
+            Err(anyhow!("should not be called"))
+        })?;
+        assert!(!blob.is_encrypted());
+        assert!(!blob.is_fallback());
+        assert!(!blob.is_strongbox());
+        assert!(!blob.is_critical_to_device_encryption());
+        assert_eq!(blob.value(), &BlobValue::Generic([0xde, 0xed, 0xbe, 0xef].to_vec()));
+
+        let blob = LegacyBlobLoader::new_from_stream_decrypt_with(
+            &mut &*REAL_LEGACY_BLOB,
+            |_, _, _, _, _| Err(anyhow!("should not be called")),
+        )?;
+        assert!(!blob.is_encrypted());
+        assert!(!blob.is_fallback());
+        assert!(!blob.is_strongbox());
+        assert!(!blob.is_critical_to_device_encryption());
+        assert_eq!(
+            blob.value(),
+            &BlobValue::Decrypted(REAL_LEGACY_BLOB_PAYLOAD.try_into().unwrap())
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn read_aes_gcm_encrypted_key_blob_test() {
+        let blob = LegacyBlobLoader::new_from_stream_decrypt_with(
+            &mut &*AES_GCM_ENCRYPTED_BLOB,
+            |d, iv, tag, salt, key_size| {
+                assert_eq!(salt, None);
+                assert_eq!(key_size, None);
+                assert_eq!(
+                    iv,
+                    &[
+                        0xbd, 0xdb, 0x8d, 0x69, 0x72, 0x56, 0xf0, 0xf5, 0xa4, 0x02, 0x88, 0x7f,
+                        0x00, 0x00, 0x00, 0x00,
+                    ]
+                );
+                assert_eq!(
+                    tag,
+                    &[
+                        0x50, 0xd9, 0x97, 0x95, 0x37, 0x6e, 0x28, 0x6a, 0x28, 0x9d, 0x51, 0xb9,
+                        0xb9, 0xe0, 0x0b, 0xc3
+                    ][..]
+                );
+                aes_gcm_decrypt(d, iv, tag, AES_KEY).context("Trying to decrypt blob.")
+            },
+        )
+        .unwrap();
+        assert!(blob.is_encrypted());
+        assert!(!blob.is_fallback());
+        assert!(!blob.is_strongbox());
+        assert!(!blob.is_critical_to_device_encryption());
+
+        assert_eq!(blob.value(), &BlobValue::Decrypted(DECRYPTED_PAYLOAD.try_into().unwrap()));
+    }
+
+    #[test]
+    fn read_golden_key_blob_too_short_test() {
+        let error =
+            LegacyBlobLoader::new_from_stream_decrypt_with(&mut &BLOB[0..15], |_, _, _, _, _| {
+                Err(anyhow!("should not be called"))
+            })
+            .unwrap_err();
+        assert_eq!(Some(&Error::BadLen), error.root_cause().downcast_ref::<Error>());
+    }
+
+    #[test]
+    fn test_is_empty() {
+        let temp_dir = TempDir::new("test_is_empty").expect("Failed to create temp dir.");
+        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+        assert!(legacy_blob_loader.is_empty().expect("Should succeed and be empty."));
+
+        let _db = crate::database::KeystoreDB::new(temp_dir.path(), None)
+            .expect("Failed to open database.");
+
+        assert!(legacy_blob_loader.is_empty().expect("Should succeed and still be empty."));
+
+        std::fs::create_dir(&*temp_dir.build().push("user_0")).expect("Failed to create user_0.");
+
+        assert!(!legacy_blob_loader.is_empty().expect("Should succeed but not be empty."));
+
+        std::fs::create_dir(&*temp_dir.build().push("user_10")).expect("Failed to create user_10.");
+
+        assert!(!legacy_blob_loader.is_empty().expect("Should succeed but still not be empty."));
+
+        std::fs::remove_dir_all(&*temp_dir.build().push("user_0"))
+            .expect("Failed to remove user_0.");
+
+        assert!(!legacy_blob_loader.is_empty().expect("Should succeed but still not be empty."));
+
+        std::fs::remove_dir_all(&*temp_dir.build().push("user_10"))
+            .expect("Failed to remove user_10.");
+
+        assert!(legacy_blob_loader.is_empty().expect("Should succeed and be empty again."));
+    }
+
+    #[test]
+    fn test_legacy_blobs() -> anyhow::Result<()> {
+        let temp_dir = TempDir::new("legacy_blob_test")?;
+        std::fs::create_dir(&*temp_dir.build().push("user_0"))?;
+
+        std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY)?;
+
+        std::fs::write(
+            &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
+            USRPKEY_AUTHBOUND,
+        )?;
+        std::fs::write(
+            &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
+            USRPKEY_AUTHBOUND_CHR,
+        )?;
+        std::fs::write(
+            &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
+            USRCERT_AUTHBOUND,
+        )?;
+        std::fs::write(
+            &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
+            CACERT_AUTHBOUND,
+        )?;
+
+        std::fs::write(
+            &*temp_dir.build().push("user_0").push("10223_USRPKEY_non_authbound"),
+            USRPKEY_NON_AUTHBOUND,
+        )?;
+        std::fs::write(
+            &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_non_authbound"),
+            USRPKEY_NON_AUTHBOUND_CHR,
+        )?;
+        std::fs::write(
+            &*temp_dir.build().push("user_0").push("10223_USRCERT_non_authbound"),
+            USRCERT_NON_AUTHBOUND,
+        )?;
+        std::fs::write(
+            &*temp_dir.build().push("user_0").push("10223_CACERT_non_authbound"),
+            CACERT_NON_AUTHBOUND,
+        )?;
+
+        let key_manager: SuperKeyManager = Default::default();
+        let mut db = crate::database::KeystoreDB::new(temp_dir.path(), None)?;
+        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+        assert_eq!(
+            legacy_blob_loader
+                .load_by_uid_alias(10223, "authbound", Some(&key_manager))
+                .unwrap_err()
+                .root_cause()
+                .downcast_ref::<error::Error>(),
+            Some(&error::Error::Rc(ResponseCode::LOCKED))
+        );
+
+        key_manager.unlock_user_key(&mut db, 0, &(PASSWORD.into()), &legacy_blob_loader)?;
+
+        if let (Some((Blob { flags, value: _ }, _params)), Some(cert), Some(chain)) =
+            legacy_blob_loader.load_by_uid_alias(10223, "authbound", Some(&key_manager))?
+        {
+            assert_eq!(flags, 4);
+            //assert_eq!(value, BlobValue::Encrypted(..));
+            assert_eq!(&cert[..], LOADED_CERT_AUTHBOUND);
+            assert_eq!(&chain[..], LOADED_CACERT_AUTHBOUND);
+        } else {
+            panic!("");
+        }
+        if let (Some((Blob { flags, value }, _params)), Some(cert), Some(chain)) =
+            legacy_blob_loader.load_by_uid_alias(10223, "non_authbound", Some(&key_manager))?
+        {
+            assert_eq!(flags, 0);
+            assert_eq!(value, BlobValue::Decrypted(LOADED_USRPKEY_NON_AUTHBOUND.try_into()?));
+            assert_eq!(&cert[..], LOADED_CERT_NON_AUTHBOUND);
+            assert_eq!(&chain[..], LOADED_CACERT_NON_AUTHBOUND);
+        } else {
+            panic!("");
+        }
+
+        legacy_blob_loader.remove_keystore_entry(10223, "authbound").expect("This should succeed.");
+        legacy_blob_loader
+            .remove_keystore_entry(10223, "non_authbound")
+            .expect("This should succeed.");
+
+        assert_eq!(
+            (None, None, None),
+            legacy_blob_loader.load_by_uid_alias(10223, "authbound", Some(&key_manager))?
+        );
+        assert_eq!(
+            (None, None, None),
+            legacy_blob_loader.load_by_uid_alias(10223, "non_authbound", Some(&key_manager))?
+        );
+
+        // The database should not be empty due to the super key.
+        assert!(!legacy_blob_loader.is_empty()?);
+        assert!(!legacy_blob_loader.is_empty_user(0)?);
+
+        // The database should be considered empty for user 1.
+        assert!(legacy_blob_loader.is_empty_user(1)?);
+
+        legacy_blob_loader.remove_super_key(0);
+
+        // Now it should be empty.
+        assert!(legacy_blob_loader.is_empty_user(0)?);
+        assert!(legacy_blob_loader.is_empty()?);
+
+        Ok(())
+    }
+
+    #[test]
+    fn list_non_existing_user() -> Result<()> {
+        let temp_dir = TempDir::new("list_non_existing_user")?;
+        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+        assert!(legacy_blob_loader.list_user(20)?.is_empty());
+
+        Ok(())
+    }
+
+    #[test]
+    fn list_vpn_profiles_on_non_existing_user() -> Result<()> {
+        let temp_dir = TempDir::new("list_vpn_profiles_on_non_existing_user")?;
+        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+        assert!(legacy_blob_loader.list_vpn_profiles(20)?.is_empty());
+
+        Ok(())
+    }
+}
diff --git a/keystore2/src/legacy_blob/test/legacy_blob_test_vectors.rs b/keystore2/src/legacy_blob/test/legacy_blob_test_vectors.rs
new file mode 100644
index 0000000..14bd40c
--- /dev/null
+++ b/keystore2/src/legacy_blob/test/legacy_blob_test_vectors.rs
@@ -0,0 +1,1277 @@
+// Copyright 2020, 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.
+
+pub static BLOB: &[u8] = &[
+    3, // version
+    1, // type
+    0, // flags
+    0, // info
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // IV
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // aead tag
+    0, 0, 0, 4, // length in big endian
+    0xde, 0xed, 0xbe, 0xef, // payload
+];
+pub static REAL_LEGACY_BLOB: &[u8] = &[
+    0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x94, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x25,
+    0x00, 0x0b, 0x00, 0x06, 0x00, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x00, 0x43, 0x00, 0x20,
+    0x85, 0x42, 0x9e, 0xe9, 0x34, 0x85, 0x2a, 0x00, 0xae, 0xbb, 0x53, 0xb4, 0x77, 0x1e, 0x59, 0x06,
+    0x70, 0x14, 0x10, 0xe3, 0xa4, 0x6e, 0xa7, 0xfa, 0x68, 0xf6, 0xa9, 0x29, 0x86, 0x08, 0x61, 0xef,
+    0x00, 0x8e, 0x00, 0x20, 0x4c, 0x3b, 0x31, 0x6a, 0x5e, 0xc2, 0xbc, 0xfc, 0x6f, 0x35, 0x14, 0x38,
+    0x0b, 0x8c, 0xa1, 0x9a, 0x2e, 0xf0, 0x40, 0xa8, 0x48, 0x4f, 0xe5, 0xe3, 0x56, 0xfb, 0x8d, 0x98,
+    0x98, 0x04, 0x73, 0x88, 0x00, 0x10, 0x8d, 0xff, 0x36, 0xf6, 0x5c, 0x30, 0x3c, 0x36, 0x96, 0xa1,
+    0x72, 0x63, 0x0b, 0xa5, 0xd7, 0x5f, 0xaf, 0x49, 0x34, 0xd0, 0xa9, 0xc3, 0x0b, 0x3c, 0xa4, 0x81,
+    0xb9, 0xb3, 0x6d, 0xfa, 0xa2, 0x45, 0x7d, 0x02, 0x34, 0x93, 0x1d, 0x89, 0x80, 0x40, 0xa2, 0xe8,
+    0xb2, 0xab, 0x61, 0x75, 0x9f, 0x0c, 0x39, 0x97, 0x28, 0x53, 0xad, 0x56, 0x19, 0x01, 0xc6, 0x66,
+    0xa5, 0xed, 0x4f, 0xe0, 0xa1, 0x6d, 0x26, 0x3b, 0xa3, 0x88, 0x22, 0x38, 0x3f, 0x53, 0x5e, 0xa5,
+    0x68, 0x85, 0x91, 0x22, 0xc3, 0x4c, 0x40, 0x64, 0x38, 0xa8, 0x49, 0x68, 0x22, 0x3c, 0xc1, 0xdc,
+    0x5d, 0x4f, 0x56, 0x12, 0xac, 0x20, 0x6b, 0xb7, 0x03, 0x6c, 0x27, 0xfc, 0x3f, 0x23, 0x2c, 0x4e,
+    0x10, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x65, 0xf5, 0x71, 0xc8, 0x6a, 0xbc, 0xd1, 0xa0,
+    0x4d, 0xa1, 0x69, 0xbf, 0xfe, 0x92, 0xae, 0x09, 0xb4, 0x26, 0xe9, 0xd7, 0x2b, 0xfe, 0x66, 0x40,
+    0x76, 0xb8, 0xc4, 0x72, 0x51, 0x80, 0xa4, 0xbd, 0x60, 0x52, 0x25, 0xaf, 0xaf, 0x0c, 0x9d, 0xe9,
+    0x91, 0xbf, 0xbe, 0xc1, 0xf8, 0x86, 0x74, 0xda, 0xf2, 0x0d, 0xa3, 0x72, 0x08, 0x29, 0x81, 0xec,
+    0x9c, 0x69, 0xea, 0x1f, 0x80, 0x0c, 0x97, 0x80, 0x6c, 0xcb, 0x61, 0x5d, 0x51, 0x35, 0x4d, 0xd1,
+    0x88, 0xe5, 0x47, 0xc3, 0x6f, 0x15, 0xee, 0xa1, 0x79, 0x02, 0x21, 0x0d, 0x1b, 0xb9, 0x87, 0x5f,
+    0x28, 0xd4, 0x70, 0x2e, 0x08, 0xa5, 0x73, 0x36, 0x81, 0xa3, 0x6a, 0x5f, 0xad, 0x61, 0x9a, 0xc5,
+    0x60, 0x76, 0x38, 0x8a, 0x2e, 0x42, 0x3e, 0x3d, 0x7f, 0x42, 0xc8, 0x00, 0xab, 0xac, 0x7f, 0xec,
+    0xba, 0xc7, 0x45, 0x08, 0xbb, 0x60, 0x58, 0xef, 0xb0, 0xc2, 0xf4, 0xe5, 0x9e, 0xb2, 0x34, 0xc6,
+    0x9f, 0x2d, 0x9b, 0x08, 0xec, 0x3c, 0xdc, 0xc2, 0xaa, 0x55, 0xf5, 0xca, 0x62, 0xbd, 0x41, 0x91,
+    0x42, 0xa8, 0xa4, 0x7e, 0xac, 0x7d, 0x78, 0xc3, 0x20, 0x00, 0x00, 0x00, 0x9f, 0xc9, 0x4a, 0x8b,
+    0xe1, 0xc0, 0x48, 0xe0, 0xd7, 0x76, 0xe7, 0x83, 0x20, 0x06, 0x24, 0x6c, 0x80, 0xf7, 0xaf, 0x7f,
+    0xda, 0x40, 0x2b, 0x75, 0xd0, 0xd2, 0x81, 0x7f, 0xe2, 0x2b, 0xef, 0x64,
+];
+
+pub static REAL_LEGACY_BLOB_PAYLOAD: &[u8] = &[
+    0x6c, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x25, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x72, 0x00, 0x00,
+    0x00, 0x06, 0x00, 0x80, 0x00, 0x43, 0x00, 0x20, 0x85, 0x42, 0x9e, 0xe9, 0x34, 0x85, 0x2a, 0x00,
+    0xae, 0xbb, 0x53, 0xb4, 0x77, 0x1e, 0x59, 0x06, 0x70, 0x14, 0x10, 0xe3, 0xa4, 0x6e, 0xa7, 0xfa,
+    0x68, 0xf6, 0xa9, 0x29, 0x86, 0x08, 0x61, 0xef, 0x00, 0x8e, 0x00, 0x20, 0x4c, 0x3b, 0x31, 0x6a,
+    0x5e, 0xc2, 0xbc, 0xfc, 0x6f, 0x35, 0x14, 0x38, 0x0b, 0x8c, 0xa1, 0x9a, 0x2e, 0xf0, 0x40, 0xa8,
+    0x48, 0x4f, 0xe5, 0xe3, 0x56, 0xfb, 0x8d, 0x98, 0x98, 0x04, 0x73, 0x88, 0x00, 0x10, 0x8d, 0xff,
+    0x36, 0xf6, 0x5c, 0x30, 0x3c, 0x36, 0x96, 0xa1, 0x72, 0x63, 0x0b, 0xa5, 0xd7, 0x5f, 0xaf, 0x49,
+    0x34, 0xd0, 0xa9, 0xc3, 0x0b, 0x3c, 0xa4, 0x81, 0xb9, 0xb3, 0x6d, 0xfa, 0xa2, 0x45, 0x7d, 0x02,
+    0x34, 0x93, 0x1d, 0x89, 0x80, 0x40, 0xa2, 0xe8, 0xb2, 0xab, 0x61, 0x75, 0x9f, 0x0c, 0x39, 0x97,
+    0x28, 0x53, 0xad, 0x56, 0x19, 0x01, 0xc6, 0x66, 0xa5, 0xed, 0x4f, 0xe0, 0xa1, 0x6d, 0x26, 0x3b,
+    0xa3, 0x88, 0x22, 0x38, 0x3f, 0x53, 0x5e, 0xa5, 0x68, 0x85, 0x91, 0x22, 0xc3, 0x4c, 0x40, 0x64,
+    0x38, 0xa8, 0x49, 0x68, 0x22, 0x3c, 0xc1, 0xdc, 0x5d, 0x4f, 0x56, 0x12, 0xac, 0x20, 0x6b, 0xb7,
+    0x03, 0x6c, 0x27, 0xfc, 0x3f, 0x23, 0x2c, 0x4e, 0x10, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00,
+    0x65, 0xf5, 0x71, 0xc8, 0x6a, 0xbc, 0xd1, 0xa0, 0x4d, 0xa1, 0x69, 0xbf, 0xfe, 0x92, 0xae, 0x09,
+    0xb4, 0x26, 0xe9, 0xd7, 0x2b, 0xfe, 0x66, 0x40, 0x76, 0xb8, 0xc4, 0x72, 0x51, 0x80, 0xa4, 0xbd,
+    0x60, 0x52, 0x25, 0xaf, 0xaf, 0x0c, 0x9d, 0xe9, 0x91, 0xbf, 0xbe, 0xc1, 0xf8, 0x86, 0x74, 0xda,
+    0xf2, 0x0d, 0xa3, 0x72, 0x08, 0x29, 0x81, 0xec, 0x9c, 0x69, 0xea, 0x1f, 0x80, 0x0c, 0x97, 0x80,
+    0x6c, 0xcb, 0x61, 0x5d, 0x51, 0x35, 0x4d, 0xd1, 0x88, 0xe5, 0x47, 0xc3, 0x6f, 0x15, 0xee, 0xa1,
+    0x79, 0x02, 0x21, 0x0d, 0x1b, 0xb9, 0x87, 0x5f, 0x28, 0xd4, 0x70, 0x2e, 0x08, 0xa5, 0x73, 0x36,
+    0x81, 0xa3, 0x6a, 0x5f, 0xad, 0x61, 0x9a, 0xc5, 0x60, 0x76, 0x38, 0x8a, 0x2e, 0x42, 0x3e, 0x3d,
+    0x7f, 0x42, 0xc8, 0x00, 0xab, 0xac, 0x7f, 0xec, 0xba, 0xc7, 0x45, 0x08, 0xbb, 0x60, 0x58, 0xef,
+    0xb0, 0xc2, 0xf4, 0xe5, 0x9e, 0xb2, 0x34, 0xc6, 0x9f, 0x2d, 0x9b, 0x08, 0xec, 0x3c, 0xdc, 0xc2,
+    0xaa, 0x55, 0xf5, 0xca, 0x62, 0xbd, 0x41, 0x91, 0x42, 0xa8, 0xa4, 0x7e, 0xac, 0x7d, 0x78, 0xc3,
+    0x20, 0x00, 0x00, 0x00, 0x9f, 0xc9, 0x4a, 0x8b, 0xe1, 0xc0, 0x48, 0xe0, 0xd7, 0x76, 0xe7, 0x83,
+    0x20, 0x06, 0x24, 0x6c, 0x80, 0xf7, 0xaf, 0x7f, 0xda, 0x40, 0x2b, 0x75, 0xd0, 0xd2, 0x81, 0x7f,
+    0xe2, 0x2b, 0xef, 0x64,
+];
+
+pub static AES_KEY: &[u8] = &[
+    0x48, 0xe4, 0xb5, 0xff, 0xcd, 0x9c, 0x41, 0x1e, 0x20, 0x41, 0xf2, 0x65, 0xa0, 0x4f, 0xf6, 0x57,
+    0xc6, 0x58, 0xca, 0xbf, 0x28, 0xa3, 0x01, 0x98, 0x01, 0x76, 0x10, 0xc0, 0x30, 0x4e, 0x35, 0x6e,
+];
+
+pub static AES_GCM_ENCRYPTED_BLOB: &[u8] = &[
+    0x03, 0x04, 0x04, 0x00, 0xbd, 0xdb, 0x8d, 0x69, 0x72, 0x56, 0xf0, 0xf5, 0xa4, 0x02, 0x88, 0x7f,
+    0x00, 0x00, 0x00, 0x00, 0x50, 0xd9, 0x97, 0x95, 0x37, 0x6e, 0x28, 0x6a, 0x28, 0x9d, 0x51, 0xb9,
+    0xb9, 0xe0, 0x0b, 0xc3, 0x00, 0x00, 0x01, 0xa4, 0x47, 0xf5, 0xf8, 0xb0, 0x77, 0x91, 0x6b, 0xb1,
+    0x33, 0xba, 0xd7, 0xaa, 0x81, 0x20, 0x4d, 0x2f, 0xda, 0x9e, 0x03, 0xe1, 0x41, 0xc9, 0x5a, 0x81,
+    0x30, 0xf6, 0x77, 0x71, 0x53, 0x8a, 0xf1, 0xf2, 0xa4, 0x28, 0xe4, 0x46, 0xc3, 0x7e, 0xbb, 0xb6,
+    0x01, 0x38, 0xa4, 0x0d, 0x78, 0x41, 0xbd, 0x63, 0x37, 0x15, 0x1d, 0x41, 0xc4, 0x55, 0xda, 0xe3,
+    0x23, 0xbf, 0x50, 0xb0, 0x7f, 0xb6, 0x1f, 0x45, 0x7b, 0x7b, 0x51, 0xd8, 0xc1, 0xa2, 0x7e, 0x1d,
+    0x81, 0xc6, 0x67, 0xde, 0x53, 0x55, 0x08, 0x97, 0x0d, 0x56, 0x30, 0x40, 0x02, 0x61, 0x85, 0x63,
+    0x1b, 0xe3, 0x4a, 0x13, 0xff, 0xf5, 0xaf, 0x2a, 0xa6, 0x8c, 0x64, 0xbf, 0x45, 0xd6, 0x63, 0x0c,
+    0x4f, 0xee, 0xac, 0x2b, 0x5c, 0x3a, 0x55, 0x1b, 0x02, 0x3b, 0x7c, 0xe6, 0xfb, 0x46, 0x85, 0x3f,
+    0x7a, 0x64, 0xb4, 0xf9, 0x30, 0xc9, 0x92, 0x8f, 0x76, 0x36, 0x11, 0xff, 0xcd, 0x12, 0x4f, 0xbe,
+    0x8b, 0x36, 0x6a, 0x65, 0x38, 0xed, 0x20, 0x2e, 0x6a, 0xe3, 0x81, 0x0c, 0x17, 0xd8, 0x65, 0xf3,
+    0xe7, 0xd2, 0x3e, 0x3b, 0x08, 0x9c, 0x52, 0x47, 0x00, 0x42, 0x4d, 0xba, 0x02, 0x2e, 0x51, 0x8c,
+    0x7f, 0x8d, 0xc3, 0x91, 0x39, 0x24, 0x69, 0x12, 0xcd, 0x3b, 0xa6, 0x9d, 0x23, 0x21, 0x94, 0xdd,
+    0xc2, 0x0a, 0x22, 0x07, 0x81, 0x8b, 0x18, 0x8c, 0x74, 0x9e, 0x47, 0x0b, 0x0b, 0x9f, 0xe2, 0xa3,
+    0x9e, 0x3f, 0x02, 0x4c, 0x8c, 0x13, 0xd3, 0xa2, 0xbb, 0x79, 0x8b, 0x1f, 0x0d, 0x61, 0xd2, 0x0d,
+    0x85, 0xf8, 0x85, 0xd9, 0x5a, 0x68, 0x50, 0x68, 0xef, 0x84, 0xfe, 0xf9, 0x63, 0x54, 0x63, 0x26,
+    0x55, 0x6c, 0x93, 0xeb, 0xa9, 0x4f, 0x13, 0x7e, 0x62, 0x34, 0xfe, 0x4d, 0x4e, 0x7b, 0x53, 0x75,
+    0x06, 0x9f, 0x2d, 0x83, 0xaf, 0xc7, 0x73, 0xab, 0x99, 0x9d, 0xda, 0x47, 0x30, 0x2a, 0x1a, 0x9f,
+    0x27, 0x6a, 0xc5, 0x19, 0xfa, 0xf2, 0x10, 0xb4, 0xf5, 0x82, 0xaa, 0x31, 0x7a, 0xe4, 0x5b, 0x3e,
+    0xe9, 0x4c, 0x92, 0x63, 0xe5, 0x28, 0x91, 0x0a, 0x0f, 0xb9, 0xe7, 0xbe, 0xad, 0x37, 0x29, 0x5e,
+    0x6b, 0x3a, 0x3b, 0xf9, 0xec, 0xab, 0xa5, 0x31, 0x44, 0xa7, 0x1a, 0x29, 0x4f, 0x20, 0x13, 0xb6,
+    0xa3, 0xe5, 0x02, 0xb9, 0x42, 0xc2, 0x1e, 0x80, 0xb6, 0x43, 0xec, 0xb7, 0x4e, 0x7c, 0x37, 0x6c,
+    0x60, 0xbd, 0xdc, 0x91, 0x13, 0x3a, 0xa0, 0x16, 0x33, 0x08, 0x51, 0xde, 0x4e, 0x1d, 0x72, 0x4a,
+    0x03, 0x7c, 0x92, 0x43, 0xe5, 0x01, 0x25, 0x71, 0x67, 0xbe, 0xf7, 0x93, 0x00, 0x38, 0x9d, 0xaf,
+    0xe7, 0x2f, 0x6a, 0xaf, 0x6c, 0xe9, 0x0b, 0x28, 0x2f, 0x11, 0xa5, 0xaf, 0x62, 0xe9, 0x0e, 0x39,
+    0xd0, 0x88, 0x50, 0x06, 0xa5, 0xa8, 0x1c, 0xce, 0x5e, 0x1e, 0x8a, 0x5b, 0x3c, 0x28, 0xf2, 0xaf,
+    0xef, 0x54, 0x86, 0xaf, 0x4d, 0x98, 0xcb, 0x71, 0xac, 0xaa, 0x93, 0x1e, 0xd2, 0xdd, 0xdf, 0x1a,
+    0x2e, 0x0c, 0xc7, 0xbf, 0x29, 0x1e, 0x31, 0xdc, 0x0e, 0x85, 0x96, 0x7b,
+];
+
+pub static DECRYPTED_PAYLOAD: &[u8] = &[
+    0x7c, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x25, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x72, 0x00, 0x00,
+    0x00, 0x06, 0x00, 0x80, 0x00, 0x43, 0x00, 0x20, 0xa4, 0xee, 0xdc, 0x1f, 0x9e, 0xba, 0x42, 0xd6,
+    0xc8, 0x7c, 0xdd, 0x1c, 0xba, 0x12, 0x67, 0x83, 0xd1, 0x7a, 0xb9, 0x91, 0x5b, 0xd3, 0x4d, 0xc7,
+    0xfe, 0xdd, 0x5b, 0x1c, 0x3e, 0x01, 0x19, 0x01, 0x00, 0x8e, 0x00, 0x20, 0xd1, 0x73, 0xca, 0x4b,
+    0xbf, 0xf0, 0xaa, 0x6c, 0xff, 0x5c, 0x3a, 0x2b, 0xf3, 0xb1, 0x6f, 0xdb, 0xff, 0x0e, 0x63, 0x43,
+    0xe3, 0x6a, 0x78, 0x1f, 0x24, 0xf2, 0x89, 0x99, 0x50, 0x66, 0xd0, 0x30, 0x00, 0x10, 0x84, 0x02,
+    0x9c, 0xf6, 0x58, 0x77, 0xe2, 0x69, 0x19, 0xb8, 0x8a, 0x49, 0x10, 0xdc, 0xb8, 0x27, 0xf8, 0xcd,
+    0x59, 0x91, 0xbb, 0x72, 0x84, 0x65, 0xee, 0x57, 0x15, 0x5b, 0x11, 0xc0, 0x8f, 0xfe, 0x16, 0x2f,
+    0x9b, 0x41, 0x80, 0x94, 0x6b, 0xf6, 0xca, 0x6e, 0x1d, 0xf4, 0x89, 0x9b, 0xb6, 0x22, 0x6d, 0x03,
+    0xbd, 0xfb, 0xec, 0x4a, 0x10, 0x9f, 0xc2, 0x67, 0xef, 0x9b, 0x25, 0x12, 0xa0, 0x6b, 0x2e, 0xa8,
+    0x63, 0x45, 0xdc, 0xb9, 0x02, 0x20, 0xcb, 0x26, 0x96, 0xec, 0xa2, 0xfb, 0x6d, 0x23, 0xc4, 0xa4,
+    0x29, 0x20, 0xa5, 0xbe, 0xb5, 0x5a, 0xa6, 0x13, 0xb6, 0x76, 0x17, 0xf3, 0xa1, 0x7f, 0x3e, 0x6c,
+    0x5a, 0xa7, 0xdb, 0x85, 0x30, 0xc7, 0x9f, 0x0c, 0x10, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00,
+    0xe9, 0x32, 0x4a, 0x5a, 0x82, 0x79, 0xd4, 0xdc, 0x64, 0xd9, 0x58, 0xbf, 0xf5, 0x24, 0xe0, 0xb0,
+    0xf1, 0x57, 0xc0, 0x52, 0x32, 0x1f, 0x9b, 0x2e, 0xd9, 0x9b, 0x04, 0x6c, 0x1f, 0xca, 0x1b, 0x0e,
+    0x08, 0x84, 0x83, 0xe6, 0x38, 0x61, 0xcb, 0x04, 0xfe, 0x6f, 0x9d, 0xe9, 0x57, 0xb2, 0xd9, 0x9f,
+    0x9d, 0xe0, 0xe4, 0xc5, 0x53, 0x21, 0x61, 0x27, 0xeb, 0x82, 0x42, 0x79, 0xdb, 0xda, 0x58, 0xea,
+    0x35, 0x01, 0x28, 0x6a, 0xaf, 0xd7, 0x7b, 0x30, 0xd4, 0xe9, 0x17, 0x18, 0xb9, 0xc1, 0xd8, 0x83,
+    0xc3, 0x04, 0xb8, 0xff, 0xd2, 0x25, 0x91, 0x7a, 0xb2, 0x42, 0xe0, 0xb8, 0x93, 0x07, 0x0a, 0x21,
+    0x79, 0xcc, 0xb4, 0x86, 0xee, 0xb8, 0x87, 0x83, 0x44, 0x47, 0x53, 0x06, 0xf2, 0xd1, 0xe5, 0xdd,
+    0xef, 0xd2, 0xe1, 0x0b, 0x05, 0x2b, 0x34, 0x84, 0x64, 0x67, 0xf6, 0xa0, 0x79, 0xc9, 0xfe, 0x60,
+    0xf9, 0x17, 0x69, 0xe1, 0xec, 0x3f, 0x20, 0xa1, 0x23, 0x86, 0x8a, 0x73, 0x6b, 0x20, 0x5f, 0xa3,
+    0x74, 0x9a, 0xbe, 0xf4, 0x38, 0x05, 0x6a, 0xc9, 0x5e, 0xb7, 0xe4, 0x70, 0x57, 0x55, 0x28, 0x18,
+    0x97, 0xb2, 0x92, 0x93, 0x21, 0xc0, 0xe1, 0x6c, 0xd8, 0x61, 0xec, 0xce, 0x46, 0x83, 0xf1, 0x12,
+    0x20, 0x00, 0x00, 0x00, 0x99, 0x6d, 0x9a, 0x9d, 0x13, 0xf3, 0x43, 0x06, 0x35, 0xf5, 0x89, 0x01,
+    0x90, 0x00, 0x09, 0xc9, 0x3f, 0xee, 0x79, 0x27, 0x26, 0xd9, 0x03, 0x9b, 0x57, 0xb1, 0x61, 0x6b,
+    0xf6, 0x0b, 0x81, 0x07,
+];
+
+pub static PASSWORD: &[u8] = &[
+    0x42, 0x39, 0x30, 0x37, 0x44, 0x37, 0x32, 0x37, 0x39, 0x39, 0x43, 0x42, 0x39, 0x41, 0x42, 0x30,
+    0x34, 0x31, 0x30, 0x38, 0x46, 0x44, 0x33, 0x45, 0x39, 0x42, 0x32, 0x38, 0x36, 0x35, 0x41, 0x36,
+    0x33, 0x44, 0x42, 0x42, 0x43, 0x36, 0x33, 0x42, 0x34, 0x39, 0x37, 0x33, 0x35, 0x45, 0x41, 0x41,
+    0x32, 0x45, 0x31, 0x35, 0x43, 0x43, 0x46, 0x32, 0x39, 0x36, 0x33, 0x34, 0x31, 0x32, 0x41, 0x39,
+];
+
+pub static SUPERKEY: &[u8] = &[
+    0x03, 0x07, 0x01, 0x10, 0x9a, 0x81, 0x56, 0x7d, 0xf5, 0x86, 0x7c, 0x62, 0xd7, 0xf9, 0x26, 0x06,
+    0x00, 0x00, 0x00, 0x00, 0xde, 0x2a, 0xcb, 0xac, 0x98, 0x57, 0x2b, 0xe5, 0x57, 0x18, 0x78, 0x57,
+    0x6e, 0x10, 0x09, 0x84, 0x00, 0x00, 0x00, 0x20, 0xac, 0x6d, 0x13, 0xe6, 0xad, 0x2c, 0x89, 0x53,
+    0x1a, 0x99, 0xa5, 0x6c, 0x88, 0xe9, 0xeb, 0x5c, 0xef, 0x68, 0x5e, 0x5b, 0x53, 0xa8, 0xe7, 0xa2,
+    0x76, 0x04, 0x2a, 0x48, 0xd1, 0xa7, 0x59, 0xd1, 0x04, 0x5b, 0xb4, 0x8a, 0x09, 0x22, 0x13, 0x0c,
+    0x94, 0xb6, 0x67, 0x7b, 0x39, 0x85, 0x28, 0x11,
+];
+pub static USRPKEY_AUTHBOUND: &[u8] = &[
+    0x03, 0x04, 0x04, 0x00, 0x1c, 0x34, 0x87, 0x6f, 0xc8, 0x35, 0x0d, 0x34, 0x88, 0x59, 0xbc, 0xf5,
+    0x00, 0x00, 0x00, 0x00, 0x62, 0xe3, 0x38, 0x2d, 0xd0, 0x58, 0x40, 0xc1, 0xb0, 0xf2, 0x4a, 0xdd,
+    0xf7, 0x81, 0x67, 0x0b, 0x00, 0x00, 0x02, 0x1d, 0x05, 0xb2, 0x5a, 0x1d, 0x1b, 0x25, 0x19, 0x48,
+    0xbf, 0x76, 0x0b, 0x37, 0x8c, 0x60, 0x52, 0xea, 0x30, 0x2a, 0x2c, 0x89, 0x99, 0x95, 0x57, 0x5c,
+    0xec, 0x62, 0x3c, 0x08, 0x1a, 0xc6, 0x65, 0xf9, 0xad, 0x24, 0x99, 0xf0, 0x5c, 0x44, 0xa0, 0xea,
+    0x9a, 0x60, 0xa2, 0xef, 0xf5, 0x27, 0x50, 0xba, 0x9c, 0xef, 0xa6, 0x08, 0x88, 0x4b, 0x0f, 0xfe,
+    0x5d, 0x41, 0xac, 0xba, 0xef, 0x9d, 0xa4, 0xb7, 0x72, 0xd3, 0xc8, 0x11, 0x92, 0x06, 0xf6, 0x26,
+    0xdf, 0x90, 0xe2, 0x66, 0x89, 0xf3, 0x85, 0x16, 0x4a, 0xdf, 0x7f, 0xac, 0x94, 0x4a, 0x1c, 0xce,
+    0x18, 0xee, 0xf4, 0x1f, 0x8e, 0xd6, 0xaf, 0xfd, 0x1d, 0xe5, 0x80, 0x4a, 0x6b, 0xbf, 0x91, 0xe2,
+    0x36, 0x1d, 0xb3, 0x53, 0x12, 0xfd, 0xc9, 0x0b, 0xa6, 0x69, 0x00, 0x45, 0xcb, 0x4c, 0x40, 0x6b,
+    0x70, 0xcb, 0xd2, 0xa0, 0x44, 0x0b, 0x4b, 0xec, 0xd6, 0x4f, 0x6f, 0x64, 0x37, 0xa7, 0xc7, 0x25,
+    0x54, 0xf4, 0xac, 0x6b, 0x34, 0x53, 0xea, 0x4e, 0x56, 0x49, 0xba, 0xf4, 0x1e, 0xc6, 0x52, 0x8f,
+    0xf4, 0x85, 0xe7, 0xb5, 0xaf, 0x49, 0x68, 0xb3, 0xb8, 0x7d, 0x63, 0xfc, 0x6e, 0x83, 0xa0, 0xf3,
+    0x91, 0x04, 0x80, 0xfd, 0xc5, 0x54, 0x7e, 0x92, 0x1a, 0x87, 0x2c, 0x6e, 0xa6, 0x29, 0xb9, 0x1e,
+    0x3f, 0xef, 0x30, 0x12, 0x7b, 0x2f, 0xa2, 0x16, 0x61, 0x8a, 0xcf, 0x14, 0x2d, 0x62, 0x98, 0x15,
+    0xae, 0x3b, 0xe6, 0x08, 0x1e, 0xb1, 0xf1, 0x21, 0xb0, 0x50, 0xc0, 0x4b, 0x81, 0x71, 0x29, 0xe7,
+    0x86, 0xbf, 0x29, 0xe1, 0xeb, 0xfe, 0xbc, 0x11, 0x3c, 0xc6, 0x15, 0x47, 0x9b, 0x41, 0x84, 0x61,
+    0x33, 0xbf, 0xca, 0xfe, 0x24, 0x92, 0x9e, 0x70, 0x26, 0x36, 0x46, 0xca, 0xfe, 0xd3, 0x5a, 0x1d,
+    0x9e, 0x30, 0x19, 0xbd, 0x26, 0x49, 0xb4, 0x90, 0x0c, 0x8d, 0xa2, 0x28, 0xa6, 0x24, 0x62, 0x6b,
+    0xe2, 0xfa, 0xe0, 0x53, 0xaa, 0x01, 0xeb, 0xaa, 0x41, 0x2b, 0xcb, 0xb1, 0x08, 0x66, 0x9d, 0x21,
+    0x2d, 0x2a, 0x47, 0x44, 0xee, 0xd5, 0x06, 0xe3, 0x4a, 0xb9, 0x3f, 0xcd, 0x78, 0x67, 0x89, 0x5b,
+    0xf7, 0x51, 0xc0, 0xc4, 0xa9, 0x68, 0xee, 0x44, 0x9c, 0x47, 0xa4, 0xbd, 0x6f, 0x7b, 0xdd, 0x64,
+    0xa8, 0xc7, 0x1e, 0x77, 0x1d, 0x68, 0x87, 0xaa, 0xae, 0x3c, 0xfc, 0x58, 0xb6, 0x3c, 0xcf, 0x58,
+    0xd0, 0x10, 0xaa, 0xef, 0xf0, 0x98, 0x67, 0x14, 0x29, 0x4d, 0x40, 0x8b, 0xe5, 0xb1, 0xdf, 0x7f,
+    0x40, 0xb1, 0xd8, 0xea, 0x6c, 0xa8, 0xf7, 0x64, 0xed, 0x02, 0x8d, 0xe7, 0x93, 0xfe, 0x79, 0x9a,
+    0x88, 0x62, 0x4f, 0xd0, 0x8a, 0x80, 0x36, 0x42, 0x0a, 0xf1, 0xa2, 0x0e, 0x30, 0x39, 0xbd, 0x26,
+    0x1d, 0xd4, 0xf1, 0xc8, 0x6e, 0xdd, 0xc5, 0x41, 0x29, 0xd8, 0xc1, 0x9e, 0x24, 0xf0, 0x25, 0x07,
+    0x05, 0x06, 0xc5, 0x08, 0xe3, 0x02, 0x2b, 0xe1, 0x40, 0xc5, 0x67, 0xd2, 0x82, 0x96, 0x20, 0x80,
+    0xcf, 0x87, 0x3a, 0xc6, 0xb0, 0xbe, 0xcc, 0xbb, 0x5a, 0x01, 0xab, 0xdd, 0x00, 0xc7, 0x0e, 0x7b,
+    0x02, 0x35, 0x27, 0xf4, 0x70, 0xfe, 0xd1, 0x19, 0x6a, 0x64, 0x23, 0x9d, 0xba, 0xe9, 0x1d, 0x76,
+    0x90, 0xfe, 0x7f, 0xd6, 0xb5, 0xa0, 0xe7, 0xb9, 0xf3, 0x56, 0x82, 0x8e, 0x57, 0x35, 0xf2, 0x69,
+    0xce, 0x52, 0xac, 0xc2, 0xf6, 0x5e, 0xb6, 0x54, 0x95, 0x83, 0x3b, 0x9f, 0x48, 0xbb, 0x04, 0x06,
+    0xac, 0x55, 0xa9, 0xb9, 0xa3, 0xe7, 0x89, 0x6e, 0x5c, 0x3a, 0x08, 0x67, 0x00, 0x8f, 0x1e, 0x26,
+    0x1b, 0x4d, 0x8a, 0xa6, 0x17, 0xa0, 0xa6, 0x18, 0xe6, 0x31, 0x43, 0x15, 0xb8, 0x7f, 0x9e, 0xf5,
+    0x78, 0x58, 0x98, 0xb1, 0x8c, 0xf5, 0x22, 0x42, 0x33, 0xc0, 0x42, 0x72, 0x4f, 0xce, 0x9f, 0x31,
+    0xaf, 0x17, 0x2f, 0x21, 0x07, 0xea, 0x61, 0xff, 0x73, 0x08, 0x50, 0xb2, 0x19, 0xe8, 0x23, 0x1b,
+    0x83, 0x42, 0xdd, 0x4e, 0x6d,
+];
+pub static USRPKEY_AUTHBOUND_CHR: &[u8] = &[
+    0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
+    0x7c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20,
+    0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0xa0,
+    0xf0, 0x7e, 0x7d, 0xb4, 0xc6, 0xd7, 0x25, 0x1d, 0x02, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00,
+    0x2d, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00,
+    0xbe, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x02, 0x00, 0x30, 0xb0, 0xad, 0x01, 0x00,
+    0xc2, 0x02, 0x00, 0x30, 0x75, 0x15, 0x03, 0x00, 0xcf, 0x02, 0x00, 0x30, 0xb9, 0x61, 0x34, 0x01,
+    0xce, 0x02, 0x00, 0x30, 0xb9, 0x61, 0x34, 0x01, 0x30, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xbd, 0x02, 0x00, 0x60,
+    0x10, 0x9d, 0x8b, 0x31, 0x76, 0x01, 0x00, 0x00, 0xf5, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+];
+pub static USRCERT_AUTHBOUND: &[u8] = &[
+    0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x97, 0x30, 0x82, 0x02, 0x93, 0x30, 0x82, 0x02, 0x3a,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
+    0x3d, 0x04, 0x03, 0x02, 0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13,
+    0x10, 0x34, 0x34, 0x61, 0x38, 0x31, 0x65, 0x61, 0x65, 0x63, 0x35, 0x31, 0x64, 0x62, 0x30, 0x62,
+    0x31, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54, 0x45, 0x45, 0x30,
+    0x20, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+    0x18, 0x0f, 0x32, 0x31, 0x30, 0x36, 0x30, 0x32, 0x30, 0x37, 0x30, 0x36, 0x32, 0x38, 0x31, 0x35,
+    0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x14, 0x41, 0x6e,
+    0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x4b,
+    0x65, 0x79, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06,
+    0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x20, 0x16, 0x85,
+    0xe6, 0x7f, 0xf1, 0x0e, 0x99, 0x1b, 0x3a, 0xc6, 0xc2, 0x83, 0x0a, 0x1d, 0xa4, 0xf1, 0x92, 0x76,
+    0x88, 0x4b, 0x6a, 0xcd, 0xb2, 0x8e, 0xf1, 0x50, 0x58, 0xd2, 0x69, 0xde, 0x57, 0x9c, 0x9c, 0x29,
+    0x04, 0x03, 0xf2, 0x4d, 0x12, 0x77, 0x9c, 0x62, 0xbc, 0x75, 0xb4, 0xab, 0x7a, 0xbc, 0xa0, 0x8f,
+    0x60, 0x5e, 0xcd, 0xce, 0x3a, 0xd8, 0x09, 0xeb, 0x9d, 0x40, 0xdb, 0x58, 0x53, 0xa3, 0x82, 0x01,
+    0x59, 0x30, 0x82, 0x01, 0x55, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x82, 0x01, 0x41, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+    0xd6, 0x79, 0x02, 0x01, 0x11, 0x04, 0x82, 0x01, 0x31, 0x30, 0x82, 0x01, 0x2d, 0x02, 0x01, 0x03,
+    0x0a, 0x01, 0x01, 0x02, 0x01, 0x04, 0x0a, 0x01, 0x01, 0x04, 0x08, 0x61, 0x73, 0x64, 0x66, 0x6a,
+    0x6b, 0x6c, 0x3b, 0x04, 0x00, 0x30, 0x6b, 0xbf, 0x85, 0x3d, 0x08, 0x02, 0x06, 0x01, 0x76, 0x31,
+    0x8b, 0x9d, 0x10, 0xbf, 0x85, 0x45, 0x5b, 0x04, 0x59, 0x30, 0x57, 0x31, 0x31, 0x30, 0x2f, 0x04,
+    0x2a, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x65,
+    0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6a, 0x64, 0x61, 0x6e, 0x69, 0x73, 0x2e, 0x6b,
+    0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x02, 0x01, 0x01, 0x31, 0x22,
+    0x04, 0x20, 0x30, 0xe0, 0x78, 0x45, 0xab, 0xd7, 0xc1, 0x74, 0x49, 0x01, 0x0f, 0xa7, 0x7f, 0x89,
+    0xde, 0x11, 0xa3, 0x8b, 0x3e, 0x31, 0x6b, 0xf1, 0x18, 0xb4, 0x58, 0x1b, 0xd7, 0xb3, 0x58, 0xa9,
+    0xc2, 0x81, 0x30, 0x81, 0xa5, 0xa1, 0x08, 0x31, 0x06, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03, 0xa2,
+    0x03, 0x02, 0x01, 0x03, 0xa3, 0x04, 0x02, 0x02, 0x01, 0x00, 0xa5, 0x05, 0x31, 0x03, 0x02, 0x01,
+    0x04, 0xaa, 0x03, 0x02, 0x01, 0x01, 0xbf, 0x83, 0x78, 0x03, 0x02, 0x01, 0x02, 0xbf, 0x85, 0x3e,
+    0x03, 0x02, 0x01, 0x00, 0xbf, 0x85, 0x40, 0x4c, 0x30, 0x4a, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0a,
+    0x01, 0x02, 0x04, 0x20, 0xe7, 0xad, 0x3c, 0x13, 0xc2, 0x73, 0x41, 0x60, 0xd7, 0x1a, 0x7c, 0x00,
+    0x5e, 0x14, 0xd8, 0xae, 0x06, 0x5d, 0x22, 0xd0, 0xb5, 0xf5, 0x6a, 0xba, 0x1f, 0x82, 0xa7, 0x8c,
+    0x17, 0x2c, 0xfd, 0x0f, 0xbf, 0x85, 0x41, 0x05, 0x02, 0x03, 0x01, 0xad, 0xb0, 0xbf, 0x85, 0x42,
+    0x05, 0x02, 0x03, 0x03, 0x15, 0x75, 0xbf, 0x85, 0x4e, 0x06, 0x02, 0x04, 0x01, 0x34, 0x61, 0xb9,
+    0xbf, 0x85, 0x4f, 0x06, 0x02, 0x04, 0x01, 0x34, 0x61, 0xb9, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86,
+    0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x4b, 0xdc, 0x8e,
+    0x91, 0xe6, 0xaa, 0x4a, 0x81, 0x6d, 0xa2, 0xd7, 0x13, 0x9e, 0x70, 0x12, 0x79, 0xb7, 0x85, 0x05,
+    0xad, 0x6e, 0x5e, 0x0b, 0x43, 0x3b, 0xaf, 0x9a, 0xa9, 0x29, 0x40, 0xd7, 0x92, 0x02, 0x20, 0x2f,
+    0x39, 0x58, 0xe9, 0x89, 0x1a, 0x14, 0x41, 0x8d, 0xe0, 0xdc, 0x3d, 0x88, 0xf4, 0x2c, 0x7c, 0xda,
+    0xa1, 0x84, 0xfa, 0x7f, 0xf9, 0x07, 0x97, 0xfb, 0xb5, 0xb7, 0x28, 0x28, 0x00, 0x7c, 0xa7,
+];
+pub static CACERT_AUTHBOUND: &[u8] = &[
+    0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x63, 0x30, 0x82, 0x02, 0x26, 0x30, 0x82, 0x01, 0xab,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x05, 0x84, 0x20, 0x26, 0x90, 0x76, 0x23, 0x58, 0x71,
+    0x77, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x29, 0x31,
+    0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x64, 0x37, 0x34, 0x61, 0x30,
+    0x65, 0x30, 0x31, 0x61, 0x61, 0x66, 0x33, 0x64, 0x64, 0x66, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03,
+    0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54, 0x45, 0x45, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33,
+    0x32, 0x31, 0x32, 0x31, 0x32, 0x35, 0x31, 0x33, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x33, 0x31,
+    0x38, 0x32, 0x31, 0x32, 0x35, 0x31, 0x33, 0x5a, 0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03,
+    0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x34, 0x61, 0x38, 0x31, 0x65, 0x61, 0x65, 0x63, 0x35, 0x31,
+    0x64, 0x62, 0x30, 0x62, 0x31, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03,
+    0x54, 0x45, 0x45, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
+    0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xfa, 0x35,
+    0x8f, 0xb0, 0x31, 0xd6, 0x30, 0x88, 0xde, 0xb0, 0x29, 0xcd, 0x6c, 0x7d, 0x4e, 0xa9, 0xce, 0x6e,
+    0x9d, 0x7a, 0xac, 0x97, 0x92, 0xc2, 0x45, 0xb5, 0xe2, 0xd0, 0xc1, 0x52, 0xa8, 0x50, 0x25, 0xd7,
+    0x89, 0x58, 0x7b, 0x04, 0xb6, 0x66, 0x93, 0x2a, 0x26, 0x5d, 0x3a, 0xb1, 0x5b, 0x77, 0x30, 0xbf,
+    0x95, 0xaa, 0x8b, 0x43, 0xc3, 0xbf, 0x43, 0xb7, 0xee, 0xac, 0x73, 0xdc, 0x03, 0x6a, 0xa3, 0x81,
+    0xba, 0x30, 0x81, 0xb7, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x19,
+    0x9f, 0x87, 0x8b, 0x56, 0xf4, 0x99, 0x3a, 0x69, 0x96, 0x9b, 0x8d, 0x9e, 0x64, 0xaa, 0x56, 0xb4,
+    0x7f, 0x8b, 0x4d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+    0xa9, 0xb5, 0xf4, 0x29, 0xc9, 0x1a, 0x58, 0xbd, 0x2f, 0x98, 0x2d, 0x67, 0x73, 0x31, 0x06, 0x87,
+    0xe0, 0xdf, 0xcd, 0x62, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+    0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x54, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x4d, 0x30, 0x4b,
+    0x30, 0x49, 0xa0, 0x47, 0xa0, 0x45, 0x86, 0x43, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+    0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70,
+    0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x30, 0x35, 0x38, 0x34, 0x32, 0x30, 0x32, 0x36, 0x39,
+    0x30, 0x37, 0x36, 0x32, 0x33, 0x35, 0x38, 0x37, 0x31, 0x37, 0x37, 0x30, 0x0a, 0x06, 0x08, 0x2a,
+    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xe3,
+    0x35, 0xc6, 0xa8, 0xb2, 0x75, 0x9c, 0x56, 0x7b, 0x6e, 0x61, 0x80, 0x65, 0x2c, 0x06, 0x88, 0xdd,
+    0xb9, 0x68, 0x4d, 0x3c, 0x68, 0x49, 0x66, 0x01, 0x4e, 0x30, 0x1d, 0xf3, 0xec, 0xa5, 0x51, 0x5c,
+    0xbf, 0xe7, 0x83, 0x33, 0xbd, 0x14, 0xee, 0x23, 0xf0, 0xcf, 0xb1, 0x37, 0x1c, 0x27, 0x78, 0x02,
+    0x31, 0x00, 0x94, 0xcb, 0x08, 0x3d, 0x2d, 0x3e, 0x69, 0x54, 0x5f, 0x63, 0xe3, 0xe4, 0x74, 0x72,
+    0xe2, 0xff, 0x8b, 0x26, 0xd2, 0x86, 0xc0, 0x97, 0x32, 0x40, 0xdd, 0x7c, 0x1f, 0x50, 0x60, 0x57,
+    0xcf, 0x2e, 0x23, 0xf3, 0x33, 0xe4, 0xfb, 0x6f, 0x5b, 0x7c, 0xc6, 0x31, 0x85, 0xae, 0xe0, 0x4e,
+    0x44, 0xa9, 0x30, 0x82, 0x03, 0xd1, 0x30, 0x82, 0x01, 0xb9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+    0x0a, 0x03, 0x88, 0x26, 0x67, 0x60, 0x65, 0x89, 0x96, 0x85, 0x7f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17,
+    0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x66, 0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38, 0x35,
+    0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32,
+    0x31, 0x32, 0x31, 0x31, 0x34, 0x31, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x33, 0x31, 0x38,
+    0x32, 0x31, 0x31, 0x34, 0x31, 0x34, 0x5a, 0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55,
+    0x04, 0x05, 0x13, 0x10, 0x34, 0x64, 0x37, 0x34, 0x61, 0x30, 0x65, 0x30, 0x31, 0x61, 0x61, 0x66,
+    0x33, 0x64, 0x64, 0x66, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54,
+    0x45, 0x45, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06,
+    0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xd5, 0xf5, 0x0e, 0xe2, 0x8d, 0xf3,
+    0x33, 0x4a, 0x6a, 0x77, 0x90, 0x9c, 0xc2, 0x25, 0xc8, 0x8a, 0x32, 0xae, 0x3b, 0xb4, 0x9c, 0x4a,
+    0x95, 0x22, 0x0c, 0xba, 0x0a, 0x76, 0xca, 0xcb, 0x24, 0x0c, 0x84, 0x3a, 0x83, 0x76, 0x04, 0x23,
+    0x31, 0x3a, 0xa0, 0x82, 0x80, 0x26, 0x65, 0xfd, 0x2f, 0x44, 0xf4, 0x96, 0xd8, 0xb7, 0xdc, 0xac,
+    0x55, 0x34, 0x74, 0x41, 0x0d, 0x0d, 0x7f, 0xbd, 0xe3, 0xf4, 0x28, 0xdf, 0x74, 0x4a, 0x17, 0x4d,
+    0xe7, 0xb2, 0x9b, 0x2b, 0x24, 0xc0, 0x9e, 0x56, 0x00, 0x52, 0xbb, 0x75, 0xb0, 0xd5, 0x6a, 0x41,
+    0x16, 0x08, 0xce, 0x32, 0xdb, 0x8f, 0x8b, 0x20, 0x73, 0x72, 0xa3, 0x81, 0xb6, 0x30, 0x81, 0xb3,
+    0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa9, 0xb5, 0xf4, 0x29, 0xc9,
+    0x1a, 0x58, 0xbd, 0x2f, 0x98, 0x2d, 0x67, 0x73, 0x31, 0x06, 0x87, 0xe0, 0xdf, 0xcd, 0x62, 0x30,
+    0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x36, 0x61, 0xe1, 0x00,
+    0x7c, 0x88, 0x05, 0x09, 0x51, 0x8b, 0x44, 0x6c, 0x47, 0xff, 0x1a, 0x4c, 0xc9, 0xea, 0x4f, 0x12,
+    0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+    0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02,
+    0x04, 0x30, 0x50, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x49, 0x30, 0x47, 0x30, 0x45, 0xa0, 0x43,
+    0xa0, 0x41, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x61, 0x6e, 0x64, 0x72,
+    0x6f, 0x69, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63,
+    0x72, 0x6c, 0x2f, 0x45, 0x38, 0x46, 0x41, 0x31, 0x39, 0x36, 0x33, 0x31, 0x34, 0x44, 0x32, 0x46,
+    0x41, 0x31, 0x38, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+    0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x32, 0xce, 0x04, 0xcc, 0x4d, 0x82, 0xad, 0x1d, 0xde,
+    0xa5, 0xcf, 0xe2, 0x1a, 0xa3, 0x79, 0xf7, 0xed, 0x88, 0x1e, 0x0e, 0x67, 0x8e, 0xfc, 0xbe, 0x7b,
+    0x04, 0xb7, 0x26, 0x59, 0xca, 0x95, 0x47, 0x8a, 0x10, 0x3f, 0xe5, 0x14, 0x19, 0xec, 0xd4, 0xdb,
+    0x33, 0xc3, 0xa1, 0x51, 0xf5, 0x06, 0x5e, 0x30, 0x66, 0x1f, 0xd2, 0x58, 0x2f, 0x14, 0x03, 0x7b,
+    0x35, 0x83, 0x86, 0x46, 0xdc, 0xee, 0x04, 0x30, 0xa1, 0x0f, 0xc4, 0x16, 0xc9, 0x8e, 0x63, 0xd0,
+    0xda, 0x5c, 0xb0, 0xf7, 0x3e, 0x21, 0xb6, 0xa5, 0x04, 0x07, 0x5a, 0x01, 0x8c, 0x31, 0x1f, 0x3e,
+    0x3a, 0xaf, 0x8d, 0x31, 0x3e, 0xb6, 0x12, 0x14, 0xf0, 0x0d, 0x2c, 0xcc, 0x6c, 0xb8, 0x7a, 0xbf,
+    0xd2, 0x6b, 0x5f, 0x27, 0xb0, 0xff, 0xc0, 0xaa, 0xde, 0xde, 0xf6, 0x31, 0x6d, 0xf3, 0x95, 0xc2,
+    0xd4, 0x90, 0xdc, 0x82, 0x4f, 0x24, 0x0d, 0x85, 0xf2, 0xbb, 0xc4, 0x58, 0xc9, 0xfa, 0xdd, 0x96,
+    0x41, 0x2b, 0x1f, 0x4c, 0x10, 0x1c, 0x9a, 0x57, 0x55, 0x0f, 0x62, 0xfc, 0x8d, 0xa2, 0xca, 0x84,
+    0x7b, 0x16, 0x60, 0xe8, 0x62, 0xce, 0x92, 0x85, 0x13, 0xf0, 0x63, 0x83, 0xd8, 0x5b, 0xa8, 0x74,
+    0x78, 0xb5, 0x28, 0xdb, 0x6c, 0xc9, 0x6e, 0x85, 0x85, 0x52, 0x3f, 0xd8, 0x67, 0xae, 0xf4, 0x09,
+    0xbe, 0xcf, 0x8c, 0x7f, 0x72, 0xb2, 0xc8, 0x93, 0xc6, 0xd2, 0xf3, 0x38, 0x74, 0x71, 0x22, 0xd6,
+    0x92, 0x76, 0xb1, 0xae, 0x14, 0x5a, 0x09, 0xd8, 0xaf, 0x1d, 0xaf, 0x48, 0x22, 0x5c, 0x30, 0x85,
+    0x8e, 0xc2, 0xfe, 0x61, 0xaf, 0xc3, 0xd2, 0x4c, 0x92, 0x53, 0xa4, 0x75, 0x1f, 0x78, 0xea, 0xfc,
+    0xfa, 0xc4, 0xca, 0x4e, 0x67, 0x68, 0x1f, 0x7d, 0xb2, 0x5e, 0xea, 0x8a, 0xb1, 0xcc, 0xb6, 0x92,
+    0x64, 0xf8, 0x82, 0xc0, 0x8b, 0xdc, 0x24, 0xe8, 0x57, 0x20, 0x33, 0x6d, 0x17, 0x33, 0x0d, 0xcb,
+    0x70, 0x02, 0x8b, 0xe5, 0xe3, 0x7d, 0x2c, 0x98, 0x32, 0x00, 0x20, 0xb4, 0xbd, 0xee, 0x89, 0xaa,
+    0x66, 0x13, 0x34, 0x9d, 0x9c, 0x8f, 0xde, 0x16, 0x09, 0x91, 0x49, 0x80, 0x50, 0x57, 0x39, 0xae,
+    0x35, 0x01, 0xe2, 0x25, 0x8e, 0x17, 0x08, 0xe0, 0xf0, 0x77, 0x98, 0x9d, 0x0a, 0x4f, 0xd2, 0x76,
+    0xda, 0xc4, 0x51, 0x45, 0x32, 0x8b, 0xe1, 0xab, 0xee, 0x10, 0x16, 0xf6, 0x95, 0x7d, 0x32, 0x76,
+    0xb2, 0xb5, 0x19, 0x67, 0x73, 0xfe, 0xc0, 0xc6, 0xa9, 0xd2, 0xa9, 0x23, 0xf0, 0x2b, 0xfc, 0xb1,
+    0xb6, 0xec, 0x3e, 0x11, 0x60, 0xa4, 0x22, 0xc7, 0xff, 0x25, 0xc3, 0xed, 0x6c, 0x6b, 0x79, 0x02,
+    0x3d, 0x5d, 0x62, 0x36, 0xd9, 0x32, 0xe4, 0x6e, 0x47, 0x67, 0x85, 0x8b, 0x23, 0x0a, 0xd5, 0x1e,
+    0xd0, 0xf4, 0x17, 0x1d, 0xcc, 0x3f, 0x5f, 0xda, 0x12, 0xe2, 0x35, 0x25, 0x52, 0xc2, 0xd6, 0x94,
+    0x3e, 0x83, 0x60, 0x55, 0xf8, 0x8d, 0x54, 0xf5, 0x47, 0x6f, 0x38, 0x03, 0x3b, 0xd7, 0x9a, 0x94,
+    0x8a, 0x3b, 0x9f, 0x92, 0x69, 0x0f, 0xcd, 0xb8, 0xf4, 0x62, 0x78, 0x22, 0x47, 0xe0, 0xae, 0xed,
+    0xfd, 0xf6, 0xe4, 0xc5, 0x8c, 0x0e, 0xb5, 0x18, 0xb1, 0x46, 0x3a, 0x6f, 0xbd, 0xde, 0x50, 0x3f,
+    0x1c, 0x35, 0x28, 0xf9, 0xed, 0x1e, 0xe8, 0x15, 0x31, 0xa9, 0xf7, 0xb1, 0x9d, 0xe1, 0x34, 0x81,
+    0x20, 0x1f, 0x22, 0xd4, 0xb7, 0xc6, 0x59, 0x8b, 0x90, 0x98, 0xdf, 0xa6, 0xb9, 0xa8, 0x8e, 0x6c,
+    0x15, 0x55, 0x5c, 0x41, 0x96, 0x82, 0x0d, 0xa9, 0x5f, 0xa9, 0xf3, 0x77, 0x1d, 0xee, 0x6b, 0x4c,
+    0x94, 0xc6, 0xc6, 0x9b, 0x78, 0x5b, 0x03, 0xbd, 0xa9, 0x87, 0xdd, 0x24, 0x04, 0x70, 0xce, 0x6c,
+    0x52, 0xe6, 0x21, 0x63, 0x6d, 0x28, 0x6c, 0x30, 0x82, 0x05, 0x60, 0x30, 0x82, 0x03, 0x48, 0xa0,
+    0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xe8, 0xfa, 0x19, 0x63, 0x14, 0xd2, 0xfa, 0x18, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1b,
+    0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x66, 0x39, 0x32, 0x30, 0x30,
+    0x39, 0x65, 0x38, 0x35, 0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+    0x36, 0x30, 0x35, 0x32, 0x36, 0x31, 0x36, 0x32, 0x38, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x36,
+    0x30, 0x35, 0x32, 0x34, 0x31, 0x36, 0x32, 0x38, 0x35, 0x32, 0x5a, 0x30, 0x1b, 0x31, 0x19, 0x30,
+    0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x66, 0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38,
+    0x35, 0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00,
+    0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xaf, 0xb6, 0xc7, 0x82, 0x2b, 0xb1, 0xa7,
+    0x01, 0xec, 0x2b, 0xb4, 0x2e, 0x8b, 0xcc, 0x54, 0x16, 0x63, 0xab, 0xef, 0x98, 0x2f, 0x32, 0xc7,
+    0x7f, 0x75, 0x31, 0x03, 0x0c, 0x97, 0x52, 0x4b, 0x1b, 0x5f, 0xe8, 0x09, 0xfb, 0xc7, 0x2a, 0xa9,
+    0x45, 0x1f, 0x74, 0x3c, 0xbd, 0x9a, 0x6f, 0x13, 0x35, 0x74, 0x4a, 0xa5, 0x5e, 0x77, 0xf6, 0xb6,
+    0xac, 0x35, 0x35, 0xee, 0x17, 0xc2, 0x5e, 0x63, 0x95, 0x17, 0xdd, 0x9c, 0x92, 0xe6, 0x37, 0x4a,
+    0x53, 0xcb, 0xfe, 0x25, 0x8f, 0x8f, 0xfb, 0xb6, 0xfd, 0x12, 0x93, 0x78, 0xa2, 0x2a, 0x4c, 0xa9,
+    0x9c, 0x45, 0x2d, 0x47, 0xa5, 0x9f, 0x32, 0x01, 0xf4, 0x41, 0x97, 0xca, 0x1c, 0xcd, 0x7e, 0x76,
+    0x2f, 0xb2, 0xf5, 0x31, 0x51, 0xb6, 0xfe, 0xb2, 0xff, 0xfd, 0x2b, 0x6f, 0xe4, 0xfe, 0x5b, 0xc6,
+    0xbd, 0x9e, 0xc3, 0x4b, 0xfe, 0x08, 0x23, 0x9d, 0xaa, 0xfc, 0xeb, 0x8e, 0xb5, 0xa8, 0xed, 0x2b,
+    0x3a, 0xcd, 0x9c, 0x5e, 0x3a, 0x77, 0x90, 0xe1, 0xb5, 0x14, 0x42, 0x79, 0x31, 0x59, 0x85, 0x98,
+    0x11, 0xad, 0x9e, 0xb2, 0xa9, 0x6b, 0xbd, 0xd7, 0xa5, 0x7c, 0x93, 0xa9, 0x1c, 0x41, 0xfc, 0xcd,
+    0x27, 0xd6, 0x7f, 0xd6, 0xf6, 0x71, 0xaa, 0x0b, 0x81, 0x52, 0x61, 0xad, 0x38, 0x4f, 0xa3, 0x79,
+    0x44, 0x86, 0x46, 0x04, 0xdd, 0xb3, 0xd8, 0xc4, 0xf9, 0x20, 0xa1, 0x9b, 0x16, 0x56, 0xc2, 0xf1,
+    0x4a, 0xd6, 0xd0, 0x3c, 0x56, 0xec, 0x06, 0x08, 0x99, 0x04, 0x1c, 0x1e, 0xd1, 0xa5, 0xfe, 0x6d,
+    0x34, 0x40, 0xb5, 0x56, 0xba, 0xd1, 0xd0, 0xa1, 0x52, 0x58, 0x9c, 0x53, 0xe5, 0x5d, 0x37, 0x07,
+    0x62, 0xf0, 0x12, 0x2e, 0xef, 0x91, 0x86, 0x1b, 0x1b, 0x0e, 0x6c, 0x4c, 0x80, 0x92, 0x74, 0x99,
+    0xc0, 0xe9, 0xbe, 0xc0, 0xb8, 0x3e, 0x3b, 0xc1, 0xf9, 0x3c, 0x72, 0xc0, 0x49, 0x60, 0x4b, 0xbd,
+    0x2f, 0x13, 0x45, 0xe6, 0x2c, 0x3f, 0x8e, 0x26, 0xdb, 0xec, 0x06, 0xc9, 0x47, 0x66, 0xf3, 0xc1,
+    0x28, 0x23, 0x9d, 0x4f, 0x43, 0x12, 0xfa, 0xd8, 0x12, 0x38, 0x87, 0xe0, 0x6b, 0xec, 0xf5, 0x67,
+    0x58, 0x3b, 0xf8, 0x35, 0x5a, 0x81, 0xfe, 0xea, 0xba, 0xf9, 0x9a, 0x83, 0xc8, 0xdf, 0x3e, 0x2a,
+    0x32, 0x2a, 0xfc, 0x67, 0x2b, 0xf1, 0x20, 0xb1, 0x35, 0x15, 0x8b, 0x68, 0x21, 0xce, 0xaf, 0x30,
+    0x9b, 0x6e, 0xee, 0x77, 0xf9, 0x88, 0x33, 0xb0, 0x18, 0xda, 0xa1, 0x0e, 0x45, 0x1f, 0x06, 0xa3,
+    0x74, 0xd5, 0x07, 0x81, 0xf3, 0x59, 0x08, 0x29, 0x66, 0xbb, 0x77, 0x8b, 0x93, 0x08, 0x94, 0x26,
+    0x98, 0xe7, 0x4e, 0x0b, 0xcd, 0x24, 0x62, 0x8a, 0x01, 0xc2, 0xcc, 0x03, 0xe5, 0x1f, 0x0b, 0x3e,
+    0x5b, 0x4a, 0xc1, 0xe4, 0xdf, 0x9e, 0xaf, 0x9f, 0xf6, 0xa4, 0x92, 0xa7, 0x7c, 0x14, 0x83, 0x88,
+    0x28, 0x85, 0x01, 0x5b, 0x42, 0x2c, 0xe6, 0x7b, 0x80, 0xb8, 0x8c, 0x9b, 0x48, 0xe1, 0x3b, 0x60,
+    0x7a, 0xb5, 0x45, 0xc7, 0x23, 0xff, 0x8c, 0x44, 0xf8, 0xf2, 0xd3, 0x68, 0xb9, 0xf6, 0x52, 0x0d,
+    0x31, 0x14, 0x5e, 0xbf, 0x9e, 0x86, 0x2a, 0xd7, 0x1d, 0xf6, 0xa3, 0xbf, 0xd2, 0x45, 0x09, 0x59,
+    0xd6, 0x53, 0x74, 0x0d, 0x97, 0xa1, 0x2f, 0x36, 0x8b, 0x13, 0xef, 0x66, 0xd5, 0xd0, 0xa5, 0x4a,
+    0x6e, 0x2f, 0x5d, 0x9a, 0x6f, 0xef, 0x44, 0x68, 0x32, 0xbc, 0x67, 0x84, 0x47, 0x25, 0x86, 0x1f,
+    0x09, 0x3d, 0xd0, 0xe6, 0xf3, 0x40, 0x5d, 0xa8, 0x96, 0x43, 0xef, 0x0f, 0x4d, 0x69, 0xb6, 0x42,
+    0x00, 0x51, 0xfd, 0xb9, 0x30, 0x49, 0x67, 0x3e, 0x36, 0x95, 0x05, 0x80, 0xd3, 0xcd, 0xf4, 0xfb,
+    0xd0, 0x8b, 0xc5, 0x84, 0x83, 0x95, 0x26, 0x00, 0x63, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+    0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x36,
+    0x61, 0xe1, 0x00, 0x7c, 0x88, 0x05, 0x09, 0x51, 0x8b, 0x44, 0x6c, 0x47, 0xff, 0x1a, 0x4c, 0xc9,
+    0xea, 0x4f, 0x12, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+    0x36, 0x61, 0xe1, 0x00, 0x7c, 0x88, 0x05, 0x09, 0x51, 0x8b, 0x44, 0x6c, 0x47, 0xff, 0x1a, 0x4c,
+    0xc9, 0xea, 0x4f, 0x12, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+    0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x40, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x39, 0x30, 0x37,
+    0x30, 0x35, 0xa0, 0x33, 0xa0, 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+    0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70,
+    0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x20, 0xc8, 0xc3, 0x8d, 0x4b,
+    0xdc, 0xa9, 0x57, 0x1b, 0x46, 0x8c, 0x89, 0x2f, 0xff, 0x72, 0xaa, 0xc6, 0xf8, 0x44, 0xa1, 0x1d,
+    0x41, 0xa8, 0xf0, 0x73, 0x6c, 0xc3, 0x7d, 0x16, 0xd6, 0x42, 0x6d, 0x8e, 0x7e, 0x94, 0x07, 0x04,
+    0x4c, 0xea, 0x39, 0xe6, 0x8b, 0x07, 0xc1, 0x3d, 0xbf, 0x15, 0x03, 0xdd, 0x5c, 0x85, 0xbd, 0xaf,
+    0xb2, 0xc0, 0x2d, 0x5f, 0x6c, 0xdb, 0x4e, 0xfa, 0x81, 0x27, 0xdf, 0x8b, 0x04, 0xf1, 0x82, 0x77,
+    0x0f, 0xc4, 0xe7, 0x74, 0x5b, 0x7f, 0xce, 0xaa, 0x87, 0x12, 0x9a, 0x88, 0x01, 0xce, 0x8e, 0x9b,
+    0xc0, 0xcb, 0x96, 0x37, 0x9b, 0x4d, 0x26, 0xa8, 0x2d, 0x30, 0xfd, 0x9c, 0x2f, 0x8e, 0xed, 0x6d,
+    0xc1, 0xbe, 0x2f, 0x84, 0xb6, 0x89, 0xe4, 0xd9, 0x14, 0x25, 0x8b, 0x14, 0x4b, 0xba, 0xe6, 0x24,
+    0xa1, 0xc7, 0x06, 0x71, 0x13, 0x2e, 0x2f, 0x06, 0x16, 0xa8, 0x84, 0xb2, 0xa4, 0xd6, 0xa4, 0x6f,
+    0xfa, 0x89, 0xb6, 0x02, 0xbf, 0xba, 0xd8, 0x0c, 0x12, 0x43, 0x71, 0x1f, 0x56, 0xeb, 0x60, 0x56,
+    0xf6, 0x37, 0xc8, 0xa0, 0x14, 0x1c, 0xc5, 0x40, 0x94, 0x26, 0x8b, 0x8c, 0x3c, 0x7d, 0xb9, 0x94,
+    0xb3, 0x5c, 0x0d, 0xcd, 0x6c, 0xb2, 0xab, 0xc2, 0xda, 0xfe, 0xe2, 0x52, 0x02, 0x3d, 0x2d, 0xea,
+    0x0c, 0xd6, 0xc3, 0x68, 0xbe, 0xa3, 0xe6, 0x41, 0x48, 0x86, 0xf6, 0xb1, 0xe5, 0x8b, 0x5b, 0xd7,
+    0xc7, 0x30, 0xb2, 0x68, 0xc4, 0xe3, 0xc1, 0xfb, 0x64, 0x24, 0xb9, 0x1f, 0xeb, 0xbd, 0xb8, 0x0c,
+    0x58, 0x6e, 0x2a, 0xe8, 0x36, 0x8c, 0x84, 0xd5, 0xd1, 0x09, 0x17, 0xbd, 0xa2, 0x56, 0x17, 0x89,
+    0xd4, 0x68, 0x73, 0x93, 0x34, 0x0e, 0x2e, 0x25, 0x4f, 0x56, 0x0e, 0xf6, 0x4b, 0x23, 0x58, 0xfc,
+    0xdc, 0x0f, 0xbf, 0xc6, 0x70, 0x09, 0x52, 0xe7, 0x08, 0xbf, 0xfc, 0xc6, 0x27, 0x50, 0x0c, 0x1f,
+    0x66, 0xe8, 0x1e, 0xa1, 0x7c, 0x09, 0x8d, 0x7a, 0x2e, 0x9b, 0x18, 0x80, 0x1b, 0x7a, 0xb4, 0xac,
+    0x71, 0x58, 0x7d, 0x34, 0x5d, 0xcc, 0x83, 0x09, 0xd5, 0xb6, 0x2a, 0x50, 0x42, 0x7a, 0xa6, 0xd0,
+    0x3d, 0xcb, 0x05, 0x99, 0x6c, 0x96, 0xba, 0x0c, 0x5d, 0x71, 0xe9, 0x21, 0x62, 0xc0, 0x16, 0xca,
+    0x84, 0x9f, 0xf3, 0x5f, 0x0d, 0x52, 0xc6, 0x5d, 0x05, 0x60, 0x5a, 0x47, 0xf3, 0xae, 0x91, 0x7a,
+    0xcd, 0x2d, 0xf9, 0x10, 0xef, 0xd2, 0x32, 0x66, 0x88, 0x59, 0x6e, 0xf6, 0x9b, 0x3b, 0xf5, 0xfe,
+    0x31, 0x54, 0xf7, 0xae, 0xb8, 0x80, 0xa0, 0xa7, 0x3c, 0xa0, 0x4d, 0x94, 0xc2, 0xce, 0x83, 0x17,
+    0xee, 0xb4, 0x3d, 0x5e, 0xff, 0x58, 0x83, 0xe3, 0x36, 0xf5, 0xf2, 0x49, 0xda, 0xac, 0xa4, 0x89,
+    0x92, 0x37, 0xbf, 0x26, 0x7e, 0x5c, 0x43, 0xab, 0x02, 0xea, 0x44, 0x16, 0x24, 0x03, 0x72, 0x3b,
+    0xe6, 0xaa, 0x69, 0x2c, 0x61, 0xbd, 0xae, 0x9e, 0xd4, 0x09, 0xd4, 0x63, 0xc4, 0xc9, 0x7c, 0x64,
+    0x30, 0x65, 0x77, 0xee, 0xf2, 0xbc, 0x75, 0x60, 0xb7, 0x57, 0x15, 0xcc, 0x9c, 0x7d, 0xc6, 0x7c,
+    0x86, 0x08, 0x2d, 0xb7, 0x51, 0xa8, 0x9c, 0x30, 0x34, 0x97, 0x62, 0xb0, 0x78, 0x23, 0x85, 0x87,
+    0x5c, 0xf1, 0xa3, 0xc6, 0x16, 0x6e, 0x0a, 0xe3, 0xc1, 0x2d, 0x37, 0x4e, 0x2d, 0x4f, 0x18, 0x46,
+    0xf3, 0x18, 0x74, 0x4b, 0xd8, 0x79, 0xb5, 0x87, 0x32, 0x9b, 0xf0, 0x18, 0x21, 0x7a, 0x6c, 0x0c,
+    0x77, 0x24, 0x1a, 0x48, 0x78, 0xe4, 0x35, 0xc0, 0x30, 0x79, 0xcb, 0x45, 0x12, 0x89, 0xc5, 0x77,
+    0x62, 0x06, 0x06, 0x9a, 0x2f, 0x8d, 0x65, 0xf8, 0x40, 0xe1, 0x44, 0x52, 0x87, 0xbe, 0xd8, 0x77,
+    0xab, 0xae, 0x24, 0xe2, 0x44, 0x35, 0x16, 0x8d, 0x55, 0x3c, 0xe4,
+];
+
+pub static USRPKEY_NON_AUTHBOUND: &[u8] = &[
+    0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1d, 0x44, 0x4b, 0x4d, 0x4b, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8a, 0xc1, 0x08, 0x13, 0x7c, 0x47, 0xba, 0x09,
+    0x0e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb0, 0xad, 0x01, 0x00, 0x01,
+    0x75, 0x15, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x60,
+    0x60, 0x8c, 0x31, 0x76, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x61, 0x34,
+    0x01, 0x01, 0xb9, 0x61, 0x34, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0xa1, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xc9, 0xcd, 0xcb, 0xca, 0xfa, 0x37, 0xe2,
+    0xc7, 0x56, 0x8c, 0x23, 0xf6, 0x7f, 0xd1, 0x8c, 0x01, 0xc1, 0x4f, 0x65, 0xd7, 0x1b, 0x10, 0xc5,
+    0x0a, 0x77, 0x13, 0xf2, 0x82, 0xde, 0x63, 0x68, 0x5f, 0xec, 0x2f, 0x95, 0x34, 0x65, 0x5d, 0x2f,
+    0x99, 0xfc, 0xed, 0x0d, 0x1b, 0xe9, 0xf4, 0x83, 0x38, 0x71, 0x83, 0x82, 0x64, 0x51, 0xab, 0x53,
+    0xb1, 0xfa, 0x73, 0x00, 0x20, 0x24, 0xdd, 0x1c, 0x13, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x00, 0x00, 0xe5, 0xa5, 0x27, 0xb5, 0x66, 0x76, 0x6c, 0x74, 0x36, 0xd7, 0x2d,
+    0xad, 0x32, 0x49, 0xd4, 0xa5, 0xed, 0xb2, 0x9c, 0x4b, 0xbd, 0xb8, 0xe1, 0x79, 0x9f, 0x8a, 0x72,
+    0xc3, 0xdf, 0x8b, 0x99, 0x49, 0xa8, 0x5e, 0x10, 0x00, 0xd6, 0xa6, 0x58, 0x49, 0x5a, 0xa2, 0x71,
+    0xb3, 0x54, 0xd3, 0x69, 0xb7, 0xfe, 0x51, 0xc5, 0xe4, 0x94, 0xff, 0x10, 0xd7, 0x46, 0x01, 0x78,
+    0x43, 0x8c, 0x9c, 0xbe, 0x2f, 0x9a, 0x4b, 0x5b, 0x72, 0x07, 0x4d, 0x8f, 0x25, 0x50, 0x1e, 0xb2,
+    0x46, 0xf0, 0xee, 0x50, 0x73, 0x6a, 0x7b, 0xa3, 0xe9, 0xb1, 0x08, 0x81, 0x00, 0xdf, 0x0e, 0xc9,
+    0xc3, 0x2c, 0x13, 0x64, 0xa1,
+];
+pub static USRPKEY_NON_AUTHBOUND_CHR: &[u8] = &[
+    0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+    0x6d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20,
+    0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10,
+    0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x00, 0x2d, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x01, 0x00, 0x70,
+    0x01, 0xbe, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x02, 0x00, 0x30, 0xb0, 0xad, 0x01,
+    0x00, 0xc2, 0x02, 0x00, 0x30, 0x75, 0x15, 0x03, 0x00, 0xcf, 0x02, 0x00, 0x30, 0xb9, 0x61, 0x34,
+    0x01, 0xce, 0x02, 0x00, 0x30, 0xb9, 0x61, 0x34, 0x01, 0x30, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xbd, 0x02, 0x00,
+    0x60, 0x60, 0x60, 0x8c, 0x31, 0x76, 0x01, 0x00, 0x00, 0xf5, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00,
+    0x00,
+];
+pub static USRCERT_NON_AUTHBOUND: &[u8] = &[
+    0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x97, 0x30, 0x82, 0x02, 0x93, 0x30, 0x82, 0x02, 0x39,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
+    0x3d, 0x04, 0x03, 0x02, 0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13,
+    0x10, 0x34, 0x34, 0x61, 0x38, 0x31, 0x65, 0x61, 0x65, 0x63, 0x35, 0x31, 0x64, 0x62, 0x30, 0x62,
+    0x31, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54, 0x45, 0x45, 0x30,
+    0x20, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
+    0x18, 0x0f, 0x32, 0x31, 0x30, 0x36, 0x30, 0x32, 0x30, 0x37, 0x30, 0x36, 0x32, 0x38, 0x31, 0x35,
+    0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x14, 0x41, 0x6e,
+    0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x4b,
+    0x65, 0x79, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06,
+    0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xa8, 0x5e, 0x10,
+    0x00, 0xd6, 0xa6, 0x58, 0x49, 0x5a, 0xa2, 0x71, 0xb3, 0x54, 0xd3, 0x69, 0xb7, 0xfe, 0x51, 0xc5,
+    0xe4, 0x94, 0xff, 0x10, 0xd7, 0x46, 0x01, 0x78, 0x43, 0x8c, 0x9c, 0xbe, 0x2f, 0x9a, 0x4b, 0x5b,
+    0x72, 0x07, 0x4d, 0x8f, 0x25, 0x50, 0x1e, 0xb2, 0x46, 0xf0, 0xee, 0x50, 0x73, 0x6a, 0x7b, 0xa3,
+    0xe9, 0xb1, 0x08, 0x81, 0x00, 0xdf, 0x0e, 0xc9, 0xc3, 0x2c, 0x13, 0x64, 0xa1, 0xa3, 0x82, 0x01,
+    0x58, 0x30, 0x82, 0x01, 0x54, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x82, 0x01, 0x40, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+    0xd6, 0x79, 0x02, 0x01, 0x11, 0x04, 0x82, 0x01, 0x30, 0x30, 0x82, 0x01, 0x2c, 0x02, 0x01, 0x03,
+    0x0a, 0x01, 0x01, 0x02, 0x01, 0x04, 0x0a, 0x01, 0x01, 0x04, 0x08, 0x61, 0x73, 0x64, 0x66, 0x6a,
+    0x6b, 0x6c, 0x3b, 0x04, 0x00, 0x30, 0x6b, 0xbf, 0x85, 0x3d, 0x08, 0x02, 0x06, 0x01, 0x76, 0x31,
+    0x8c, 0x60, 0x60, 0xbf, 0x85, 0x45, 0x5b, 0x04, 0x59, 0x30, 0x57, 0x31, 0x31, 0x30, 0x2f, 0x04,
+    0x2a, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x65,
+    0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6a, 0x64, 0x61, 0x6e, 0x69, 0x73, 0x2e, 0x6b,
+    0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x02, 0x01, 0x01, 0x31, 0x22,
+    0x04, 0x20, 0x30, 0xe0, 0x78, 0x45, 0xab, 0xd7, 0xc1, 0x74, 0x49, 0x01, 0x0f, 0xa7, 0x7f, 0x89,
+    0xde, 0x11, 0xa3, 0x8b, 0x3e, 0x31, 0x6b, 0xf1, 0x18, 0xb4, 0x58, 0x1b, 0xd7, 0xb3, 0x58, 0xa9,
+    0xc2, 0x81, 0x30, 0x81, 0xa4, 0xa1, 0x08, 0x31, 0x06, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03, 0xa2,
+    0x03, 0x02, 0x01, 0x03, 0xa3, 0x04, 0x02, 0x02, 0x01, 0x00, 0xa5, 0x05, 0x31, 0x03, 0x02, 0x01,
+    0x04, 0xaa, 0x03, 0x02, 0x01, 0x01, 0xbf, 0x83, 0x77, 0x02, 0x05, 0x00, 0xbf, 0x85, 0x3e, 0x03,
+    0x02, 0x01, 0x00, 0xbf, 0x85, 0x40, 0x4c, 0x30, 0x4a, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0a, 0x01,
+    0x02, 0x04, 0x20, 0xe7, 0xad, 0x3c, 0x13, 0xc2, 0x73, 0x41, 0x60, 0xd7, 0x1a, 0x7c, 0x00, 0x5e,
+    0x14, 0xd8, 0xae, 0x06, 0x5d, 0x22, 0xd0, 0xb5, 0xf5, 0x6a, 0xba, 0x1f, 0x82, 0xa7, 0x8c, 0x17,
+    0x2c, 0xfd, 0x0f, 0xbf, 0x85, 0x41, 0x05, 0x02, 0x03, 0x01, 0xad, 0xb0, 0xbf, 0x85, 0x42, 0x05,
+    0x02, 0x03, 0x03, 0x15, 0x75, 0xbf, 0x85, 0x4e, 0x06, 0x02, 0x04, 0x01, 0x34, 0x61, 0xb9, 0xbf,
+    0x85, 0x4f, 0x06, 0x02, 0x04, 0x01, 0x34, 0x61, 0xb9, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48,
+    0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x3f, 0x12, 0x76, 0x4c,
+    0x85, 0xfd, 0xc9, 0x68, 0x0d, 0x66, 0x0b, 0x60, 0x3d, 0xff, 0x7c, 0x8b, 0x11, 0x9c, 0x26, 0xef,
+    0xdb, 0x4a, 0xc3, 0x37, 0x40, 0x06, 0xa9, 0x16, 0xc7, 0x99, 0x85, 0x89, 0x02, 0x21, 0x00, 0xc7,
+    0x02, 0xf3, 0x21, 0x60, 0x17, 0x05, 0x7e, 0x36, 0x33, 0x21, 0x0c, 0x1d, 0x27, 0xc3, 0x8f, 0xd6,
+    0xd8, 0xd5, 0xd1, 0x64, 0x4c, 0x05, 0xdd, 0x13, 0x0e, 0xa4, 0xf3, 0x38, 0xbf, 0x18, 0xd5,
+];
+
+pub static CACERT_NON_AUTHBOUND: &[u8] = &[
+    0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x63, 0x30, 0x82, 0x02, 0x26, 0x30, 0x82, 0x01, 0xab,
+    0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x05, 0x84, 0x20, 0x26, 0x90, 0x76, 0x23, 0x58, 0x71,
+    0x77, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x29, 0x31,
+    0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x64, 0x37, 0x34, 0x61, 0x30,
+    0x65, 0x30, 0x31, 0x61, 0x61, 0x66, 0x33, 0x64, 0x64, 0x66, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03,
+    0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54, 0x45, 0x45, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33,
+    0x32, 0x31, 0x32, 0x31, 0x32, 0x35, 0x31, 0x33, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x33, 0x31,
+    0x38, 0x32, 0x31, 0x32, 0x35, 0x31, 0x33, 0x5a, 0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03,
+    0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x34, 0x61, 0x38, 0x31, 0x65, 0x61, 0x65, 0x63, 0x35, 0x31,
+    0x64, 0x62, 0x30, 0x62, 0x31, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03,
+    0x54, 0x45, 0x45, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
+    0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xfa, 0x35,
+    0x8f, 0xb0, 0x31, 0xd6, 0x30, 0x88, 0xde, 0xb0, 0x29, 0xcd, 0x6c, 0x7d, 0x4e, 0xa9, 0xce, 0x6e,
+    0x9d, 0x7a, 0xac, 0x97, 0x92, 0xc2, 0x45, 0xb5, 0xe2, 0xd0, 0xc1, 0x52, 0xa8, 0x50, 0x25, 0xd7,
+    0x89, 0x58, 0x7b, 0x04, 0xb6, 0x66, 0x93, 0x2a, 0x26, 0x5d, 0x3a, 0xb1, 0x5b, 0x77, 0x30, 0xbf,
+    0x95, 0xaa, 0x8b, 0x43, 0xc3, 0xbf, 0x43, 0xb7, 0xee, 0xac, 0x73, 0xdc, 0x03, 0x6a, 0xa3, 0x81,
+    0xba, 0x30, 0x81, 0xb7, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x19,
+    0x9f, 0x87, 0x8b, 0x56, 0xf4, 0x99, 0x3a, 0x69, 0x96, 0x9b, 0x8d, 0x9e, 0x64, 0xaa, 0x56, 0xb4,
+    0x7f, 0x8b, 0x4d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+    0xa9, 0xb5, 0xf4, 0x29, 0xc9, 0x1a, 0x58, 0xbd, 0x2f, 0x98, 0x2d, 0x67, 0x73, 0x31, 0x06, 0x87,
+    0xe0, 0xdf, 0xcd, 0x62, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+    0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x54, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x4d, 0x30, 0x4b,
+    0x30, 0x49, 0xa0, 0x47, 0xa0, 0x45, 0x86, 0x43, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+    0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70,
+    0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x30, 0x35, 0x38, 0x34, 0x32, 0x30, 0x32, 0x36, 0x39,
+    0x30, 0x37, 0x36, 0x32, 0x33, 0x35, 0x38, 0x37, 0x31, 0x37, 0x37, 0x30, 0x0a, 0x06, 0x08, 0x2a,
+    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xe3,
+    0x35, 0xc6, 0xa8, 0xb2, 0x75, 0x9c, 0x56, 0x7b, 0x6e, 0x61, 0x80, 0x65, 0x2c, 0x06, 0x88, 0xdd,
+    0xb9, 0x68, 0x4d, 0x3c, 0x68, 0x49, 0x66, 0x01, 0x4e, 0x30, 0x1d, 0xf3, 0xec, 0xa5, 0x51, 0x5c,
+    0xbf, 0xe7, 0x83, 0x33, 0xbd, 0x14, 0xee, 0x23, 0xf0, 0xcf, 0xb1, 0x37, 0x1c, 0x27, 0x78, 0x02,
+    0x31, 0x00, 0x94, 0xcb, 0x08, 0x3d, 0x2d, 0x3e, 0x69, 0x54, 0x5f, 0x63, 0xe3, 0xe4, 0x74, 0x72,
+    0xe2, 0xff, 0x8b, 0x26, 0xd2, 0x86, 0xc0, 0x97, 0x32, 0x40, 0xdd, 0x7c, 0x1f, 0x50, 0x60, 0x57,
+    0xcf, 0x2e, 0x23, 0xf3, 0x33, 0xe4, 0xfb, 0x6f, 0x5b, 0x7c, 0xc6, 0x31, 0x85, 0xae, 0xe0, 0x4e,
+    0x44, 0xa9, 0x30, 0x82, 0x03, 0xd1, 0x30, 0x82, 0x01, 0xb9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+    0x0a, 0x03, 0x88, 0x26, 0x67, 0x60, 0x65, 0x89, 0x96, 0x85, 0x7f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17,
+    0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x66, 0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38, 0x35,
+    0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32,
+    0x31, 0x32, 0x31, 0x31, 0x34, 0x31, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x33, 0x31, 0x38,
+    0x32, 0x31, 0x31, 0x34, 0x31, 0x34, 0x5a, 0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55,
+    0x04, 0x05, 0x13, 0x10, 0x34, 0x64, 0x37, 0x34, 0x61, 0x30, 0x65, 0x30, 0x31, 0x61, 0x61, 0x66,
+    0x33, 0x64, 0x64, 0x66, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54,
+    0x45, 0x45, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06,
+    0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xd5, 0xf5, 0x0e, 0xe2, 0x8d, 0xf3,
+    0x33, 0x4a, 0x6a, 0x77, 0x90, 0x9c, 0xc2, 0x25, 0xc8, 0x8a, 0x32, 0xae, 0x3b, 0xb4, 0x9c, 0x4a,
+    0x95, 0x22, 0x0c, 0xba, 0x0a, 0x76, 0xca, 0xcb, 0x24, 0x0c, 0x84, 0x3a, 0x83, 0x76, 0x04, 0x23,
+    0x31, 0x3a, 0xa0, 0x82, 0x80, 0x26, 0x65, 0xfd, 0x2f, 0x44, 0xf4, 0x96, 0xd8, 0xb7, 0xdc, 0xac,
+    0x55, 0x34, 0x74, 0x41, 0x0d, 0x0d, 0x7f, 0xbd, 0xe3, 0xf4, 0x28, 0xdf, 0x74, 0x4a, 0x17, 0x4d,
+    0xe7, 0xb2, 0x9b, 0x2b, 0x24, 0xc0, 0x9e, 0x56, 0x00, 0x52, 0xbb, 0x75, 0xb0, 0xd5, 0x6a, 0x41,
+    0x16, 0x08, 0xce, 0x32, 0xdb, 0x8f, 0x8b, 0x20, 0x73, 0x72, 0xa3, 0x81, 0xb6, 0x30, 0x81, 0xb3,
+    0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa9, 0xb5, 0xf4, 0x29, 0xc9,
+    0x1a, 0x58, 0xbd, 0x2f, 0x98, 0x2d, 0x67, 0x73, 0x31, 0x06, 0x87, 0xe0, 0xdf, 0xcd, 0x62, 0x30,
+    0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x36, 0x61, 0xe1, 0x00,
+    0x7c, 0x88, 0x05, 0x09, 0x51, 0x8b, 0x44, 0x6c, 0x47, 0xff, 0x1a, 0x4c, 0xc9, 0xea, 0x4f, 0x12,
+    0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+    0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02,
+    0x04, 0x30, 0x50, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x49, 0x30, 0x47, 0x30, 0x45, 0xa0, 0x43,
+    0xa0, 0x41, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x61, 0x6e, 0x64, 0x72,
+    0x6f, 0x69, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63,
+    0x6f, 0x6d, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63,
+    0x72, 0x6c, 0x2f, 0x45, 0x38, 0x46, 0x41, 0x31, 0x39, 0x36, 0x33, 0x31, 0x34, 0x44, 0x32, 0x46,
+    0x41, 0x31, 0x38, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+    0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x32, 0xce, 0x04, 0xcc, 0x4d, 0x82, 0xad, 0x1d, 0xde,
+    0xa5, 0xcf, 0xe2, 0x1a, 0xa3, 0x79, 0xf7, 0xed, 0x88, 0x1e, 0x0e, 0x67, 0x8e, 0xfc, 0xbe, 0x7b,
+    0x04, 0xb7, 0x26, 0x59, 0xca, 0x95, 0x47, 0x8a, 0x10, 0x3f, 0xe5, 0x14, 0x19, 0xec, 0xd4, 0xdb,
+    0x33, 0xc3, 0xa1, 0x51, 0xf5, 0x06, 0x5e, 0x30, 0x66, 0x1f, 0xd2, 0x58, 0x2f, 0x14, 0x03, 0x7b,
+    0x35, 0x83, 0x86, 0x46, 0xdc, 0xee, 0x04, 0x30, 0xa1, 0x0f, 0xc4, 0x16, 0xc9, 0x8e, 0x63, 0xd0,
+    0xda, 0x5c, 0xb0, 0xf7, 0x3e, 0x21, 0xb6, 0xa5, 0x04, 0x07, 0x5a, 0x01, 0x8c, 0x31, 0x1f, 0x3e,
+    0x3a, 0xaf, 0x8d, 0x31, 0x3e, 0xb6, 0x12, 0x14, 0xf0, 0x0d, 0x2c, 0xcc, 0x6c, 0xb8, 0x7a, 0xbf,
+    0xd2, 0x6b, 0x5f, 0x27, 0xb0, 0xff, 0xc0, 0xaa, 0xde, 0xde, 0xf6, 0x31, 0x6d, 0xf3, 0x95, 0xc2,
+    0xd4, 0x90, 0xdc, 0x82, 0x4f, 0x24, 0x0d, 0x85, 0xf2, 0xbb, 0xc4, 0x58, 0xc9, 0xfa, 0xdd, 0x96,
+    0x41, 0x2b, 0x1f, 0x4c, 0x10, 0x1c, 0x9a, 0x57, 0x55, 0x0f, 0x62, 0xfc, 0x8d, 0xa2, 0xca, 0x84,
+    0x7b, 0x16, 0x60, 0xe8, 0x62, 0xce, 0x92, 0x85, 0x13, 0xf0, 0x63, 0x83, 0xd8, 0x5b, 0xa8, 0x74,
+    0x78, 0xb5, 0x28, 0xdb, 0x6c, 0xc9, 0x6e, 0x85, 0x85, 0x52, 0x3f, 0xd8, 0x67, 0xae, 0xf4, 0x09,
+    0xbe, 0xcf, 0x8c, 0x7f, 0x72, 0xb2, 0xc8, 0x93, 0xc6, 0xd2, 0xf3, 0x38, 0x74, 0x71, 0x22, 0xd6,
+    0x92, 0x76, 0xb1, 0xae, 0x14, 0x5a, 0x09, 0xd8, 0xaf, 0x1d, 0xaf, 0x48, 0x22, 0x5c, 0x30, 0x85,
+    0x8e, 0xc2, 0xfe, 0x61, 0xaf, 0xc3, 0xd2, 0x4c, 0x92, 0x53, 0xa4, 0x75, 0x1f, 0x78, 0xea, 0xfc,
+    0xfa, 0xc4, 0xca, 0x4e, 0x67, 0x68, 0x1f, 0x7d, 0xb2, 0x5e, 0xea, 0x8a, 0xb1, 0xcc, 0xb6, 0x92,
+    0x64, 0xf8, 0x82, 0xc0, 0x8b, 0xdc, 0x24, 0xe8, 0x57, 0x20, 0x33, 0x6d, 0x17, 0x33, 0x0d, 0xcb,
+    0x70, 0x02, 0x8b, 0xe5, 0xe3, 0x7d, 0x2c, 0x98, 0x32, 0x00, 0x20, 0xb4, 0xbd, 0xee, 0x89, 0xaa,
+    0x66, 0x13, 0x34, 0x9d, 0x9c, 0x8f, 0xde, 0x16, 0x09, 0x91, 0x49, 0x80, 0x50, 0x57, 0x39, 0xae,
+    0x35, 0x01, 0xe2, 0x25, 0x8e, 0x17, 0x08, 0xe0, 0xf0, 0x77, 0x98, 0x9d, 0x0a, 0x4f, 0xd2, 0x76,
+    0xda, 0xc4, 0x51, 0x45, 0x32, 0x8b, 0xe1, 0xab, 0xee, 0x10, 0x16, 0xf6, 0x95, 0x7d, 0x32, 0x76,
+    0xb2, 0xb5, 0x19, 0x67, 0x73, 0xfe, 0xc0, 0xc6, 0xa9, 0xd2, 0xa9, 0x23, 0xf0, 0x2b, 0xfc, 0xb1,
+    0xb6, 0xec, 0x3e, 0x11, 0x60, 0xa4, 0x22, 0xc7, 0xff, 0x25, 0xc3, 0xed, 0x6c, 0x6b, 0x79, 0x02,
+    0x3d, 0x5d, 0x62, 0x36, 0xd9, 0x32, 0xe4, 0x6e, 0x47, 0x67, 0x85, 0x8b, 0x23, 0x0a, 0xd5, 0x1e,
+    0xd0, 0xf4, 0x17, 0x1d, 0xcc, 0x3f, 0x5f, 0xda, 0x12, 0xe2, 0x35, 0x25, 0x52, 0xc2, 0xd6, 0x94,
+    0x3e, 0x83, 0x60, 0x55, 0xf8, 0x8d, 0x54, 0xf5, 0x47, 0x6f, 0x38, 0x03, 0x3b, 0xd7, 0x9a, 0x94,
+    0x8a, 0x3b, 0x9f, 0x92, 0x69, 0x0f, 0xcd, 0xb8, 0xf4, 0x62, 0x78, 0x22, 0x47, 0xe0, 0xae, 0xed,
+    0xfd, 0xf6, 0xe4, 0xc5, 0x8c, 0x0e, 0xb5, 0x18, 0xb1, 0x46, 0x3a, 0x6f, 0xbd, 0xde, 0x50, 0x3f,
+    0x1c, 0x35, 0x28, 0xf9, 0xed, 0x1e, 0xe8, 0x15, 0x31, 0xa9, 0xf7, 0xb1, 0x9d, 0xe1, 0x34, 0x81,
+    0x20, 0x1f, 0x22, 0xd4, 0xb7, 0xc6, 0x59, 0x8b, 0x90, 0x98, 0xdf, 0xa6, 0xb9, 0xa8, 0x8e, 0x6c,
+    0x15, 0x55, 0x5c, 0x41, 0x96, 0x82, 0x0d, 0xa9, 0x5f, 0xa9, 0xf3, 0x77, 0x1d, 0xee, 0x6b, 0x4c,
+    0x94, 0xc6, 0xc6, 0x9b, 0x78, 0x5b, 0x03, 0xbd, 0xa9, 0x87, 0xdd, 0x24, 0x04, 0x70, 0xce, 0x6c,
+    0x52, 0xe6, 0x21, 0x63, 0x6d, 0x28, 0x6c, 0x30, 0x82, 0x05, 0x60, 0x30, 0x82, 0x03, 0x48, 0xa0,
+    0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xe8, 0xfa, 0x19, 0x63, 0x14, 0xd2, 0xfa, 0x18, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1b,
+    0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x66, 0x39, 0x32, 0x30, 0x30,
+    0x39, 0x65, 0x38, 0x35, 0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35, 0x30, 0x1e, 0x17, 0x0d, 0x31,
+    0x36, 0x30, 0x35, 0x32, 0x36, 0x31, 0x36, 0x32, 0x38, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x36,
+    0x30, 0x35, 0x32, 0x34, 0x31, 0x36, 0x32, 0x38, 0x35, 0x32, 0x5a, 0x30, 0x1b, 0x31, 0x19, 0x30,
+    0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x66, 0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38,
+    0x35, 0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00,
+    0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xaf, 0xb6, 0xc7, 0x82, 0x2b, 0xb1, 0xa7,
+    0x01, 0xec, 0x2b, 0xb4, 0x2e, 0x8b, 0xcc, 0x54, 0x16, 0x63, 0xab, 0xef, 0x98, 0x2f, 0x32, 0xc7,
+    0x7f, 0x75, 0x31, 0x03, 0x0c, 0x97, 0x52, 0x4b, 0x1b, 0x5f, 0xe8, 0x09, 0xfb, 0xc7, 0x2a, 0xa9,
+    0x45, 0x1f, 0x74, 0x3c, 0xbd, 0x9a, 0x6f, 0x13, 0x35, 0x74, 0x4a, 0xa5, 0x5e, 0x77, 0xf6, 0xb6,
+    0xac, 0x35, 0x35, 0xee, 0x17, 0xc2, 0x5e, 0x63, 0x95, 0x17, 0xdd, 0x9c, 0x92, 0xe6, 0x37, 0x4a,
+    0x53, 0xcb, 0xfe, 0x25, 0x8f, 0x8f, 0xfb, 0xb6, 0xfd, 0x12, 0x93, 0x78, 0xa2, 0x2a, 0x4c, 0xa9,
+    0x9c, 0x45, 0x2d, 0x47, 0xa5, 0x9f, 0x32, 0x01, 0xf4, 0x41, 0x97, 0xca, 0x1c, 0xcd, 0x7e, 0x76,
+    0x2f, 0xb2, 0xf5, 0x31, 0x51, 0xb6, 0xfe, 0xb2, 0xff, 0xfd, 0x2b, 0x6f, 0xe4, 0xfe, 0x5b, 0xc6,
+    0xbd, 0x9e, 0xc3, 0x4b, 0xfe, 0x08, 0x23, 0x9d, 0xaa, 0xfc, 0xeb, 0x8e, 0xb5, 0xa8, 0xed, 0x2b,
+    0x3a, 0xcd, 0x9c, 0x5e, 0x3a, 0x77, 0x90, 0xe1, 0xb5, 0x14, 0x42, 0x79, 0x31, 0x59, 0x85, 0x98,
+    0x11, 0xad, 0x9e, 0xb2, 0xa9, 0x6b, 0xbd, 0xd7, 0xa5, 0x7c, 0x93, 0xa9, 0x1c, 0x41, 0xfc, 0xcd,
+    0x27, 0xd6, 0x7f, 0xd6, 0xf6, 0x71, 0xaa, 0x0b, 0x81, 0x52, 0x61, 0xad, 0x38, 0x4f, 0xa3, 0x79,
+    0x44, 0x86, 0x46, 0x04, 0xdd, 0xb3, 0xd8, 0xc4, 0xf9, 0x20, 0xa1, 0x9b, 0x16, 0x56, 0xc2, 0xf1,
+    0x4a, 0xd6, 0xd0, 0x3c, 0x56, 0xec, 0x06, 0x08, 0x99, 0x04, 0x1c, 0x1e, 0xd1, 0xa5, 0xfe, 0x6d,
+    0x34, 0x40, 0xb5, 0x56, 0xba, 0xd1, 0xd0, 0xa1, 0x52, 0x58, 0x9c, 0x53, 0xe5, 0x5d, 0x37, 0x07,
+    0x62, 0xf0, 0x12, 0x2e, 0xef, 0x91, 0x86, 0x1b, 0x1b, 0x0e, 0x6c, 0x4c, 0x80, 0x92, 0x74, 0x99,
+    0xc0, 0xe9, 0xbe, 0xc0, 0xb8, 0x3e, 0x3b, 0xc1, 0xf9, 0x3c, 0x72, 0xc0, 0x49, 0x60, 0x4b, 0xbd,
+    0x2f, 0x13, 0x45, 0xe6, 0x2c, 0x3f, 0x8e, 0x26, 0xdb, 0xec, 0x06, 0xc9, 0x47, 0x66, 0xf3, 0xc1,
+    0x28, 0x23, 0x9d, 0x4f, 0x43, 0x12, 0xfa, 0xd8, 0x12, 0x38, 0x87, 0xe0, 0x6b, 0xec, 0xf5, 0x67,
+    0x58, 0x3b, 0xf8, 0x35, 0x5a, 0x81, 0xfe, 0xea, 0xba, 0xf9, 0x9a, 0x83, 0xc8, 0xdf, 0x3e, 0x2a,
+    0x32, 0x2a, 0xfc, 0x67, 0x2b, 0xf1, 0x20, 0xb1, 0x35, 0x15, 0x8b, 0x68, 0x21, 0xce, 0xaf, 0x30,
+    0x9b, 0x6e, 0xee, 0x77, 0xf9, 0x88, 0x33, 0xb0, 0x18, 0xda, 0xa1, 0x0e, 0x45, 0x1f, 0x06, 0xa3,
+    0x74, 0xd5, 0x07, 0x81, 0xf3, 0x59, 0x08, 0x29, 0x66, 0xbb, 0x77, 0x8b, 0x93, 0x08, 0x94, 0x26,
+    0x98, 0xe7, 0x4e, 0x0b, 0xcd, 0x24, 0x62, 0x8a, 0x01, 0xc2, 0xcc, 0x03, 0xe5, 0x1f, 0x0b, 0x3e,
+    0x5b, 0x4a, 0xc1, 0xe4, 0xdf, 0x9e, 0xaf, 0x9f, 0xf6, 0xa4, 0x92, 0xa7, 0x7c, 0x14, 0x83, 0x88,
+    0x28, 0x85, 0x01, 0x5b, 0x42, 0x2c, 0xe6, 0x7b, 0x80, 0xb8, 0x8c, 0x9b, 0x48, 0xe1, 0x3b, 0x60,
+    0x7a, 0xb5, 0x45, 0xc7, 0x23, 0xff, 0x8c, 0x44, 0xf8, 0xf2, 0xd3, 0x68, 0xb9, 0xf6, 0x52, 0x0d,
+    0x31, 0x14, 0x5e, 0xbf, 0x9e, 0x86, 0x2a, 0xd7, 0x1d, 0xf6, 0xa3, 0xbf, 0xd2, 0x45, 0x09, 0x59,
+    0xd6, 0x53, 0x74, 0x0d, 0x97, 0xa1, 0x2f, 0x36, 0x8b, 0x13, 0xef, 0x66, 0xd5, 0xd0, 0xa5, 0x4a,
+    0x6e, 0x2f, 0x5d, 0x9a, 0x6f, 0xef, 0x44, 0x68, 0x32, 0xbc, 0x67, 0x84, 0x47, 0x25, 0x86, 0x1f,
+    0x09, 0x3d, 0xd0, 0xe6, 0xf3, 0x40, 0x5d, 0xa8, 0x96, 0x43, 0xef, 0x0f, 0x4d, 0x69, 0xb6, 0x42,
+    0x00, 0x51, 0xfd, 0xb9, 0x30, 0x49, 0x67, 0x3e, 0x36, 0x95, 0x05, 0x80, 0xd3, 0xcd, 0xf4, 0xfb,
+    0xd0, 0x8b, 0xc5, 0x84, 0x83, 0x95, 0x26, 0x00, 0x63, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
+    0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x36,
+    0x61, 0xe1, 0x00, 0x7c, 0x88, 0x05, 0x09, 0x51, 0x8b, 0x44, 0x6c, 0x47, 0xff, 0x1a, 0x4c, 0xc9,
+    0xea, 0x4f, 0x12, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+    0x36, 0x61, 0xe1, 0x00, 0x7c, 0x88, 0x05, 0x09, 0x51, 0x8b, 0x44, 0x6c, 0x47, 0xff, 0x1a, 0x4c,
+    0xc9, 0xea, 0x4f, 0x12, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05,
+    0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+    0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x40, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x39, 0x30, 0x37,
+    0x30, 0x35, 0xa0, 0x33, 0xa0, 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+    0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70,
+    0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x20, 0xc8, 0xc3, 0x8d, 0x4b,
+    0xdc, 0xa9, 0x57, 0x1b, 0x46, 0x8c, 0x89, 0x2f, 0xff, 0x72, 0xaa, 0xc6, 0xf8, 0x44, 0xa1, 0x1d,
+    0x41, 0xa8, 0xf0, 0x73, 0x6c, 0xc3, 0x7d, 0x16, 0xd6, 0x42, 0x6d, 0x8e, 0x7e, 0x94, 0x07, 0x04,
+    0x4c, 0xea, 0x39, 0xe6, 0x8b, 0x07, 0xc1, 0x3d, 0xbf, 0x15, 0x03, 0xdd, 0x5c, 0x85, 0xbd, 0xaf,
+    0xb2, 0xc0, 0x2d, 0x5f, 0x6c, 0xdb, 0x4e, 0xfa, 0x81, 0x27, 0xdf, 0x8b, 0x04, 0xf1, 0x82, 0x77,
+    0x0f, 0xc4, 0xe7, 0x74, 0x5b, 0x7f, 0xce, 0xaa, 0x87, 0x12, 0x9a, 0x88, 0x01, 0xce, 0x8e, 0x9b,
+    0xc0, 0xcb, 0x96, 0x37, 0x9b, 0x4d, 0x26, 0xa8, 0x2d, 0x30, 0xfd, 0x9c, 0x2f, 0x8e, 0xed, 0x6d,
+    0xc1, 0xbe, 0x2f, 0x84, 0xb6, 0x89, 0xe4, 0xd9, 0x14, 0x25, 0x8b, 0x14, 0x4b, 0xba, 0xe6, 0x24,
+    0xa1, 0xc7, 0x06, 0x71, 0x13, 0x2e, 0x2f, 0x06, 0x16, 0xa8, 0x84, 0xb2, 0xa4, 0xd6, 0xa4, 0x6f,
+    0xfa, 0x89, 0xb6, 0x02, 0xbf, 0xba, 0xd8, 0x0c, 0x12, 0x43, 0x71, 0x1f, 0x56, 0xeb, 0x60, 0x56,
+    0xf6, 0x37, 0xc8, 0xa0, 0x14, 0x1c, 0xc5, 0x40, 0x94, 0x26, 0x8b, 0x8c, 0x3c, 0x7d, 0xb9, 0x94,
+    0xb3, 0x5c, 0x0d, 0xcd, 0x6c, 0xb2, 0xab, 0xc2, 0xda, 0xfe, 0xe2, 0x52, 0x02, 0x3d, 0x2d, 0xea,
+    0x0c, 0xd6, 0xc3, 0x68, 0xbe, 0xa3, 0xe6, 0x41, 0x48, 0x86, 0xf6, 0xb1, 0xe5, 0x8b, 0x5b, 0xd7,
+    0xc7, 0x30, 0xb2, 0x68, 0xc4, 0xe3, 0xc1, 0xfb, 0x64, 0x24, 0xb9, 0x1f, 0xeb, 0xbd, 0xb8, 0x0c,
+    0x58, 0x6e, 0x2a, 0xe8, 0x36, 0x8c, 0x84, 0xd5, 0xd1, 0x09, 0x17, 0xbd, 0xa2, 0x56, 0x17, 0x89,
+    0xd4, 0x68, 0x73, 0x93, 0x34, 0x0e, 0x2e, 0x25, 0x4f, 0x56, 0x0e, 0xf6, 0x4b, 0x23, 0x58, 0xfc,
+    0xdc, 0x0f, 0xbf, 0xc6, 0x70, 0x09, 0x52, 0xe7, 0x08, 0xbf, 0xfc, 0xc6, 0x27, 0x50, 0x0c, 0x1f,
+    0x66, 0xe8, 0x1e, 0xa1, 0x7c, 0x09, 0x8d, 0x7a, 0x2e, 0x9b, 0x18, 0x80, 0x1b, 0x7a, 0xb4, 0xac,
+    0x71, 0x58, 0x7d, 0x34, 0x5d, 0xcc, 0x83, 0x09, 0xd5, 0xb6, 0x2a, 0x50, 0x42, 0x7a, 0xa6, 0xd0,
+    0x3d, 0xcb, 0x05, 0x99, 0x6c, 0x96, 0xba, 0x0c, 0x5d, 0x71, 0xe9, 0x21, 0x62, 0xc0, 0x16, 0xca,
+    0x84, 0x9f, 0xf3, 0x5f, 0x0d, 0x52, 0xc6, 0x5d, 0x05, 0x60, 0x5a, 0x47, 0xf3, 0xae, 0x91, 0x7a,
+    0xcd, 0x2d, 0xf9, 0x10, 0xef, 0xd2, 0x32, 0x66, 0x88, 0x59, 0x6e, 0xf6, 0x9b, 0x3b, 0xf5, 0xfe,
+    0x31, 0x54, 0xf7, 0xae, 0xb8, 0x80, 0xa0, 0xa7, 0x3c, 0xa0, 0x4d, 0x94, 0xc2, 0xce, 0x83, 0x17,
+    0xee, 0xb4, 0x3d, 0x5e, 0xff, 0x58, 0x83, 0xe3, 0x36, 0xf5, 0xf2, 0x49, 0xda, 0xac, 0xa4, 0x89,
+    0x92, 0x37, 0xbf, 0x26, 0x7e, 0x5c, 0x43, 0xab, 0x02, 0xea, 0x44, 0x16, 0x24, 0x03, 0x72, 0x3b,
+    0xe6, 0xaa, 0x69, 0x2c, 0x61, 0xbd, 0xae, 0x9e, 0xd4, 0x09, 0xd4, 0x63, 0xc4, 0xc9, 0x7c, 0x64,
+    0x30, 0x65, 0x77, 0xee, 0xf2, 0xbc, 0x75, 0x60, 0xb7, 0x57, 0x15, 0xcc, 0x9c, 0x7d, 0xc6, 0x7c,
+    0x86, 0x08, 0x2d, 0xb7, 0x51, 0xa8, 0x9c, 0x30, 0x34, 0x97, 0x62, 0xb0, 0x78, 0x23, 0x85, 0x87,
+    0x5c, 0xf1, 0xa3, 0xc6, 0x16, 0x6e, 0x0a, 0xe3, 0xc1, 0x2d, 0x37, 0x4e, 0x2d, 0x4f, 0x18, 0x46,
+    0xf3, 0x18, 0x74, 0x4b, 0xd8, 0x79, 0xb5, 0x87, 0x32, 0x9b, 0xf0, 0x18, 0x21, 0x7a, 0x6c, 0x0c,
+    0x77, 0x24, 0x1a, 0x48, 0x78, 0xe4, 0x35, 0xc0, 0x30, 0x79, 0xcb, 0x45, 0x12, 0x89, 0xc5, 0x77,
+    0x62, 0x06, 0x06, 0x9a, 0x2f, 0x8d, 0x65, 0xf8, 0x40, 0xe1, 0x44, 0x52, 0x87, 0xbe, 0xd8, 0x77,
+    0xab, 0xae, 0x24, 0xe2, 0x44, 0x35, 0x16, 0x8d, 0x55, 0x3c, 0xe4,
+];
+
+pub static _DECRYPTED_USRPKEY_AUTHBOUND: &[u8] = &[
+    0x44, 0x4b, 0x4d, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0xc6, 0x15, 0x3a, 0x08, 0x1e, 0x43, 0xba, 0x7a, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xf0, 0x7e, 0x7d, 0xb4, 0xc6, 0xd7, 0x25, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0xb0, 0xad, 0x01, 0x00, 0x01, 0x75, 0x15, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x9d, 0x8b, 0x31, 0x76, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x61, 0x34, 0x01, 0x01, 0xb9, 0x61, 0x34, 0x01, 0x01, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00,
+    0x00, 0x37, 0x91, 0x69, 0xeb, 0x25, 0x1e, 0xcf, 0x6c, 0xab, 0xe1, 0x91, 0xdd, 0x2e, 0xf8, 0x86,
+    0x20, 0x97, 0x54, 0x23, 0x0b, 0x0a, 0x0c, 0x35, 0xcb, 0xcd, 0x9c, 0x60, 0x44, 0x29, 0xb3, 0xe9,
+    0x84, 0xa9, 0x91, 0xd9, 0x71, 0x62, 0x45, 0x7c, 0x2b, 0x73, 0xf5, 0x10, 0x6b, 0xc5, 0x35, 0xa7,
+    0x36, 0xcb, 0x65, 0x0d, 0x0d, 0xa9, 0x3a, 0x17, 0xd1, 0x83, 0x08, 0x22, 0xe4, 0x3a, 0xa1, 0x11,
+    0xac, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x4d, 0xac, 0x97,
+    0x2a, 0xc9, 0xfc, 0x59, 0x46, 0x9a, 0x5d, 0x9f, 0x55, 0x20, 0x91, 0xa3, 0x15, 0x37, 0xbb, 0x86,
+    0xb4, 0x03, 0xcb, 0x78, 0x48, 0x08, 0x0a, 0xad, 0x44, 0x35, 0x14, 0x0d, 0x6c, 0x20, 0x16, 0x85,
+    0xe6, 0x7f, 0xf1, 0x0e, 0x99, 0x1b, 0x3a, 0xc6, 0xc2, 0x83, 0x0a, 0x1d, 0xa4, 0xf1, 0x92, 0x76,
+    0x88, 0x4b, 0x6a, 0xcd, 0xb2, 0x8e, 0xf1, 0x50, 0x58, 0xd2, 0x69, 0xde, 0x57, 0x9c, 0x9c, 0x29,
+    0x04, 0x03, 0xf2, 0x4d, 0x12, 0x77, 0x9c, 0x62, 0xbc, 0x75, 0xb4, 0xab, 0x7a, 0xbc, 0xa0, 0x8f,
+    0x60, 0x5e, 0xcd, 0xce, 0x3a, 0xd8, 0x09, 0xeb, 0x9d, 0x40, 0xdb, 0x58, 0x53,
+];
+
+pub static LOADED_CERT_AUTHBOUND: &[u8] = &[
+    0x30, 0x82, 0x02, 0x93, 0x30, 0x82, 0x02, 0x3A, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01,
+    0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x29, 0x31, 0x19,
+    0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x34, 0x61, 0x38, 0x31, 0x65, 0x61,
+    0x65, 0x63, 0x35, 0x31, 0x64, 0x62, 0x30, 0x62, 0x31, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55,
+    0x04, 0x0C, 0x0C, 0x03, 0x54, 0x45, 0x45, 0x30, 0x20, 0x17, 0x0D, 0x37, 0x30, 0x30, 0x31, 0x30,
+    0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x18, 0x0F, 0x32, 0x31, 0x30, 0x36, 0x30, 0x32,
+    0x30, 0x37, 0x30, 0x36, 0x32, 0x38, 0x31, 0x35, 0x5A, 0x30, 0x1F, 0x31, 0x1D, 0x30, 0x1B, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64, 0x20, 0x4B, 0x65,
+    0x79, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x20, 0x4B, 0x65, 0x79, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
+    0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01,
+    0x07, 0x03, 0x42, 0x00, 0x04, 0x20, 0x16, 0x85, 0xE6, 0x7F, 0xF1, 0x0E, 0x99, 0x1B, 0x3A, 0xC6,
+    0xC2, 0x83, 0x0A, 0x1D, 0xA4, 0xF1, 0x92, 0x76, 0x88, 0x4B, 0x6A, 0xCD, 0xB2, 0x8E, 0xF1, 0x50,
+    0x58, 0xD2, 0x69, 0xDE, 0x57, 0x9C, 0x9C, 0x29, 0x04, 0x03, 0xF2, 0x4D, 0x12, 0x77, 0x9C, 0x62,
+    0xBC, 0x75, 0xB4, 0xAB, 0x7A, 0xBC, 0xA0, 0x8F, 0x60, 0x5E, 0xCD, 0xCE, 0x3A, 0xD8, 0x09, 0xEB,
+    0x9D, 0x40, 0xDB, 0x58, 0x53, 0xA3, 0x82, 0x01, 0x59, 0x30, 0x82, 0x01, 0x55, 0x30, 0x0E, 0x06,
+    0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x82, 0x01,
+    0x41, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xD6, 0x79, 0x02, 0x01, 0x11, 0x04, 0x82, 0x01,
+    0x31, 0x30, 0x82, 0x01, 0x2D, 0x02, 0x01, 0x03, 0x0A, 0x01, 0x01, 0x02, 0x01, 0x04, 0x0A, 0x01,
+    0x01, 0x04, 0x08, 0x61, 0x73, 0x64, 0x66, 0x6A, 0x6B, 0x6C, 0x3B, 0x04, 0x00, 0x30, 0x6B, 0xBF,
+    0x85, 0x3D, 0x08, 0x02, 0x06, 0x01, 0x76, 0x31, 0x8B, 0x9D, 0x10, 0xBF, 0x85, 0x45, 0x5B, 0x04,
+    0x59, 0x30, 0x57, 0x31, 0x31, 0x30, 0x2F, 0x04, 0x2A, 0x63, 0x6F, 0x6D, 0x2E, 0x67, 0x6F, 0x6F,
+    0x67, 0x6C, 0x65, 0x2E, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x2E,
+    0x6A, 0x64, 0x61, 0x6E, 0x69, 0x73, 0x2E, 0x6B, 0x65, 0x79, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x74,
+    0x6F, 0x6F, 0x6C, 0x02, 0x01, 0x01, 0x31, 0x22, 0x04, 0x20, 0x30, 0xE0, 0x78, 0x45, 0xAB, 0xD7,
+    0xC1, 0x74, 0x49, 0x01, 0x0F, 0xA7, 0x7F, 0x89, 0xDE, 0x11, 0xA3, 0x8B, 0x3E, 0x31, 0x6B, 0xF1,
+    0x18, 0xB4, 0x58, 0x1B, 0xD7, 0xB3, 0x58, 0xA9, 0xC2, 0x81, 0x30, 0x81, 0xA5, 0xA1, 0x08, 0x31,
+    0x06, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03, 0xA2, 0x03, 0x02, 0x01, 0x03, 0xA3, 0x04, 0x02, 0x02,
+    0x01, 0x00, 0xA5, 0x05, 0x31, 0x03, 0x02, 0x01, 0x04, 0xAA, 0x03, 0x02, 0x01, 0x01, 0xBF, 0x83,
+    0x78, 0x03, 0x02, 0x01, 0x02, 0xBF, 0x85, 0x3E, 0x03, 0x02, 0x01, 0x00, 0xBF, 0x85, 0x40, 0x4C,
+    0x30, 0x4A, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0A, 0x01, 0x02, 0x04, 0x20, 0xE7, 0xAD, 0x3C, 0x13,
+    0xC2, 0x73, 0x41, 0x60, 0xD7, 0x1A, 0x7C, 0x00, 0x5E, 0x14, 0xD8, 0xAE, 0x06, 0x5D, 0x22, 0xD0,
+    0xB5, 0xF5, 0x6A, 0xBA, 0x1F, 0x82, 0xA7, 0x8C, 0x17, 0x2C, 0xFD, 0x0F, 0xBF, 0x85, 0x41, 0x05,
+    0x02, 0x03, 0x01, 0xAD, 0xB0, 0xBF, 0x85, 0x42, 0x05, 0x02, 0x03, 0x03, 0x15, 0x75, 0xBF, 0x85,
+    0x4E, 0x06, 0x02, 0x04, 0x01, 0x34, 0x61, 0xB9, 0xBF, 0x85, 0x4F, 0x06, 0x02, 0x04, 0x01, 0x34,
+    0x61, 0xB9, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x47,
+    0x00, 0x30, 0x44, 0x02, 0x20, 0x4B, 0xDC, 0x8E, 0x91, 0xE6, 0xAA, 0x4A, 0x81, 0x6D, 0xA2, 0xD7,
+    0x13, 0x9E, 0x70, 0x12, 0x79, 0xB7, 0x85, 0x05, 0xAD, 0x6E, 0x5E, 0x0B, 0x43, 0x3B, 0xAF, 0x9A,
+    0xA9, 0x29, 0x40, 0xD7, 0x92, 0x02, 0x20, 0x2F, 0x39, 0x58, 0xE9, 0x89, 0x1A, 0x14, 0x41, 0x8D,
+    0xE0, 0xDC, 0x3D, 0x88, 0xF4, 0x2C, 0x7C, 0xDA, 0xA1, 0x84, 0xFA, 0x7F, 0xF9, 0x07, 0x97, 0xFB,
+    0xB5, 0xB7, 0x28, 0x28, 0x00, 0x7C, 0xA7,
+];
+pub static LOADED_CACERT_AUTHBOUND: &[u8] = &[
+    0x30, 0x82, 0x02, 0x26, 0x30, 0x82, 0x01, 0xAB, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0A, 0x05,
+    0x84, 0x20, 0x26, 0x90, 0x76, 0x23, 0x58, 0x71, 0x77, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48,
+    0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05,
+    0x13, 0x10, 0x34, 0x64, 0x37, 0x34, 0x61, 0x30, 0x65, 0x30, 0x31, 0x61, 0x61, 0x66, 0x33, 0x64,
+    0x64, 0x66, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55, 0x04, 0x0C, 0x0C, 0x03, 0x54, 0x45, 0x45,
+    0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x33, 0x32, 0x31, 0x32, 0x31, 0x32, 0x35, 0x31, 0x33,
+    0x5A, 0x17, 0x0D, 0x32, 0x38, 0x30, 0x33, 0x31, 0x38, 0x32, 0x31, 0x32, 0x35, 0x31, 0x33, 0x5A,
+    0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x34, 0x61,
+    0x38, 0x31, 0x65, 0x61, 0x65, 0x63, 0x35, 0x31, 0x64, 0x62, 0x30, 0x62, 0x31, 0x31, 0x0C, 0x30,
+    0x0A, 0x06, 0x03, 0x55, 0x04, 0x0C, 0x0C, 0x03, 0x54, 0x45, 0x45, 0x30, 0x59, 0x30, 0x13, 0x06,
+    0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03,
+    0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xFA, 0x35, 0x8F, 0xB0, 0x31, 0xD6, 0x30, 0x88, 0xDE, 0xB0,
+    0x29, 0xCD, 0x6C, 0x7D, 0x4E, 0xA9, 0xCE, 0x6E, 0x9D, 0x7A, 0xAC, 0x97, 0x92, 0xC2, 0x45, 0xB5,
+    0xE2, 0xD0, 0xC1, 0x52, 0xA8, 0x50, 0x25, 0xD7, 0x89, 0x58, 0x7B, 0x04, 0xB6, 0x66, 0x93, 0x2A,
+    0x26, 0x5D, 0x3A, 0xB1, 0x5B, 0x77, 0x30, 0xBF, 0x95, 0xAA, 0x8B, 0x43, 0xC3, 0xBF, 0x43, 0xB7,
+    0xEE, 0xAC, 0x73, 0xDC, 0x03, 0x6A, 0xA3, 0x81, 0xBA, 0x30, 0x81, 0xB7, 0x30, 0x1D, 0x06, 0x03,
+    0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x19, 0x9F, 0x87, 0x8B, 0x56, 0xF4, 0x99, 0x3A, 0x69,
+    0x96, 0x9B, 0x8D, 0x9E, 0x64, 0xAA, 0x56, 0xB4, 0x7F, 0x8B, 0x4D, 0x30, 0x1F, 0x06, 0x03, 0x55,
+    0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xA9, 0xB5, 0xF4, 0x29, 0xC9, 0x1A, 0x58, 0xBD,
+    0x2F, 0x98, 0x2D, 0x67, 0x73, 0x31, 0x06, 0x87, 0xE0, 0xDF, 0xCD, 0x62, 0x30, 0x0F, 0x06, 0x03,
+    0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06,
+    0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x54, 0x06,
+    0x03, 0x55, 0x1D, 0x1F, 0x04, 0x4D, 0x30, 0x4B, 0x30, 0x49, 0xA0, 0x47, 0xA0, 0x45, 0x86, 0x43,
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x61, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64, 0x2E,
+    0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x61,
+    0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x30,
+    0x35, 0x38, 0x34, 0x32, 0x30, 0x32, 0x36, 0x39, 0x30, 0x37, 0x36, 0x32, 0x33, 0x35, 0x38, 0x37,
+    0x31, 0x37, 0x37, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03,
+    0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xE3, 0x35, 0xC6, 0xA8, 0xB2, 0x75, 0x9C, 0x56, 0x7B,
+    0x6E, 0x61, 0x80, 0x65, 0x2C, 0x06, 0x88, 0xDD, 0xB9, 0x68, 0x4D, 0x3C, 0x68, 0x49, 0x66, 0x01,
+    0x4E, 0x30, 0x1D, 0xF3, 0xEC, 0xA5, 0x51, 0x5C, 0xBF, 0xE7, 0x83, 0x33, 0xBD, 0x14, 0xEE, 0x23,
+    0xF0, 0xCF, 0xB1, 0x37, 0x1C, 0x27, 0x78, 0x02, 0x31, 0x00, 0x94, 0xCB, 0x08, 0x3D, 0x2D, 0x3E,
+    0x69, 0x54, 0x5F, 0x63, 0xE3, 0xE4, 0x74, 0x72, 0xE2, 0xFF, 0x8B, 0x26, 0xD2, 0x86, 0xC0, 0x97,
+    0x32, 0x40, 0xDD, 0x7C, 0x1F, 0x50, 0x60, 0x57, 0xCF, 0x2E, 0x23, 0xF3, 0x33, 0xE4, 0xFB, 0x6F,
+    0x5B, 0x7C, 0xC6, 0x31, 0x85, 0xAE, 0xE0, 0x4E, 0x44, 0xA9, 0x30, 0x82, 0x03, 0xD1, 0x30, 0x82,
+    0x01, 0xB9, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0A, 0x03, 0x88, 0x26, 0x67, 0x60, 0x65, 0x89,
+    0x96, 0x85, 0x7F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B,
+    0x05, 0x00, 0x30, 0x1B, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x66,
+    0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38, 0x35, 0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35, 0x30,
+    0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x33, 0x32, 0x31, 0x32, 0x31, 0x31, 0x34, 0x31, 0x34, 0x5A,
+    0x17, 0x0D, 0x32, 0x38, 0x30, 0x33, 0x31, 0x38, 0x32, 0x31, 0x31, 0x34, 0x31, 0x34, 0x5A, 0x30,
+    0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x64, 0x37, 0x34,
+    0x61, 0x30, 0x65, 0x30, 0x31, 0x61, 0x61, 0x66, 0x33, 0x64, 0x64, 0x66, 0x31, 0x0C, 0x30, 0x0A,
+    0x06, 0x03, 0x55, 0x04, 0x0C, 0x0C, 0x03, 0x54, 0x45, 0x45, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07,
+    0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62,
+    0x00, 0x04, 0xD5, 0xF5, 0x0E, 0xE2, 0x8D, 0xF3, 0x33, 0x4A, 0x6A, 0x77, 0x90, 0x9C, 0xC2, 0x25,
+    0xC8, 0x8A, 0x32, 0xAE, 0x3B, 0xB4, 0x9C, 0x4A, 0x95, 0x22, 0x0C, 0xBA, 0x0A, 0x76, 0xCA, 0xCB,
+    0x24, 0x0C, 0x84, 0x3A, 0x83, 0x76, 0x04, 0x23, 0x31, 0x3A, 0xA0, 0x82, 0x80, 0x26, 0x65, 0xFD,
+    0x2F, 0x44, 0xF4, 0x96, 0xD8, 0xB7, 0xDC, 0xAC, 0x55, 0x34, 0x74, 0x41, 0x0D, 0x0D, 0x7F, 0xBD,
+    0xE3, 0xF4, 0x28, 0xDF, 0x74, 0x4A, 0x17, 0x4D, 0xE7, 0xB2, 0x9B, 0x2B, 0x24, 0xC0, 0x9E, 0x56,
+    0x00, 0x52, 0xBB, 0x75, 0xB0, 0xD5, 0x6A, 0x41, 0x16, 0x08, 0xCE, 0x32, 0xDB, 0x8F, 0x8B, 0x20,
+    0x73, 0x72, 0xA3, 0x81, 0xB6, 0x30, 0x81, 0xB3, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04,
+    0x16, 0x04, 0x14, 0xA9, 0xB5, 0xF4, 0x29, 0xC9, 0x1A, 0x58, 0xBD, 0x2F, 0x98, 0x2D, 0x67, 0x73,
+    0x31, 0x06, 0x87, 0xE0, 0xDF, 0xCD, 0x62, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18,
+    0x30, 0x16, 0x80, 0x14, 0x36, 0x61, 0xE1, 0x00, 0x7C, 0x88, 0x05, 0x09, 0x51, 0x8B, 0x44, 0x6C,
+    0x47, 0xFF, 0x1A, 0x4C, 0xC9, 0xEA, 0x4F, 0x12, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01,
+    0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F,
+    0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x50, 0x06, 0x03, 0x55, 0x1D, 0x1F,
+    0x04, 0x49, 0x30, 0x47, 0x30, 0x45, 0xA0, 0x43, 0xA0, 0x41, 0x86, 0x3F, 0x68, 0x74, 0x74, 0x70,
+    0x73, 0x3A, 0x2F, 0x2F, 0x61, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64, 0x2E, 0x67, 0x6F, 0x6F, 0x67,
+    0x6C, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x61, 0x74, 0x74, 0x65, 0x73,
+    0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x45, 0x38, 0x46, 0x41, 0x31,
+    0x39, 0x36, 0x33, 0x31, 0x34, 0x44, 0x32, 0x46, 0x41, 0x31, 0x38, 0x30, 0x0D, 0x06, 0x09, 0x2A,
+    0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x32,
+    0xCE, 0x04, 0xCC, 0x4D, 0x82, 0xAD, 0x1D, 0xDE, 0xA5, 0xCF, 0xE2, 0x1A, 0xA3, 0x79, 0xF7, 0xED,
+    0x88, 0x1E, 0x0E, 0x67, 0x8E, 0xFC, 0xBE, 0x7B, 0x04, 0xB7, 0x26, 0x59, 0xCA, 0x95, 0x47, 0x8A,
+    0x10, 0x3F, 0xE5, 0x14, 0x19, 0xEC, 0xD4, 0xDB, 0x33, 0xC3, 0xA1, 0x51, 0xF5, 0x06, 0x5E, 0x30,
+    0x66, 0x1F, 0xD2, 0x58, 0x2F, 0x14, 0x03, 0x7B, 0x35, 0x83, 0x86, 0x46, 0xDC, 0xEE, 0x04, 0x30,
+    0xA1, 0x0F, 0xC4, 0x16, 0xC9, 0x8E, 0x63, 0xD0, 0xDA, 0x5C, 0xB0, 0xF7, 0x3E, 0x21, 0xB6, 0xA5,
+    0x04, 0x07, 0x5A, 0x01, 0x8C, 0x31, 0x1F, 0x3E, 0x3A, 0xAF, 0x8D, 0x31, 0x3E, 0xB6, 0x12, 0x14,
+    0xF0, 0x0D, 0x2C, 0xCC, 0x6C, 0xB8, 0x7A, 0xBF, 0xD2, 0x6B, 0x5F, 0x27, 0xB0, 0xFF, 0xC0, 0xAA,
+    0xDE, 0xDE, 0xF6, 0x31, 0x6D, 0xF3, 0x95, 0xC2, 0xD4, 0x90, 0xDC, 0x82, 0x4F, 0x24, 0x0D, 0x85,
+    0xF2, 0xBB, 0xC4, 0x58, 0xC9, 0xFA, 0xDD, 0x96, 0x41, 0x2B, 0x1F, 0x4C, 0x10, 0x1C, 0x9A, 0x57,
+    0x55, 0x0F, 0x62, 0xFC, 0x8D, 0xA2, 0xCA, 0x84, 0x7B, 0x16, 0x60, 0xE8, 0x62, 0xCE, 0x92, 0x85,
+    0x13, 0xF0, 0x63, 0x83, 0xD8, 0x5B, 0xA8, 0x74, 0x78, 0xB5, 0x28, 0xDB, 0x6C, 0xC9, 0x6E, 0x85,
+    0x85, 0x52, 0x3F, 0xD8, 0x67, 0xAE, 0xF4, 0x09, 0xBE, 0xCF, 0x8C, 0x7F, 0x72, 0xB2, 0xC8, 0x93,
+    0xC6, 0xD2, 0xF3, 0x38, 0x74, 0x71, 0x22, 0xD6, 0x92, 0x76, 0xB1, 0xAE, 0x14, 0x5A, 0x09, 0xD8,
+    0xAF, 0x1D, 0xAF, 0x48, 0x22, 0x5C, 0x30, 0x85, 0x8E, 0xC2, 0xFE, 0x61, 0xAF, 0xC3, 0xD2, 0x4C,
+    0x92, 0x53, 0xA4, 0x75, 0x1F, 0x78, 0xEA, 0xFC, 0xFA, 0xC4, 0xCA, 0x4E, 0x67, 0x68, 0x1F, 0x7D,
+    0xB2, 0x5E, 0xEA, 0x8A, 0xB1, 0xCC, 0xB6, 0x92, 0x64, 0xF8, 0x82, 0xC0, 0x8B, 0xDC, 0x24, 0xE8,
+    0x57, 0x20, 0x33, 0x6D, 0x17, 0x33, 0x0D, 0xCB, 0x70, 0x02, 0x8B, 0xE5, 0xE3, 0x7D, 0x2C, 0x98,
+    0x32, 0x00, 0x20, 0xB4, 0xBD, 0xEE, 0x89, 0xAA, 0x66, 0x13, 0x34, 0x9D, 0x9C, 0x8F, 0xDE, 0x16,
+    0x09, 0x91, 0x49, 0x80, 0x50, 0x57, 0x39, 0xAE, 0x35, 0x01, 0xE2, 0x25, 0x8E, 0x17, 0x08, 0xE0,
+    0xF0, 0x77, 0x98, 0x9D, 0x0A, 0x4F, 0xD2, 0x76, 0xDA, 0xC4, 0x51, 0x45, 0x32, 0x8B, 0xE1, 0xAB,
+    0xEE, 0x10, 0x16, 0xF6, 0x95, 0x7D, 0x32, 0x76, 0xB2, 0xB5, 0x19, 0x67, 0x73, 0xFE, 0xC0, 0xC6,
+    0xA9, 0xD2, 0xA9, 0x23, 0xF0, 0x2B, 0xFC, 0xB1, 0xB6, 0xEC, 0x3E, 0x11, 0x60, 0xA4, 0x22, 0xC7,
+    0xFF, 0x25, 0xC3, 0xED, 0x6C, 0x6B, 0x79, 0x02, 0x3D, 0x5D, 0x62, 0x36, 0xD9, 0x32, 0xE4, 0x6E,
+    0x47, 0x67, 0x85, 0x8B, 0x23, 0x0A, 0xD5, 0x1E, 0xD0, 0xF4, 0x17, 0x1D, 0xCC, 0x3F, 0x5F, 0xDA,
+    0x12, 0xE2, 0x35, 0x25, 0x52, 0xC2, 0xD6, 0x94, 0x3E, 0x83, 0x60, 0x55, 0xF8, 0x8D, 0x54, 0xF5,
+    0x47, 0x6F, 0x38, 0x03, 0x3B, 0xD7, 0x9A, 0x94, 0x8A, 0x3B, 0x9F, 0x92, 0x69, 0x0F, 0xCD, 0xB8,
+    0xF4, 0x62, 0x78, 0x22, 0x47, 0xE0, 0xAE, 0xED, 0xFD, 0xF6, 0xE4, 0xC5, 0x8C, 0x0E, 0xB5, 0x18,
+    0xB1, 0x46, 0x3A, 0x6F, 0xBD, 0xDE, 0x50, 0x3F, 0x1C, 0x35, 0x28, 0xF9, 0xED, 0x1E, 0xE8, 0x15,
+    0x31, 0xA9, 0xF7, 0xB1, 0x9D, 0xE1, 0x34, 0x81, 0x20, 0x1F, 0x22, 0xD4, 0xB7, 0xC6, 0x59, 0x8B,
+    0x90, 0x98, 0xDF, 0xA6, 0xB9, 0xA8, 0x8E, 0x6C, 0x15, 0x55, 0x5C, 0x41, 0x96, 0x82, 0x0D, 0xA9,
+    0x5F, 0xA9, 0xF3, 0x77, 0x1D, 0xEE, 0x6B, 0x4C, 0x94, 0xC6, 0xC6, 0x9B, 0x78, 0x5B, 0x03, 0xBD,
+    0xA9, 0x87, 0xDD, 0x24, 0x04, 0x70, 0xCE, 0x6C, 0x52, 0xE6, 0x21, 0x63, 0x6D, 0x28, 0x6C, 0x30,
+    0x82, 0x05, 0x60, 0x30, 0x82, 0x03, 0x48, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xE8,
+    0xFA, 0x19, 0x63, 0x14, 0xD2, 0xFA, 0x18, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
+    0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x1B, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04,
+    0x05, 0x13, 0x10, 0x66, 0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38, 0x35, 0x33, 0x62, 0x36, 0x62,
+    0x30, 0x34, 0x35, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36, 0x30, 0x35, 0x32, 0x36, 0x31, 0x36, 0x32,
+    0x38, 0x35, 0x32, 0x5A, 0x17, 0x0D, 0x32, 0x36, 0x30, 0x35, 0x32, 0x34, 0x31, 0x36, 0x32, 0x38,
+    0x35, 0x32, 0x5A, 0x30, 0x1B, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10,
+    0x66, 0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38, 0x35, 0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35,
+    0x30, 0x82, 0x02, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01,
+    0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0F, 0x00, 0x30, 0x82, 0x02, 0x0A, 0x02, 0x82, 0x02, 0x01,
+    0x00, 0xAF, 0xB6, 0xC7, 0x82, 0x2B, 0xB1, 0xA7, 0x01, 0xEC, 0x2B, 0xB4, 0x2E, 0x8B, 0xCC, 0x54,
+    0x16, 0x63, 0xAB, 0xEF, 0x98, 0x2F, 0x32, 0xC7, 0x7F, 0x75, 0x31, 0x03, 0x0C, 0x97, 0x52, 0x4B,
+    0x1B, 0x5F, 0xE8, 0x09, 0xFB, 0xC7, 0x2A, 0xA9, 0x45, 0x1F, 0x74, 0x3C, 0xBD, 0x9A, 0x6F, 0x13,
+    0x35, 0x74, 0x4A, 0xA5, 0x5E, 0x77, 0xF6, 0xB6, 0xAC, 0x35, 0x35, 0xEE, 0x17, 0xC2, 0x5E, 0x63,
+    0x95, 0x17, 0xDD, 0x9C, 0x92, 0xE6, 0x37, 0x4A, 0x53, 0xCB, 0xFE, 0x25, 0x8F, 0x8F, 0xFB, 0xB6,
+    0xFD, 0x12, 0x93, 0x78, 0xA2, 0x2A, 0x4C, 0xA9, 0x9C, 0x45, 0x2D, 0x47, 0xA5, 0x9F, 0x32, 0x01,
+    0xF4, 0x41, 0x97, 0xCA, 0x1C, 0xCD, 0x7E, 0x76, 0x2F, 0xB2, 0xF5, 0x31, 0x51, 0xB6, 0xFE, 0xB2,
+    0xFF, 0xFD, 0x2B, 0x6F, 0xE4, 0xFE, 0x5B, 0xC6, 0xBD, 0x9E, 0xC3, 0x4B, 0xFE, 0x08, 0x23, 0x9D,
+    0xAA, 0xFC, 0xEB, 0x8E, 0xB5, 0xA8, 0xED, 0x2B, 0x3A, 0xCD, 0x9C, 0x5E, 0x3A, 0x77, 0x90, 0xE1,
+    0xB5, 0x14, 0x42, 0x79, 0x31, 0x59, 0x85, 0x98, 0x11, 0xAD, 0x9E, 0xB2, 0xA9, 0x6B, 0xBD, 0xD7,
+    0xA5, 0x7C, 0x93, 0xA9, 0x1C, 0x41, 0xFC, 0xCD, 0x27, 0xD6, 0x7F, 0xD6, 0xF6, 0x71, 0xAA, 0x0B,
+    0x81, 0x52, 0x61, 0xAD, 0x38, 0x4F, 0xA3, 0x79, 0x44, 0x86, 0x46, 0x04, 0xDD, 0xB3, 0xD8, 0xC4,
+    0xF9, 0x20, 0xA1, 0x9B, 0x16, 0x56, 0xC2, 0xF1, 0x4A, 0xD6, 0xD0, 0x3C, 0x56, 0xEC, 0x06, 0x08,
+    0x99, 0x04, 0x1C, 0x1E, 0xD1, 0xA5, 0xFE, 0x6D, 0x34, 0x40, 0xB5, 0x56, 0xBA, 0xD1, 0xD0, 0xA1,
+    0x52, 0x58, 0x9C, 0x53, 0xE5, 0x5D, 0x37, 0x07, 0x62, 0xF0, 0x12, 0x2E, 0xEF, 0x91, 0x86, 0x1B,
+    0x1B, 0x0E, 0x6C, 0x4C, 0x80, 0x92, 0x74, 0x99, 0xC0, 0xE9, 0xBE, 0xC0, 0xB8, 0x3E, 0x3B, 0xC1,
+    0xF9, 0x3C, 0x72, 0xC0, 0x49, 0x60, 0x4B, 0xBD, 0x2F, 0x13, 0x45, 0xE6, 0x2C, 0x3F, 0x8E, 0x26,
+    0xDB, 0xEC, 0x06, 0xC9, 0x47, 0x66, 0xF3, 0xC1, 0x28, 0x23, 0x9D, 0x4F, 0x43, 0x12, 0xFA, 0xD8,
+    0x12, 0x38, 0x87, 0xE0, 0x6B, 0xEC, 0xF5, 0x67, 0x58, 0x3B, 0xF8, 0x35, 0x5A, 0x81, 0xFE, 0xEA,
+    0xBA, 0xF9, 0x9A, 0x83, 0xC8, 0xDF, 0x3E, 0x2A, 0x32, 0x2A, 0xFC, 0x67, 0x2B, 0xF1, 0x20, 0xB1,
+    0x35, 0x15, 0x8B, 0x68, 0x21, 0xCE, 0xAF, 0x30, 0x9B, 0x6E, 0xEE, 0x77, 0xF9, 0x88, 0x33, 0xB0,
+    0x18, 0xDA, 0xA1, 0x0E, 0x45, 0x1F, 0x06, 0xA3, 0x74, 0xD5, 0x07, 0x81, 0xF3, 0x59, 0x08, 0x29,
+    0x66, 0xBB, 0x77, 0x8B, 0x93, 0x08, 0x94, 0x26, 0x98, 0xE7, 0x4E, 0x0B, 0xCD, 0x24, 0x62, 0x8A,
+    0x01, 0xC2, 0xCC, 0x03, 0xE5, 0x1F, 0x0B, 0x3E, 0x5B, 0x4A, 0xC1, 0xE4, 0xDF, 0x9E, 0xAF, 0x9F,
+    0xF6, 0xA4, 0x92, 0xA7, 0x7C, 0x14, 0x83, 0x88, 0x28, 0x85, 0x01, 0x5B, 0x42, 0x2C, 0xE6, 0x7B,
+    0x80, 0xB8, 0x8C, 0x9B, 0x48, 0xE1, 0x3B, 0x60, 0x7A, 0xB5, 0x45, 0xC7, 0x23, 0xFF, 0x8C, 0x44,
+    0xF8, 0xF2, 0xD3, 0x68, 0xB9, 0xF6, 0x52, 0x0D, 0x31, 0x14, 0x5E, 0xBF, 0x9E, 0x86, 0x2A, 0xD7,
+    0x1D, 0xF6, 0xA3, 0xBF, 0xD2, 0x45, 0x09, 0x59, 0xD6, 0x53, 0x74, 0x0D, 0x97, 0xA1, 0x2F, 0x36,
+    0x8B, 0x13, 0xEF, 0x66, 0xD5, 0xD0, 0xA5, 0x4A, 0x6E, 0x2F, 0x5D, 0x9A, 0x6F, 0xEF, 0x44, 0x68,
+    0x32, 0xBC, 0x67, 0x84, 0x47, 0x25, 0x86, 0x1F, 0x09, 0x3D, 0xD0, 0xE6, 0xF3, 0x40, 0x5D, 0xA8,
+    0x96, 0x43, 0xEF, 0x0F, 0x4D, 0x69, 0xB6, 0x42, 0x00, 0x51, 0xFD, 0xB9, 0x30, 0x49, 0x67, 0x3E,
+    0x36, 0x95, 0x05, 0x80, 0xD3, 0xCD, 0xF4, 0xFB, 0xD0, 0x8B, 0xC5, 0x84, 0x83, 0x95, 0x26, 0x00,
+    0x63, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x81, 0xA6, 0x30, 0x81, 0xA3, 0x30, 0x1D, 0x06, 0x03,
+    0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x36, 0x61, 0xE1, 0x00, 0x7C, 0x88, 0x05, 0x09, 0x51,
+    0x8B, 0x44, 0x6C, 0x47, 0xFF, 0x1A, 0x4C, 0xC9, 0xEA, 0x4F, 0x12, 0x30, 0x1F, 0x06, 0x03, 0x55,
+    0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x36, 0x61, 0xE1, 0x00, 0x7C, 0x88, 0x05, 0x09,
+    0x51, 0x8B, 0x44, 0x6C, 0x47, 0xFF, 0x1A, 0x4C, 0xC9, 0xEA, 0x4F, 0x12, 0x30, 0x0F, 0x06, 0x03,
+    0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E, 0x06,
+    0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x40, 0x06,
+    0x03, 0x55, 0x1D, 0x1F, 0x04, 0x39, 0x30, 0x37, 0x30, 0x35, 0xA0, 0x33, 0xA0, 0x31, 0x86, 0x2F,
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x61, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64, 0x2E,
+    0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x61,
+    0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x30,
+    0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82,
+    0x02, 0x01, 0x00, 0x20, 0xC8, 0xC3, 0x8D, 0x4B, 0xDC, 0xA9, 0x57, 0x1B, 0x46, 0x8C, 0x89, 0x2F,
+    0xFF, 0x72, 0xAA, 0xC6, 0xF8, 0x44, 0xA1, 0x1D, 0x41, 0xA8, 0xF0, 0x73, 0x6C, 0xC3, 0x7D, 0x16,
+    0xD6, 0x42, 0x6D, 0x8E, 0x7E, 0x94, 0x07, 0x04, 0x4C, 0xEA, 0x39, 0xE6, 0x8B, 0x07, 0xC1, 0x3D,
+    0xBF, 0x15, 0x03, 0xDD, 0x5C, 0x85, 0xBD, 0xAF, 0xB2, 0xC0, 0x2D, 0x5F, 0x6C, 0xDB, 0x4E, 0xFA,
+    0x81, 0x27, 0xDF, 0x8B, 0x04, 0xF1, 0x82, 0x77, 0x0F, 0xC4, 0xE7, 0x74, 0x5B, 0x7F, 0xCE, 0xAA,
+    0x87, 0x12, 0x9A, 0x88, 0x01, 0xCE, 0x8E, 0x9B, 0xC0, 0xCB, 0x96, 0x37, 0x9B, 0x4D, 0x26, 0xA8,
+    0x2D, 0x30, 0xFD, 0x9C, 0x2F, 0x8E, 0xED, 0x6D, 0xC1, 0xBE, 0x2F, 0x84, 0xB6, 0x89, 0xE4, 0xD9,
+    0x14, 0x25, 0x8B, 0x14, 0x4B, 0xBA, 0xE6, 0x24, 0xA1, 0xC7, 0x06, 0x71, 0x13, 0x2E, 0x2F, 0x06,
+    0x16, 0xA8, 0x84, 0xB2, 0xA4, 0xD6, 0xA4, 0x6F, 0xFA, 0x89, 0xB6, 0x02, 0xBF, 0xBA, 0xD8, 0x0C,
+    0x12, 0x43, 0x71, 0x1F, 0x56, 0xEB, 0x60, 0x56, 0xF6, 0x37, 0xC8, 0xA0, 0x14, 0x1C, 0xC5, 0x40,
+    0x94, 0x26, 0x8B, 0x8C, 0x3C, 0x7D, 0xB9, 0x94, 0xB3, 0x5C, 0x0D, 0xCD, 0x6C, 0xB2, 0xAB, 0xC2,
+    0xDA, 0xFE, 0xE2, 0x52, 0x02, 0x3D, 0x2D, 0xEA, 0x0C, 0xD6, 0xC3, 0x68, 0xBE, 0xA3, 0xE6, 0x41,
+    0x48, 0x86, 0xF6, 0xB1, 0xE5, 0x8B, 0x5B, 0xD7, 0xC7, 0x30, 0xB2, 0x68, 0xC4, 0xE3, 0xC1, 0xFB,
+    0x64, 0x24, 0xB9, 0x1F, 0xEB, 0xBD, 0xB8, 0x0C, 0x58, 0x6E, 0x2A, 0xE8, 0x36, 0x8C, 0x84, 0xD5,
+    0xD1, 0x09, 0x17, 0xBD, 0xA2, 0x56, 0x17, 0x89, 0xD4, 0x68, 0x73, 0x93, 0x34, 0x0E, 0x2E, 0x25,
+    0x4F, 0x56, 0x0E, 0xF6, 0x4B, 0x23, 0x58, 0xFC, 0xDC, 0x0F, 0xBF, 0xC6, 0x70, 0x09, 0x52, 0xE7,
+    0x08, 0xBF, 0xFC, 0xC6, 0x27, 0x50, 0x0C, 0x1F, 0x66, 0xE8, 0x1E, 0xA1, 0x7C, 0x09, 0x8D, 0x7A,
+    0x2E, 0x9B, 0x18, 0x80, 0x1B, 0x7A, 0xB4, 0xAC, 0x71, 0x58, 0x7D, 0x34, 0x5D, 0xCC, 0x83, 0x09,
+    0xD5, 0xB6, 0x2A, 0x50, 0x42, 0x7A, 0xA6, 0xD0, 0x3D, 0xCB, 0x05, 0x99, 0x6C, 0x96, 0xBA, 0x0C,
+    0x5D, 0x71, 0xE9, 0x21, 0x62, 0xC0, 0x16, 0xCA, 0x84, 0x9F, 0xF3, 0x5F, 0x0D, 0x52, 0xC6, 0x5D,
+    0x05, 0x60, 0x5A, 0x47, 0xF3, 0xAE, 0x91, 0x7A, 0xCD, 0x2D, 0xF9, 0x10, 0xEF, 0xD2, 0x32, 0x66,
+    0x88, 0x59, 0x6E, 0xF6, 0x9B, 0x3B, 0xF5, 0xFE, 0x31, 0x54, 0xF7, 0xAE, 0xB8, 0x80, 0xA0, 0xA7,
+    0x3C, 0xA0, 0x4D, 0x94, 0xC2, 0xCE, 0x83, 0x17, 0xEE, 0xB4, 0x3D, 0x5E, 0xFF, 0x58, 0x83, 0xE3,
+    0x36, 0xF5, 0xF2, 0x49, 0xDA, 0xAC, 0xA4, 0x89, 0x92, 0x37, 0xBF, 0x26, 0x7E, 0x5C, 0x43, 0xAB,
+    0x02, 0xEA, 0x44, 0x16, 0x24, 0x03, 0x72, 0x3B, 0xE6, 0xAA, 0x69, 0x2C, 0x61, 0xBD, 0xAE, 0x9E,
+    0xD4, 0x09, 0xD4, 0x63, 0xC4, 0xC9, 0x7C, 0x64, 0x30, 0x65, 0x77, 0xEE, 0xF2, 0xBC, 0x75, 0x60,
+    0xB7, 0x57, 0x15, 0xCC, 0x9C, 0x7D, 0xC6, 0x7C, 0x86, 0x08, 0x2D, 0xB7, 0x51, 0xA8, 0x9C, 0x30,
+    0x34, 0x97, 0x62, 0xB0, 0x78, 0x23, 0x85, 0x87, 0x5C, 0xF1, 0xA3, 0xC6, 0x16, 0x6E, 0x0A, 0xE3,
+    0xC1, 0x2D, 0x37, 0x4E, 0x2D, 0x4F, 0x18, 0x46, 0xF3, 0x18, 0x74, 0x4B, 0xD8, 0x79, 0xB5, 0x87,
+    0x32, 0x9B, 0xF0, 0x18, 0x21, 0x7A, 0x6C, 0x0C, 0x77, 0x24, 0x1A, 0x48, 0x78, 0xE4, 0x35, 0xC0,
+    0x30, 0x79, 0xCB, 0x45, 0x12, 0x89, 0xC5, 0x77, 0x62, 0x06, 0x06, 0x9A, 0x2F, 0x8D, 0x65, 0xF8,
+    0x40, 0xE1, 0x44, 0x52, 0x87, 0xBE, 0xD8, 0x77, 0xAB, 0xAE, 0x24, 0xE2, 0x44, 0x35, 0x16, 0x8D,
+    0x55, 0x3C, 0xE4,
+];
+
+pub static LOADED_USRPKEY_NON_AUTHBOUND: &[u8] = &[
+    0x44, 0x4b, 0x4d, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x8a, 0xc1, 0x08, 0x13, 0x7c, 0x47, 0xba, 0x09, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0xb0, 0xad, 0x01, 0x00, 0x01, 0x75, 0x15, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x60, 0x60, 0x8c, 0x31, 0x76, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x61, 0x34, 0x01, 0x01, 0xb9, 0x61, 0x34, 0x01, 0x01, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00,
+    0x00, 0xc9, 0xcd, 0xcb, 0xca, 0xfa, 0x37, 0xe2, 0xc7, 0x56, 0x8c, 0x23, 0xf6, 0x7f, 0xd1, 0x8c,
+    0x01, 0xc1, 0x4f, 0x65, 0xd7, 0x1b, 0x10, 0xc5, 0x0a, 0x77, 0x13, 0xf2, 0x82, 0xde, 0x63, 0x68,
+    0x5f, 0xec, 0x2f, 0x95, 0x34, 0x65, 0x5d, 0x2f, 0x99, 0xfc, 0xed, 0x0d, 0x1b, 0xe9, 0xf4, 0x83,
+    0x38, 0x71, 0x83, 0x82, 0x64, 0x51, 0xab, 0x53, 0xb1, 0xfa, 0x73, 0x00, 0x20, 0x24, 0xdd, 0x1c,
+    0x13, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xe5, 0xa5, 0x27,
+    0xb5, 0x66, 0x76, 0x6c, 0x74, 0x36, 0xd7, 0x2d, 0xad, 0x32, 0x49, 0xd4, 0xa5, 0xed, 0xb2, 0x9c,
+    0x4b, 0xbd, 0xb8, 0xe1, 0x79, 0x9f, 0x8a, 0x72, 0xc3, 0xdf, 0x8b, 0x99, 0x49, 0xa8, 0x5e, 0x10,
+    0x00, 0xd6, 0xa6, 0x58, 0x49, 0x5a, 0xa2, 0x71, 0xb3, 0x54, 0xd3, 0x69, 0xb7, 0xfe, 0x51, 0xc5,
+    0xe4, 0x94, 0xff, 0x10, 0xd7, 0x46, 0x01, 0x78, 0x43, 0x8c, 0x9c, 0xbe, 0x2f, 0x9a, 0x4b, 0x5b,
+    0x72, 0x07, 0x4d, 0x8f, 0x25, 0x50, 0x1e, 0xb2, 0x46, 0xf0, 0xee, 0x50, 0x73, 0x6a, 0x7b, 0xa3,
+    0xe9, 0xb1, 0x08, 0x81, 0x00, 0xdf, 0x0e, 0xc9, 0xc3, 0x2c, 0x13, 0x64, 0xa1,
+];
+
+pub static LOADED_CERT_NON_AUTHBOUND: &[u8] = &[
+    0x30, 0x82, 0x02, 0x93, 0x30, 0x82, 0x02, 0x39, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01,
+    0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x29, 0x31, 0x19,
+    0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x34, 0x61, 0x38, 0x31, 0x65, 0x61,
+    0x65, 0x63, 0x35, 0x31, 0x64, 0x62, 0x30, 0x62, 0x31, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55,
+    0x04, 0x0c, 0x0c, 0x03, 0x54, 0x45, 0x45, 0x30, 0x20, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
+    0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x30, 0x36, 0x30, 0x32,
+    0x30, 0x37, 0x30, 0x36, 0x32, 0x38, 0x31, 0x35, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30, 0x1b, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x0c, 0x14, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65,
+    0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01,
+    0x07, 0x03, 0x42, 0x00, 0x04, 0xa8, 0x5e, 0x10, 0x00, 0xd6, 0xa6, 0x58, 0x49, 0x5a, 0xa2, 0x71,
+    0xb3, 0x54, 0xd3, 0x69, 0xb7, 0xfe, 0x51, 0xc5, 0xe4, 0x94, 0xff, 0x10, 0xd7, 0x46, 0x01, 0x78,
+    0x43, 0x8c, 0x9c, 0xbe, 0x2f, 0x9a, 0x4b, 0x5b, 0x72, 0x07, 0x4d, 0x8f, 0x25, 0x50, 0x1e, 0xb2,
+    0x46, 0xf0, 0xee, 0x50, 0x73, 0x6a, 0x7b, 0xa3, 0xe9, 0xb1, 0x08, 0x81, 0x00, 0xdf, 0x0e, 0xc9,
+    0xc3, 0x2c, 0x13, 0x64, 0xa1, 0xa3, 0x82, 0x01, 0x58, 0x30, 0x82, 0x01, 0x54, 0x30, 0x0e, 0x06,
+    0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x82, 0x01,
+    0x40, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x11, 0x04, 0x82, 0x01,
+    0x30, 0x30, 0x82, 0x01, 0x2c, 0x02, 0x01, 0x03, 0x0a, 0x01, 0x01, 0x02, 0x01, 0x04, 0x0a, 0x01,
+    0x01, 0x04, 0x08, 0x61, 0x73, 0x64, 0x66, 0x6a, 0x6b, 0x6c, 0x3b, 0x04, 0x00, 0x30, 0x6b, 0xbf,
+    0x85, 0x3d, 0x08, 0x02, 0x06, 0x01, 0x76, 0x31, 0x8c, 0x60, 0x60, 0xbf, 0x85, 0x45, 0x5b, 0x04,
+    0x59, 0x30, 0x57, 0x31, 0x31, 0x30, 0x2f, 0x04, 0x2a, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f,
+    0x67, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e,
+    0x6a, 0x64, 0x61, 0x6e, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x74,
+    0x6f, 0x6f, 0x6c, 0x02, 0x01, 0x01, 0x31, 0x22, 0x04, 0x20, 0x30, 0xe0, 0x78, 0x45, 0xab, 0xd7,
+    0xc1, 0x74, 0x49, 0x01, 0x0f, 0xa7, 0x7f, 0x89, 0xde, 0x11, 0xa3, 0x8b, 0x3e, 0x31, 0x6b, 0xf1,
+    0x18, 0xb4, 0x58, 0x1b, 0xd7, 0xb3, 0x58, 0xa9, 0xc2, 0x81, 0x30, 0x81, 0xa4, 0xa1, 0x08, 0x31,
+    0x06, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03, 0xa2, 0x03, 0x02, 0x01, 0x03, 0xa3, 0x04, 0x02, 0x02,
+    0x01, 0x00, 0xa5, 0x05, 0x31, 0x03, 0x02, 0x01, 0x04, 0xaa, 0x03, 0x02, 0x01, 0x01, 0xbf, 0x83,
+    0x77, 0x02, 0x05, 0x00, 0xbf, 0x85, 0x3e, 0x03, 0x02, 0x01, 0x00, 0xbf, 0x85, 0x40, 0x4c, 0x30,
+    0x4a, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0a, 0x01, 0x02, 0x04, 0x20, 0xe7, 0xad, 0x3c, 0x13, 0xc2,
+    0x73, 0x41, 0x60, 0xd7, 0x1a, 0x7c, 0x00, 0x5e, 0x14, 0xd8, 0xae, 0x06, 0x5d, 0x22, 0xd0, 0xb5,
+    0xf5, 0x6a, 0xba, 0x1f, 0x82, 0xa7, 0x8c, 0x17, 0x2c, 0xfd, 0x0f, 0xbf, 0x85, 0x41, 0x05, 0x02,
+    0x03, 0x01, 0xad, 0xb0, 0xbf, 0x85, 0x42, 0x05, 0x02, 0x03, 0x03, 0x15, 0x75, 0xbf, 0x85, 0x4e,
+    0x06, 0x02, 0x04, 0x01, 0x34, 0x61, 0xb9, 0xbf, 0x85, 0x4f, 0x06, 0x02, 0x04, 0x01, 0x34, 0x61,
+    0xb9, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00,
+    0x30, 0x45, 0x02, 0x20, 0x3f, 0x12, 0x76, 0x4c, 0x85, 0xfd, 0xc9, 0x68, 0x0d, 0x66, 0x0b, 0x60,
+    0x3d, 0xff, 0x7c, 0x8b, 0x11, 0x9c, 0x26, 0xef, 0xdb, 0x4a, 0xc3, 0x37, 0x40, 0x06, 0xa9, 0x16,
+    0xc7, 0x99, 0x85, 0x89, 0x02, 0x21, 0x00, 0xc7, 0x02, 0xf3, 0x21, 0x60, 0x17, 0x05, 0x7e, 0x36,
+    0x33, 0x21, 0x0c, 0x1d, 0x27, 0xc3, 0x8f, 0xd6, 0xd8, 0xd5, 0xd1, 0x64, 0x4c, 0x05, 0xdd, 0x13,
+    0x0e, 0xa4, 0xf3, 0x38, 0xbf, 0x18, 0xd5,
+];
+
+pub static LOADED_CACERT_NON_AUTHBOUND: &[u8] = &[
+    0x30, 0x82, 0x02, 0x26, 0x30, 0x82, 0x01, 0xab, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x05,
+    0x84, 0x20, 0x26, 0x90, 0x76, 0x23, 0x58, 0x71, 0x77, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48,
+    0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05,
+    0x13, 0x10, 0x34, 0x64, 0x37, 0x34, 0x61, 0x30, 0x65, 0x30, 0x31, 0x61, 0x61, 0x66, 0x33, 0x64,
+    0x64, 0x66, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54, 0x45, 0x45,
+    0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32, 0x31, 0x32, 0x31, 0x32, 0x35, 0x31, 0x33,
+    0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x33, 0x31, 0x38, 0x32, 0x31, 0x32, 0x35, 0x31, 0x33, 0x5a,
+    0x30, 0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x34, 0x61,
+    0x38, 0x31, 0x65, 0x61, 0x65, 0x63, 0x35, 0x31, 0x64, 0x62, 0x30, 0x62, 0x31, 0x31, 0x0c, 0x30,
+    0x0a, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54, 0x45, 0x45, 0x30, 0x59, 0x30, 0x13, 0x06,
+    0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
+    0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xfa, 0x35, 0x8f, 0xb0, 0x31, 0xd6, 0x30, 0x88, 0xde, 0xb0,
+    0x29, 0xcd, 0x6c, 0x7d, 0x4e, 0xa9, 0xce, 0x6e, 0x9d, 0x7a, 0xac, 0x97, 0x92, 0xc2, 0x45, 0xb5,
+    0xe2, 0xd0, 0xc1, 0x52, 0xa8, 0x50, 0x25, 0xd7, 0x89, 0x58, 0x7b, 0x04, 0xb6, 0x66, 0x93, 0x2a,
+    0x26, 0x5d, 0x3a, 0xb1, 0x5b, 0x77, 0x30, 0xbf, 0x95, 0xaa, 0x8b, 0x43, 0xc3, 0xbf, 0x43, 0xb7,
+    0xee, 0xac, 0x73, 0xdc, 0x03, 0x6a, 0xa3, 0x81, 0xba, 0x30, 0x81, 0xb7, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x19, 0x9f, 0x87, 0x8b, 0x56, 0xf4, 0x99, 0x3a, 0x69,
+    0x96, 0x9b, 0x8d, 0x9e, 0x64, 0xaa, 0x56, 0xb4, 0x7f, 0x8b, 0x4d, 0x30, 0x1f, 0x06, 0x03, 0x55,
+    0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xa9, 0xb5, 0xf4, 0x29, 0xc9, 0x1a, 0x58, 0xbd,
+    0x2f, 0x98, 0x2d, 0x67, 0x73, 0x31, 0x06, 0x87, 0xe0, 0xdf, 0xcd, 0x62, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
+    0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x54, 0x06,
+    0x03, 0x55, 0x1d, 0x1f, 0x04, 0x4d, 0x30, 0x4b, 0x30, 0x49, 0xa0, 0x47, 0xa0, 0x45, 0x86, 0x43,
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+    0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
+    0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x30,
+    0x35, 0x38, 0x34, 0x32, 0x30, 0x32, 0x36, 0x39, 0x30, 0x37, 0x36, 0x32, 0x33, 0x35, 0x38, 0x37,
+    0x31, 0x37, 0x37, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03,
+    0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xe3, 0x35, 0xc6, 0xa8, 0xb2, 0x75, 0x9c, 0x56, 0x7b,
+    0x6e, 0x61, 0x80, 0x65, 0x2c, 0x06, 0x88, 0xdd, 0xb9, 0x68, 0x4d, 0x3c, 0x68, 0x49, 0x66, 0x01,
+    0x4e, 0x30, 0x1d, 0xf3, 0xec, 0xa5, 0x51, 0x5c, 0xbf, 0xe7, 0x83, 0x33, 0xbd, 0x14, 0xee, 0x23,
+    0xf0, 0xcf, 0xb1, 0x37, 0x1c, 0x27, 0x78, 0x02, 0x31, 0x00, 0x94, 0xcb, 0x08, 0x3d, 0x2d, 0x3e,
+    0x69, 0x54, 0x5f, 0x63, 0xe3, 0xe4, 0x74, 0x72, 0xe2, 0xff, 0x8b, 0x26, 0xd2, 0x86, 0xc0, 0x97,
+    0x32, 0x40, 0xdd, 0x7c, 0x1f, 0x50, 0x60, 0x57, 0xcf, 0x2e, 0x23, 0xf3, 0x33, 0xe4, 0xfb, 0x6f,
+    0x5b, 0x7c, 0xc6, 0x31, 0x85, 0xae, 0xe0, 0x4e, 0x44, 0xa9, 0x30, 0x82, 0x03, 0xd1, 0x30, 0x82,
+    0x01, 0xb9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x03, 0x88, 0x26, 0x67, 0x60, 0x65, 0x89,
+    0x96, 0x85, 0x7f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+    0x05, 0x00, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x66,
+    0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38, 0x35, 0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35, 0x30,
+    0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33, 0x32, 0x31, 0x32, 0x31, 0x31, 0x34, 0x31, 0x34, 0x5a,
+    0x17, 0x0d, 0x32, 0x38, 0x30, 0x33, 0x31, 0x38, 0x32, 0x31, 0x31, 0x34, 0x31, 0x34, 0x5a, 0x30,
+    0x29, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10, 0x34, 0x64, 0x37, 0x34,
+    0x61, 0x30, 0x65, 0x30, 0x31, 0x61, 0x61, 0x66, 0x33, 0x64, 0x64, 0x66, 0x31, 0x0c, 0x30, 0x0a,
+    0x06, 0x03, 0x55, 0x04, 0x0c, 0x0c, 0x03, 0x54, 0x45, 0x45, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07,
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62,
+    0x00, 0x04, 0xd5, 0xf5, 0x0e, 0xe2, 0x8d, 0xf3, 0x33, 0x4a, 0x6a, 0x77, 0x90, 0x9c, 0xc2, 0x25,
+    0xc8, 0x8a, 0x32, 0xae, 0x3b, 0xb4, 0x9c, 0x4a, 0x95, 0x22, 0x0c, 0xba, 0x0a, 0x76, 0xca, 0xcb,
+    0x24, 0x0c, 0x84, 0x3a, 0x83, 0x76, 0x04, 0x23, 0x31, 0x3a, 0xa0, 0x82, 0x80, 0x26, 0x65, 0xfd,
+    0x2f, 0x44, 0xf4, 0x96, 0xd8, 0xb7, 0xdc, 0xac, 0x55, 0x34, 0x74, 0x41, 0x0d, 0x0d, 0x7f, 0xbd,
+    0xe3, 0xf4, 0x28, 0xdf, 0x74, 0x4a, 0x17, 0x4d, 0xe7, 0xb2, 0x9b, 0x2b, 0x24, 0xc0, 0x9e, 0x56,
+    0x00, 0x52, 0xbb, 0x75, 0xb0, 0xd5, 0x6a, 0x41, 0x16, 0x08, 0xce, 0x32, 0xdb, 0x8f, 0x8b, 0x20,
+    0x73, 0x72, 0xa3, 0x81, 0xb6, 0x30, 0x81, 0xb3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+    0x16, 0x04, 0x14, 0xa9, 0xb5, 0xf4, 0x29, 0xc9, 0x1a, 0x58, 0xbd, 0x2f, 0x98, 0x2d, 0x67, 0x73,
+    0x31, 0x06, 0x87, 0xe0, 0xdf, 0xcd, 0x62, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+    0x30, 0x16, 0x80, 0x14, 0x36, 0x61, 0xe1, 0x00, 0x7c, 0x88, 0x05, 0x09, 0x51, 0x8b, 0x44, 0x6c,
+    0x47, 0xff, 0x1a, 0x4c, 0xc9, 0xea, 0x4f, 0x12, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+    0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+    0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x50, 0x06, 0x03, 0x55, 0x1d, 0x1f,
+    0x04, 0x49, 0x30, 0x47, 0x30, 0x45, 0xa0, 0x43, 0xa0, 0x41, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70,
+    0x73, 0x3a, 0x2f, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+    0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73,
+    0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x45, 0x38, 0x46, 0x41, 0x31,
+    0x39, 0x36, 0x33, 0x31, 0x34, 0x44, 0x32, 0x46, 0x41, 0x31, 0x38, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x32,
+    0xce, 0x04, 0xcc, 0x4d, 0x82, 0xad, 0x1d, 0xde, 0xa5, 0xcf, 0xe2, 0x1a, 0xa3, 0x79, 0xf7, 0xed,
+    0x88, 0x1e, 0x0e, 0x67, 0x8e, 0xfc, 0xbe, 0x7b, 0x04, 0xb7, 0x26, 0x59, 0xca, 0x95, 0x47, 0x8a,
+    0x10, 0x3f, 0xe5, 0x14, 0x19, 0xec, 0xd4, 0xdb, 0x33, 0xc3, 0xa1, 0x51, 0xf5, 0x06, 0x5e, 0x30,
+    0x66, 0x1f, 0xd2, 0x58, 0x2f, 0x14, 0x03, 0x7b, 0x35, 0x83, 0x86, 0x46, 0xdc, 0xee, 0x04, 0x30,
+    0xa1, 0x0f, 0xc4, 0x16, 0xc9, 0x8e, 0x63, 0xd0, 0xda, 0x5c, 0xb0, 0xf7, 0x3e, 0x21, 0xb6, 0xa5,
+    0x04, 0x07, 0x5a, 0x01, 0x8c, 0x31, 0x1f, 0x3e, 0x3a, 0xaf, 0x8d, 0x31, 0x3e, 0xb6, 0x12, 0x14,
+    0xf0, 0x0d, 0x2c, 0xcc, 0x6c, 0xb8, 0x7a, 0xbf, 0xd2, 0x6b, 0x5f, 0x27, 0xb0, 0xff, 0xc0, 0xaa,
+    0xde, 0xde, 0xf6, 0x31, 0x6d, 0xf3, 0x95, 0xc2, 0xd4, 0x90, 0xdc, 0x82, 0x4f, 0x24, 0x0d, 0x85,
+    0xf2, 0xbb, 0xc4, 0x58, 0xc9, 0xfa, 0xdd, 0x96, 0x41, 0x2b, 0x1f, 0x4c, 0x10, 0x1c, 0x9a, 0x57,
+    0x55, 0x0f, 0x62, 0xfc, 0x8d, 0xa2, 0xca, 0x84, 0x7b, 0x16, 0x60, 0xe8, 0x62, 0xce, 0x92, 0x85,
+    0x13, 0xf0, 0x63, 0x83, 0xd8, 0x5b, 0xa8, 0x74, 0x78, 0xb5, 0x28, 0xdb, 0x6c, 0xc9, 0x6e, 0x85,
+    0x85, 0x52, 0x3f, 0xd8, 0x67, 0xae, 0xf4, 0x09, 0xbe, 0xcf, 0x8c, 0x7f, 0x72, 0xb2, 0xc8, 0x93,
+    0xc6, 0xd2, 0xf3, 0x38, 0x74, 0x71, 0x22, 0xd6, 0x92, 0x76, 0xb1, 0xae, 0x14, 0x5a, 0x09, 0xd8,
+    0xaf, 0x1d, 0xaf, 0x48, 0x22, 0x5c, 0x30, 0x85, 0x8e, 0xc2, 0xfe, 0x61, 0xaf, 0xc3, 0xd2, 0x4c,
+    0x92, 0x53, 0xa4, 0x75, 0x1f, 0x78, 0xea, 0xfc, 0xfa, 0xc4, 0xca, 0x4e, 0x67, 0x68, 0x1f, 0x7d,
+    0xb2, 0x5e, 0xea, 0x8a, 0xb1, 0xcc, 0xb6, 0x92, 0x64, 0xf8, 0x82, 0xc0, 0x8b, 0xdc, 0x24, 0xe8,
+    0x57, 0x20, 0x33, 0x6d, 0x17, 0x33, 0x0d, 0xcb, 0x70, 0x02, 0x8b, 0xe5, 0xe3, 0x7d, 0x2c, 0x98,
+    0x32, 0x00, 0x20, 0xb4, 0xbd, 0xee, 0x89, 0xaa, 0x66, 0x13, 0x34, 0x9d, 0x9c, 0x8f, 0xde, 0x16,
+    0x09, 0x91, 0x49, 0x80, 0x50, 0x57, 0x39, 0xae, 0x35, 0x01, 0xe2, 0x25, 0x8e, 0x17, 0x08, 0xe0,
+    0xf0, 0x77, 0x98, 0x9d, 0x0a, 0x4f, 0xd2, 0x76, 0xda, 0xc4, 0x51, 0x45, 0x32, 0x8b, 0xe1, 0xab,
+    0xee, 0x10, 0x16, 0xf6, 0x95, 0x7d, 0x32, 0x76, 0xb2, 0xb5, 0x19, 0x67, 0x73, 0xfe, 0xc0, 0xc6,
+    0xa9, 0xd2, 0xa9, 0x23, 0xf0, 0x2b, 0xfc, 0xb1, 0xb6, 0xec, 0x3e, 0x11, 0x60, 0xa4, 0x22, 0xc7,
+    0xff, 0x25, 0xc3, 0xed, 0x6c, 0x6b, 0x79, 0x02, 0x3d, 0x5d, 0x62, 0x36, 0xd9, 0x32, 0xe4, 0x6e,
+    0x47, 0x67, 0x85, 0x8b, 0x23, 0x0a, 0xd5, 0x1e, 0xd0, 0xf4, 0x17, 0x1d, 0xcc, 0x3f, 0x5f, 0xda,
+    0x12, 0xe2, 0x35, 0x25, 0x52, 0xc2, 0xd6, 0x94, 0x3e, 0x83, 0x60, 0x55, 0xf8, 0x8d, 0x54, 0xf5,
+    0x47, 0x6f, 0x38, 0x03, 0x3b, 0xd7, 0x9a, 0x94, 0x8a, 0x3b, 0x9f, 0x92, 0x69, 0x0f, 0xcd, 0xb8,
+    0xf4, 0x62, 0x78, 0x22, 0x47, 0xe0, 0xae, 0xed, 0xfd, 0xf6, 0xe4, 0xc5, 0x8c, 0x0e, 0xb5, 0x18,
+    0xb1, 0x46, 0x3a, 0x6f, 0xbd, 0xde, 0x50, 0x3f, 0x1c, 0x35, 0x28, 0xf9, 0xed, 0x1e, 0xe8, 0x15,
+    0x31, 0xa9, 0xf7, 0xb1, 0x9d, 0xe1, 0x34, 0x81, 0x20, 0x1f, 0x22, 0xd4, 0xb7, 0xc6, 0x59, 0x8b,
+    0x90, 0x98, 0xdf, 0xa6, 0xb9, 0xa8, 0x8e, 0x6c, 0x15, 0x55, 0x5c, 0x41, 0x96, 0x82, 0x0d, 0xa9,
+    0x5f, 0xa9, 0xf3, 0x77, 0x1d, 0xee, 0x6b, 0x4c, 0x94, 0xc6, 0xc6, 0x9b, 0x78, 0x5b, 0x03, 0xbd,
+    0xa9, 0x87, 0xdd, 0x24, 0x04, 0x70, 0xce, 0x6c, 0x52, 0xe6, 0x21, 0x63, 0x6d, 0x28, 0x6c, 0x30,
+    0x82, 0x05, 0x60, 0x30, 0x82, 0x03, 0x48, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xe8,
+    0xfa, 0x19, 0x63, 0x14, 0xd2, 0xfa, 0x18, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04,
+    0x05, 0x13, 0x10, 0x66, 0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38, 0x35, 0x33, 0x62, 0x36, 0x62,
+    0x30, 0x34, 0x35, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x35, 0x32, 0x36, 0x31, 0x36, 0x32,
+    0x38, 0x35, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x35, 0x32, 0x34, 0x31, 0x36, 0x32, 0x38,
+    0x35, 0x32, 0x5a, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x10,
+    0x66, 0x39, 0x32, 0x30, 0x30, 0x39, 0x65, 0x38, 0x35, 0x33, 0x62, 0x36, 0x62, 0x30, 0x34, 0x35,
+    0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01,
+    0x00, 0xaf, 0xb6, 0xc7, 0x82, 0x2b, 0xb1, 0xa7, 0x01, 0xec, 0x2b, 0xb4, 0x2e, 0x8b, 0xcc, 0x54,
+    0x16, 0x63, 0xab, 0xef, 0x98, 0x2f, 0x32, 0xc7, 0x7f, 0x75, 0x31, 0x03, 0x0c, 0x97, 0x52, 0x4b,
+    0x1b, 0x5f, 0xe8, 0x09, 0xfb, 0xc7, 0x2a, 0xa9, 0x45, 0x1f, 0x74, 0x3c, 0xbd, 0x9a, 0x6f, 0x13,
+    0x35, 0x74, 0x4a, 0xa5, 0x5e, 0x77, 0xf6, 0xb6, 0xac, 0x35, 0x35, 0xee, 0x17, 0xc2, 0x5e, 0x63,
+    0x95, 0x17, 0xdd, 0x9c, 0x92, 0xe6, 0x37, 0x4a, 0x53, 0xcb, 0xfe, 0x25, 0x8f, 0x8f, 0xfb, 0xb6,
+    0xfd, 0x12, 0x93, 0x78, 0xa2, 0x2a, 0x4c, 0xa9, 0x9c, 0x45, 0x2d, 0x47, 0xa5, 0x9f, 0x32, 0x01,
+    0xf4, 0x41, 0x97, 0xca, 0x1c, 0xcd, 0x7e, 0x76, 0x2f, 0xb2, 0xf5, 0x31, 0x51, 0xb6, 0xfe, 0xb2,
+    0xff, 0xfd, 0x2b, 0x6f, 0xe4, 0xfe, 0x5b, 0xc6, 0xbd, 0x9e, 0xc3, 0x4b, 0xfe, 0x08, 0x23, 0x9d,
+    0xaa, 0xfc, 0xeb, 0x8e, 0xb5, 0xa8, 0xed, 0x2b, 0x3a, 0xcd, 0x9c, 0x5e, 0x3a, 0x77, 0x90, 0xe1,
+    0xb5, 0x14, 0x42, 0x79, 0x31, 0x59, 0x85, 0x98, 0x11, 0xad, 0x9e, 0xb2, 0xa9, 0x6b, 0xbd, 0xd7,
+    0xa5, 0x7c, 0x93, 0xa9, 0x1c, 0x41, 0xfc, 0xcd, 0x27, 0xd6, 0x7f, 0xd6, 0xf6, 0x71, 0xaa, 0x0b,
+    0x81, 0x52, 0x61, 0xad, 0x38, 0x4f, 0xa3, 0x79, 0x44, 0x86, 0x46, 0x04, 0xdd, 0xb3, 0xd8, 0xc4,
+    0xf9, 0x20, 0xa1, 0x9b, 0x16, 0x56, 0xc2, 0xf1, 0x4a, 0xd6, 0xd0, 0x3c, 0x56, 0xec, 0x06, 0x08,
+    0x99, 0x04, 0x1c, 0x1e, 0xd1, 0xa5, 0xfe, 0x6d, 0x34, 0x40, 0xb5, 0x56, 0xba, 0xd1, 0xd0, 0xa1,
+    0x52, 0x58, 0x9c, 0x53, 0xe5, 0x5d, 0x37, 0x07, 0x62, 0xf0, 0x12, 0x2e, 0xef, 0x91, 0x86, 0x1b,
+    0x1b, 0x0e, 0x6c, 0x4c, 0x80, 0x92, 0x74, 0x99, 0xc0, 0xe9, 0xbe, 0xc0, 0xb8, 0x3e, 0x3b, 0xc1,
+    0xf9, 0x3c, 0x72, 0xc0, 0x49, 0x60, 0x4b, 0xbd, 0x2f, 0x13, 0x45, 0xe6, 0x2c, 0x3f, 0x8e, 0x26,
+    0xdb, 0xec, 0x06, 0xc9, 0x47, 0x66, 0xf3, 0xc1, 0x28, 0x23, 0x9d, 0x4f, 0x43, 0x12, 0xfa, 0xd8,
+    0x12, 0x38, 0x87, 0xe0, 0x6b, 0xec, 0xf5, 0x67, 0x58, 0x3b, 0xf8, 0x35, 0x5a, 0x81, 0xfe, 0xea,
+    0xba, 0xf9, 0x9a, 0x83, 0xc8, 0xdf, 0x3e, 0x2a, 0x32, 0x2a, 0xfc, 0x67, 0x2b, 0xf1, 0x20, 0xb1,
+    0x35, 0x15, 0x8b, 0x68, 0x21, 0xce, 0xaf, 0x30, 0x9b, 0x6e, 0xee, 0x77, 0xf9, 0x88, 0x33, 0xb0,
+    0x18, 0xda, 0xa1, 0x0e, 0x45, 0x1f, 0x06, 0xa3, 0x74, 0xd5, 0x07, 0x81, 0xf3, 0x59, 0x08, 0x29,
+    0x66, 0xbb, 0x77, 0x8b, 0x93, 0x08, 0x94, 0x26, 0x98, 0xe7, 0x4e, 0x0b, 0xcd, 0x24, 0x62, 0x8a,
+    0x01, 0xc2, 0xcc, 0x03, 0xe5, 0x1f, 0x0b, 0x3e, 0x5b, 0x4a, 0xc1, 0xe4, 0xdf, 0x9e, 0xaf, 0x9f,
+    0xf6, 0xa4, 0x92, 0xa7, 0x7c, 0x14, 0x83, 0x88, 0x28, 0x85, 0x01, 0x5b, 0x42, 0x2c, 0xe6, 0x7b,
+    0x80, 0xb8, 0x8c, 0x9b, 0x48, 0xe1, 0x3b, 0x60, 0x7a, 0xb5, 0x45, 0xc7, 0x23, 0xff, 0x8c, 0x44,
+    0xf8, 0xf2, 0xd3, 0x68, 0xb9, 0xf6, 0x52, 0x0d, 0x31, 0x14, 0x5e, 0xbf, 0x9e, 0x86, 0x2a, 0xd7,
+    0x1d, 0xf6, 0xa3, 0xbf, 0xd2, 0x45, 0x09, 0x59, 0xd6, 0x53, 0x74, 0x0d, 0x97, 0xa1, 0x2f, 0x36,
+    0x8b, 0x13, 0xef, 0x66, 0xd5, 0xd0, 0xa5, 0x4a, 0x6e, 0x2f, 0x5d, 0x9a, 0x6f, 0xef, 0x44, 0x68,
+    0x32, 0xbc, 0x67, 0x84, 0x47, 0x25, 0x86, 0x1f, 0x09, 0x3d, 0xd0, 0xe6, 0xf3, 0x40, 0x5d, 0xa8,
+    0x96, 0x43, 0xef, 0x0f, 0x4d, 0x69, 0xb6, 0x42, 0x00, 0x51, 0xfd, 0xb9, 0x30, 0x49, 0x67, 0x3e,
+    0x36, 0x95, 0x05, 0x80, 0xd3, 0xcd, 0xf4, 0xfb, 0xd0, 0x8b, 0xc5, 0x84, 0x83, 0x95, 0x26, 0x00,
+    0x63, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x36, 0x61, 0xe1, 0x00, 0x7c, 0x88, 0x05, 0x09, 0x51,
+    0x8b, 0x44, 0x6c, 0x47, 0xff, 0x1a, 0x4c, 0xc9, 0xea, 0x4f, 0x12, 0x30, 0x1f, 0x06, 0x03, 0x55,
+    0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x36, 0x61, 0xe1, 0x00, 0x7c, 0x88, 0x05, 0x09,
+    0x51, 0x8b, 0x44, 0x6c, 0x47, 0xff, 0x1a, 0x4c, 0xc9, 0xea, 0x4f, 0x12, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06,
+    0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x40, 0x06,
+    0x03, 0x55, 0x1d, 0x1f, 0x04, 0x39, 0x30, 0x37, 0x30, 0x35, 0xa0, 0x33, 0xa0, 0x31, 0x86, 0x2f,
+    0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+    0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
+    0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x30,
+    0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
+    0x02, 0x01, 0x00, 0x20, 0xc8, 0xc3, 0x8d, 0x4b, 0xdc, 0xa9, 0x57, 0x1b, 0x46, 0x8c, 0x89, 0x2f,
+    0xff, 0x72, 0xaa, 0xc6, 0xf8, 0x44, 0xa1, 0x1d, 0x41, 0xa8, 0xf0, 0x73, 0x6c, 0xc3, 0x7d, 0x16,
+    0xd6, 0x42, 0x6d, 0x8e, 0x7e, 0x94, 0x07, 0x04, 0x4c, 0xea, 0x39, 0xe6, 0x8b, 0x07, 0xc1, 0x3d,
+    0xbf, 0x15, 0x03, 0xdd, 0x5c, 0x85, 0xbd, 0xaf, 0xb2, 0xc0, 0x2d, 0x5f, 0x6c, 0xdb, 0x4e, 0xfa,
+    0x81, 0x27, 0xdf, 0x8b, 0x04, 0xf1, 0x82, 0x77, 0x0f, 0xc4, 0xe7, 0x74, 0x5b, 0x7f, 0xce, 0xaa,
+    0x87, 0x12, 0x9a, 0x88, 0x01, 0xce, 0x8e, 0x9b, 0xc0, 0xcb, 0x96, 0x37, 0x9b, 0x4d, 0x26, 0xa8,
+    0x2d, 0x30, 0xfd, 0x9c, 0x2f, 0x8e, 0xed, 0x6d, 0xc1, 0xbe, 0x2f, 0x84, 0xb6, 0x89, 0xe4, 0xd9,
+    0x14, 0x25, 0x8b, 0x14, 0x4b, 0xba, 0xe6, 0x24, 0xa1, 0xc7, 0x06, 0x71, 0x13, 0x2e, 0x2f, 0x06,
+    0x16, 0xa8, 0x84, 0xb2, 0xa4, 0xd6, 0xa4, 0x6f, 0xfa, 0x89, 0xb6, 0x02, 0xbf, 0xba, 0xd8, 0x0c,
+    0x12, 0x43, 0x71, 0x1f, 0x56, 0xeb, 0x60, 0x56, 0xf6, 0x37, 0xc8, 0xa0, 0x14, 0x1c, 0xc5, 0x40,
+    0x94, 0x26, 0x8b, 0x8c, 0x3c, 0x7d, 0xb9, 0x94, 0xb3, 0x5c, 0x0d, 0xcd, 0x6c, 0xb2, 0xab, 0xc2,
+    0xda, 0xfe, 0xe2, 0x52, 0x02, 0x3d, 0x2d, 0xea, 0x0c, 0xd6, 0xc3, 0x68, 0xbe, 0xa3, 0xe6, 0x41,
+    0x48, 0x86, 0xf6, 0xb1, 0xe5, 0x8b, 0x5b, 0xd7, 0xc7, 0x30, 0xb2, 0x68, 0xc4, 0xe3, 0xc1, 0xfb,
+    0x64, 0x24, 0xb9, 0x1f, 0xeb, 0xbd, 0xb8, 0x0c, 0x58, 0x6e, 0x2a, 0xe8, 0x36, 0x8c, 0x84, 0xd5,
+    0xd1, 0x09, 0x17, 0xbd, 0xa2, 0x56, 0x17, 0x89, 0xd4, 0x68, 0x73, 0x93, 0x34, 0x0e, 0x2e, 0x25,
+    0x4f, 0x56, 0x0e, 0xf6, 0x4b, 0x23, 0x58, 0xfc, 0xdc, 0x0f, 0xbf, 0xc6, 0x70, 0x09, 0x52, 0xe7,
+    0x08, 0xbf, 0xfc, 0xc6, 0x27, 0x50, 0x0c, 0x1f, 0x66, 0xe8, 0x1e, 0xa1, 0x7c, 0x09, 0x8d, 0x7a,
+    0x2e, 0x9b, 0x18, 0x80, 0x1b, 0x7a, 0xb4, 0xac, 0x71, 0x58, 0x7d, 0x34, 0x5d, 0xcc, 0x83, 0x09,
+    0xd5, 0xb6, 0x2a, 0x50, 0x42, 0x7a, 0xa6, 0xd0, 0x3d, 0xcb, 0x05, 0x99, 0x6c, 0x96, 0xba, 0x0c,
+    0x5d, 0x71, 0xe9, 0x21, 0x62, 0xc0, 0x16, 0xca, 0x84, 0x9f, 0xf3, 0x5f, 0x0d, 0x52, 0xc6, 0x5d,
+    0x05, 0x60, 0x5a, 0x47, 0xf3, 0xae, 0x91, 0x7a, 0xcd, 0x2d, 0xf9, 0x10, 0xef, 0xd2, 0x32, 0x66,
+    0x88, 0x59, 0x6e, 0xf6, 0x9b, 0x3b, 0xf5, 0xfe, 0x31, 0x54, 0xf7, 0xae, 0xb8, 0x80, 0xa0, 0xa7,
+    0x3c, 0xa0, 0x4d, 0x94, 0xc2, 0xce, 0x83, 0x17, 0xee, 0xb4, 0x3d, 0x5e, 0xff, 0x58, 0x83, 0xe3,
+    0x36, 0xf5, 0xf2, 0x49, 0xda, 0xac, 0xa4, 0x89, 0x92, 0x37, 0xbf, 0x26, 0x7e, 0x5c, 0x43, 0xab,
+    0x02, 0xea, 0x44, 0x16, 0x24, 0x03, 0x72, 0x3b, 0xe6, 0xaa, 0x69, 0x2c, 0x61, 0xbd, 0xae, 0x9e,
+    0xd4, 0x09, 0xd4, 0x63, 0xc4, 0xc9, 0x7c, 0x64, 0x30, 0x65, 0x77, 0xee, 0xf2, 0xbc, 0x75, 0x60,
+    0xb7, 0x57, 0x15, 0xcc, 0x9c, 0x7d, 0xc6, 0x7c, 0x86, 0x08, 0x2d, 0xb7, 0x51, 0xa8, 0x9c, 0x30,
+    0x34, 0x97, 0x62, 0xb0, 0x78, 0x23, 0x85, 0x87, 0x5c, 0xf1, 0xa3, 0xc6, 0x16, 0x6e, 0x0a, 0xe3,
+    0xc1, 0x2d, 0x37, 0x4e, 0x2d, 0x4f, 0x18, 0x46, 0xf3, 0x18, 0x74, 0x4b, 0xd8, 0x79, 0xb5, 0x87,
+    0x32, 0x9b, 0xf0, 0x18, 0x21, 0x7a, 0x6c, 0x0c, 0x77, 0x24, 0x1a, 0x48, 0x78, 0xe4, 0x35, 0xc0,
+    0x30, 0x79, 0xcb, 0x45, 0x12, 0x89, 0xc5, 0x77, 0x62, 0x06, 0x06, 0x9a, 0x2f, 0x8d, 0x65, 0xf8,
+    0x40, 0xe1, 0x44, 0x52, 0x87, 0xbe, 0xd8, 0x77, 0xab, 0xae, 0x24, 0xe2, 0x44, 0x35, 0x16, 0x8d,
+    0x55, 0x3c, 0xe4,
+];
diff --git a/keystore2/src/legacy_migrator.rs b/keystore2/src/legacy_migrator.rs
new file mode 100644
index 0000000..d5647cd
--- /dev/null
+++ b/keystore2/src/legacy_migrator.rs
@@ -0,0 +1,730 @@
+// Copyright 2021, 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.
+
+//! This module acts as a bridge between the legacy key database and the keystore2 database.
+
+use crate::error::Error;
+use crate::key_parameter::KeyParameterValue;
+use crate::legacy_blob::BlobValue;
+use crate::utils::{uid_to_android_user, watchdog as wd};
+use crate::{async_task::AsyncTask, legacy_blob::LegacyBlobLoader};
+use crate::{
+    database::{
+        BlobMetaData, BlobMetaEntry, CertificateInfo, DateTime, EncryptedBy, KeyMetaData,
+        KeyMetaEntry, KeystoreDB, Uuid, KEYSTORE_UUID,
+    },
+    super_key::USER_SUPER_KEY,
+};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor, ResponseCode::ResponseCode,
+};
+use anyhow::{Context, Result};
+use core::ops::Deref;
+use keystore2_crypto::{Password, ZVec};
+use std::collections::{HashMap, HashSet};
+use std::sync::atomic::{AtomicU8, Ordering};
+use std::sync::mpsc::channel;
+use std::sync::{Arc, Mutex};
+
+/// Represents LegacyMigrator.
+pub struct LegacyMigrator {
+    async_task: Arc<AsyncTask>,
+    initializer: Mutex<
+        Option<
+            Box<
+                dyn FnOnce() -> (KeystoreDB, HashMap<SecurityLevel, Uuid>, Arc<LegacyBlobLoader>)
+                    + Send
+                    + 'static,
+            >,
+        >,
+    >,
+    /// This atomic is used for cheap interior mutability. It is intended to prevent
+    /// expensive calls into the legacy migrator when the legacy database is empty.
+    /// When transitioning from READY to EMPTY, spurious calls may occur for a brief period
+    /// of time. This is tolerable in favor of the common case.
+    state: AtomicU8,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+struct RecentMigration {
+    uid: u32,
+    alias: String,
+}
+
+impl RecentMigration {
+    fn new(uid: u32, alias: String) -> Self {
+        Self { uid, alias }
+    }
+}
+
+enum BulkDeleteRequest {
+    Uid(u32),
+    User(u32),
+}
+
+struct LegacyMigratorState {
+    recently_migrated: HashSet<RecentMigration>,
+    recently_migrated_super_key: HashSet<u32>,
+    legacy_loader: Arc<LegacyBlobLoader>,
+    sec_level_to_km_uuid: HashMap<SecurityLevel, Uuid>,
+    db: KeystoreDB,
+}
+
+impl LegacyMigrator {
+    const WIFI_NAMESPACE: i64 = 102;
+    const AID_WIFI: u32 = 1010;
+
+    const STATE_UNINITIALIZED: u8 = 0;
+    const STATE_READY: u8 = 1;
+    const STATE_EMPTY: u8 = 2;
+
+    /// Constructs a new LegacyMigrator using the given AsyncTask object as migration
+    /// worker.
+    pub fn new(async_task: Arc<AsyncTask>) -> Self {
+        Self {
+            async_task,
+            initializer: Default::default(),
+            state: AtomicU8::new(Self::STATE_UNINITIALIZED),
+        }
+    }
+
+    /// The legacy migrator must be initialized deferred, because keystore starts very early.
+    /// At this time the data partition may not be mounted. So we cannot open database connections
+    /// until we get actual key load requests. This sets the function that the legacy loader
+    /// uses to connect to the database.
+    pub fn set_init<F>(&self, f_init: F) -> Result<()>
+    where
+        F: FnOnce() -> (KeystoreDB, HashMap<SecurityLevel, Uuid>, Arc<LegacyBlobLoader>)
+            + Send
+            + 'static,
+    {
+        let mut initializer = self.initializer.lock().expect("Failed to lock initializer.");
+
+        // If we are not uninitialized we have no business setting the initializer.
+        if self.state.load(Ordering::Relaxed) != Self::STATE_UNINITIALIZED {
+            return Ok(());
+        }
+
+        // Only set the initializer if it hasn't been set before.
+        if initializer.is_none() {
+            *initializer = Some(Box::new(f_init))
+        }
+
+        Ok(())
+    }
+
+    /// This function is called by the migration requestor to check if it is worth
+    /// making a migration request. It also transitions the state from UNINITIALIZED
+    /// to READY or EMPTY on first use. The deferred initialization is necessary, because
+    /// Keystore 2.0 runs early during boot, where data may not yet be mounted.
+    /// Returns Ok(STATE_READY) if a migration request is worth undertaking and
+    /// Ok(STATE_EMPTY) if the database is empty. An error is returned if the loader
+    /// was not initialized and cannot be initialized.
+    fn check_state(&self) -> Result<u8> {
+        let mut first_try = true;
+        loop {
+            match (self.state.load(Ordering::Relaxed), first_try) {
+                (Self::STATE_EMPTY, _) => {
+                    return Ok(Self::STATE_EMPTY);
+                }
+                (Self::STATE_UNINITIALIZED, true) => {
+                    // If we find the legacy loader uninitialized, we grab the initializer lock,
+                    // check if the legacy database is empty, and if not, schedule an initialization
+                    // request. Coming out of the initializer lock, the state is either EMPTY or
+                    // READY.
+                    let mut initializer = self.initializer.lock().unwrap();
+
+                    if let Some(initializer) = initializer.take() {
+                        let (db, sec_level_to_km_uuid, legacy_loader) = (initializer)();
+
+                        if legacy_loader.is_empty().context(
+                            "In check_state: Trying to check if the legacy database is empty.",
+                        )? {
+                            self.state.store(Self::STATE_EMPTY, Ordering::Relaxed);
+                            return Ok(Self::STATE_EMPTY);
+                        }
+
+                        self.async_task.queue_hi(move |shelf| {
+                            shelf.get_or_put_with(|| LegacyMigratorState {
+                                recently_migrated: Default::default(),
+                                recently_migrated_super_key: Default::default(),
+                                legacy_loader,
+                                sec_level_to_km_uuid,
+                                db,
+                            });
+                        });
+
+                        // It is safe to set this here even though the async task may not yet have
+                        // run because any thread observing this will not be able to schedule a
+                        // task that can run before the initialization.
+                        // Also we can only transition out of this state while having the
+                        // initializer lock and having found an initializer.
+                        self.state.store(Self::STATE_READY, Ordering::Relaxed);
+                        return Ok(Self::STATE_READY);
+                    } else {
+                        // There is a chance that we just lost the race from state.load() to
+                        // grabbing the initializer mutex. If that is the case the state must
+                        // be EMPTY or READY after coming out of the lock. So we can give it
+                        // one more try.
+                        first_try = false;
+                        continue;
+                    }
+                }
+                (Self::STATE_UNINITIALIZED, false) => {
+                    // Okay, tough luck. The legacy loader was really completely uninitialized.
+                    return Err(Error::sys()).context(
+                        "In check_state: Legacy loader should not be called uninitialized.",
+                    );
+                }
+                (Self::STATE_READY, _) => return Ok(Self::STATE_READY),
+                (s, _) => panic!("Unknown legacy migrator state. {} ", s),
+            }
+        }
+    }
+
+    /// List all aliases for uid in the legacy database.
+    pub fn list_uid(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
+        let _wp = wd::watch_millis("LegacyMigrator::list_uid", 500);
+
+        let uid = match (domain, namespace) {
+            (Domain::APP, namespace) => namespace as u32,
+            (Domain::SELINUX, Self::WIFI_NAMESPACE) => Self::AID_WIFI,
+            _ => return Ok(Vec::new()),
+        };
+        self.do_serialized(move |state| state.list_uid(uid)).unwrap_or_else(|| Ok(Vec::new())).map(
+            |v| {
+                v.into_iter()
+                    .map(|alias| KeyDescriptor {
+                        domain,
+                        nspace: namespace,
+                        alias: Some(alias),
+                        blob: None,
+                    })
+                    .collect()
+            },
+        )
+    }
+
+    /// Sends the given closure to the migrator thread for execution after calling check_state.
+    /// Returns None if the database was empty and the request was not executed.
+    /// Otherwise returns Some with the result produced by the migration request.
+    /// The loader state may transition to STATE_EMPTY during the execution of this function.
+    fn do_serialized<F, T: Send + 'static>(&self, f: F) -> Option<Result<T>>
+    where
+        F: FnOnce(&mut LegacyMigratorState) -> Result<T> + Send + 'static,
+    {
+        // Short circuit if the database is empty or not initialized (error case).
+        match self.check_state().context("In do_serialized: Checking state.") {
+            Ok(LegacyMigrator::STATE_EMPTY) => return None,
+            Ok(LegacyMigrator::STATE_READY) => {}
+            Err(e) => return Some(Err(e)),
+            Ok(s) => panic!("Unknown legacy migrator state. {} ", s),
+        }
+
+        // We have established that there may be a key in the legacy database.
+        // Now we schedule a migration request.
+        let (sender, receiver) = channel();
+        self.async_task.queue_hi(move |shelf| {
+            // Get the migrator state from the shelf.
+            // There may not be a state. This can happen if this migration request was scheduled
+            // before a previous request established that the legacy database was empty
+            // and removed the state from the shelf. Since we know now that the database
+            // is empty, we can return None here.
+            let (new_state, result) = if let Some(legacy_migrator_state) =
+                shelf.get_downcast_mut::<LegacyMigratorState>()
+            {
+                let result = f(legacy_migrator_state);
+                (legacy_migrator_state.check_empty(), Some(result))
+            } else {
+                (Self::STATE_EMPTY, None)
+            };
+
+            // If the migration request determined that the database is now empty, we discard
+            // the state from the shelf to free up the resources we won't need any longer.
+            if result.is_some() && new_state == Self::STATE_EMPTY {
+                shelf.remove_downcast_ref::<LegacyMigratorState>();
+            }
+
+            // Send the result to the requester.
+            if let Err(e) = sender.send((new_state, result)) {
+                log::error!("In do_serialized. Error in sending the result. {:?}", e);
+            }
+        });
+
+        let (new_state, result) = match receiver.recv() {
+            Err(e) => {
+                return Some(Err(e).context("In do_serialized. Failed to receive from the sender."))
+            }
+            Ok(r) => r,
+        };
+
+        // We can only transition to EMPTY but never back.
+        // The migrator never creates any legacy blobs.
+        if new_state == Self::STATE_EMPTY {
+            self.state.store(Self::STATE_EMPTY, Ordering::Relaxed)
+        }
+
+        result
+    }
+
+    /// Runs the key_accessor function and returns its result. If it returns an error and the
+    /// root cause was KEY_NOT_FOUND, tries to migrate a key with the given parameters from
+    /// the legacy database to the new database and runs the key_accessor function again if
+    /// the migration request was successful.
+    pub fn with_try_migrate<F, T>(
+        &self,
+        key: &KeyDescriptor,
+        caller_uid: u32,
+        key_accessor: F,
+    ) -> Result<T>
+    where
+        F: Fn() -> Result<T>,
+    {
+        let _wp = wd::watch_millis("LegacyMigrator::with_try_migrate", 500);
+
+        // Access the key and return on success.
+        match key_accessor() {
+            Ok(result) => return Ok(result),
+            Err(e) => match e.root_cause().downcast_ref::<Error>() {
+                Some(&Error::Rc(ResponseCode::KEY_NOT_FOUND)) => {}
+                _ => return Err(e),
+            },
+        }
+
+        // Filter inputs. We can only load legacy app domain keys and some special rules due
+        // to which we migrate keys transparently to an SELINUX domain.
+        let uid = match key {
+            KeyDescriptor { domain: Domain::APP, alias: Some(_), .. } => caller_uid,
+            KeyDescriptor { domain: Domain::SELINUX, nspace, alias: Some(_), .. } => {
+                match *nspace {
+                    Self::WIFI_NAMESPACE => Self::AID_WIFI,
+                    _ => {
+                        return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+                            .context(format!("No legacy keys for namespace {}", nspace))
+                    }
+                }
+            }
+            _ => {
+                return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+                    .context("No legacy keys for key descriptor.")
+            }
+        };
+
+        let key_clone = key.clone();
+        let result = self
+            .do_serialized(move |migrator_state| migrator_state.check_and_migrate(uid, key_clone));
+
+        if let Some(result) = result {
+            result?;
+            // After successful migration try again.
+            key_accessor()
+        } else {
+            Err(Error::Rc(ResponseCode::KEY_NOT_FOUND)).context("Legacy database is empty.")
+        }
+    }
+
+    /// Calls key_accessor and returns the result on success. In the case of a KEY_NOT_FOUND error
+    /// this function makes a migration request and on success retries the key_accessor.
+    pub fn with_try_migrate_super_key<F, T>(
+        &self,
+        user_id: u32,
+        pw: &Password,
+        mut key_accessor: F,
+    ) -> Result<Option<T>>
+    where
+        F: FnMut() -> Result<Option<T>>,
+    {
+        let _wp = wd::watch_millis("LegacyMigrator::with_try_migrate_super_key", 500);
+
+        match key_accessor() {
+            Ok(Some(result)) => return Ok(Some(result)),
+            Ok(None) => {}
+            Err(e) => return Err(e),
+        }
+        let pw = pw.try_clone().context("In with_try_migrate_super_key: Cloning password.")?;
+        let result = self.do_serialized(move |migrator_state| {
+            migrator_state.check_and_migrate_super_key(user_id, &pw)
+        });
+
+        if let Some(result) = result {
+            result?;
+            // After successful migration try again.
+            key_accessor()
+        } else {
+            Ok(None)
+        }
+    }
+
+    /// Deletes all keys belonging to the given namespace, migrating them into the database
+    /// for subsequent garbage collection if necessary.
+    pub fn bulk_delete_uid(&self, domain: Domain, nspace: i64) -> Result<()> {
+        let _wp = wd::watch_millis("LegacyMigrator::bulk_delete_uid", 500);
+
+        let uid = match (domain, nspace) {
+            (Domain::APP, nspace) => nspace as u32,
+            (Domain::SELINUX, Self::WIFI_NAMESPACE) => Self::AID_WIFI,
+            // Nothing to do.
+            _ => return Ok(()),
+        };
+
+        let result = self.do_serialized(move |migrator_state| {
+            migrator_state.bulk_delete(BulkDeleteRequest::Uid(uid), false)
+        });
+
+        result.unwrap_or(Ok(()))
+    }
+
+    /// Deletes all keys belonging to the given android user, migrating them into the database
+    /// for subsequent garbage collection if necessary.
+    pub fn bulk_delete_user(
+        &self,
+        user_id: u32,
+        keep_non_super_encrypted_keys: bool,
+    ) -> Result<()> {
+        let _wp = wd::watch_millis("LegacyMigrator::bulk_delete_user", 500);
+
+        let result = self.do_serialized(move |migrator_state| {
+            migrator_state
+                .bulk_delete(BulkDeleteRequest::User(user_id), keep_non_super_encrypted_keys)
+        });
+
+        result.unwrap_or(Ok(()))
+    }
+
+    /// Queries the legacy database for the presence of a super key for the given user.
+    pub fn has_super_key(&self, user_id: u32) -> Result<bool> {
+        let result =
+            self.do_serialized(move |migrator_state| migrator_state.has_super_key(user_id));
+        result.unwrap_or(Ok(false))
+    }
+}
+
+impl LegacyMigratorState {
+    fn get_km_uuid(&self, is_strongbox: bool) -> Result<Uuid> {
+        let sec_level = if is_strongbox {
+            SecurityLevel::STRONGBOX
+        } else {
+            SecurityLevel::TRUSTED_ENVIRONMENT
+        };
+
+        self.sec_level_to_km_uuid.get(&sec_level).copied().ok_or_else(|| {
+            anyhow::anyhow!(Error::sys()).context("In get_km_uuid: No KM instance for blob.")
+        })
+    }
+
+    fn list_uid(&mut self, uid: u32) -> Result<Vec<String>> {
+        self.legacy_loader
+            .list_keystore_entries_for_uid(uid)
+            .context("In list_uid: Trying to list legacy entries.")
+    }
+
+    /// This is a key migration request that must run in the migrator thread. This must
+    /// be passed to do_serialized.
+    fn check_and_migrate(&mut self, uid: u32, mut key: KeyDescriptor) -> Result<()> {
+        let alias = key.alias.clone().ok_or_else(|| {
+            anyhow::anyhow!(Error::sys()).context(concat!(
+                "In check_and_migrate: Must be Some because ",
+                "our caller must not have called us otherwise."
+            ))
+        })?;
+
+        if self.recently_migrated.contains(&RecentMigration::new(uid, alias.clone())) {
+            return Ok(());
+        }
+
+        if key.domain == Domain::APP {
+            key.nspace = uid as i64;
+        }
+
+        // If the key is not found in the cache, try to load from the legacy database.
+        let (km_blob_params, user_cert, ca_cert) = self
+            .legacy_loader
+            .load_by_uid_alias(uid, &alias, None)
+            .context("In check_and_migrate: Trying to load legacy blob.")?;
+        let result = match km_blob_params {
+            Some((km_blob, params)) => {
+                let is_strongbox = km_blob.is_strongbox();
+                let (blob, mut blob_metadata) = match km_blob.take_value() {
+                    BlobValue::Encrypted { iv, tag, data } => {
+                        // Get super key id for user id.
+                        let user_id = uid_to_android_user(uid as u32);
+
+                        let super_key_id = match self
+                            .db
+                            .load_super_key(&USER_SUPER_KEY, user_id)
+                            .context("In check_and_migrate: Failed to load super key")?
+                        {
+                            Some((_, entry)) => entry.id(),
+                            None => {
+                                // This might be the first time we access the super key,
+                                // and it may not have been migrated. We cannot import
+                                // the legacy super_key key now, because we need to reencrypt
+                                // it which we cannot do if we are not unlocked, which we are
+                                // not because otherwise the key would have been migrated.
+                                // We can check though if the key exists. If it does,
+                                // we can return Locked. Otherwise, we can delete the
+                                // key and return NotFound, because the key will never
+                                // be unlocked again.
+                                if self.legacy_loader.has_super_key(user_id) {
+                                    return Err(Error::Rc(ResponseCode::LOCKED)).context(concat!(
+                                        "In check_and_migrate: Cannot migrate super key of this ",
+                                        "key while user is locked."
+                                    ));
+                                } else {
+                                    self.legacy_loader.remove_keystore_entry(uid, &alias).context(
+                                        concat!(
+                                            "In check_and_migrate: ",
+                                            "Trying to remove obsolete key."
+                                        ),
+                                    )?;
+                                    return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+                                        .context("In check_and_migrate: Obsolete key.");
+                                }
+                            }
+                        };
+
+                        let mut blob_metadata = BlobMetaData::new();
+                        blob_metadata.add(BlobMetaEntry::Iv(iv.to_vec()));
+                        blob_metadata.add(BlobMetaEntry::AeadTag(tag.to_vec()));
+                        blob_metadata
+                            .add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(super_key_id)));
+                        (LegacyBlob::Vec(data), blob_metadata)
+                    }
+                    BlobValue::Decrypted(data) => (LegacyBlob::ZVec(data), BlobMetaData::new()),
+                    _ => {
+                        return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+                            .context("In check_and_migrate: Legacy key has unexpected type.")
+                    }
+                };
+
+                let km_uuid = self
+                    .get_km_uuid(is_strongbox)
+                    .context("In check_and_migrate: Trying to get KM UUID")?;
+                blob_metadata.add(BlobMetaEntry::KmUuid(km_uuid));
+
+                let mut metadata = KeyMetaData::new();
+                let creation_date = DateTime::now()
+                    .context("In check_and_migrate: Trying to make creation time.")?;
+                metadata.add(KeyMetaEntry::CreationDate(creation_date));
+
+                // Store legacy key in the database.
+                self.db
+                    .store_new_key(
+                        &key,
+                        &params,
+                        &(&blob, &blob_metadata),
+                        &CertificateInfo::new(user_cert, ca_cert),
+                        &metadata,
+                        &km_uuid,
+                    )
+                    .context("In check_and_migrate.")?;
+                Ok(())
+            }
+            None => {
+                if let Some(ca_cert) = ca_cert {
+                    self.db
+                        .store_new_certificate(&key, &ca_cert, &KEYSTORE_UUID)
+                        .context("In check_and_migrate: Failed to insert new certificate.")?;
+                    Ok(())
+                } else {
+                    Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+                        .context("In check_and_migrate: Legacy key not found.")
+                }
+            }
+        };
+
+        match result {
+            Ok(()) => {
+                // Add the key to the migrated_keys list.
+                self.recently_migrated.insert(RecentMigration::new(uid, alias.clone()));
+                // Delete legacy key from the file system
+                self.legacy_loader
+                    .remove_keystore_entry(uid, &alias)
+                    .context("In check_and_migrate: Trying to remove migrated key.")?;
+                Ok(())
+            }
+            Err(e) => Err(e),
+        }
+    }
+
+    fn check_and_migrate_super_key(&mut self, user_id: u32, pw: &Password) -> Result<()> {
+        if self.recently_migrated_super_key.contains(&user_id) {
+            return Ok(());
+        }
+
+        if let Some(super_key) = self
+            .legacy_loader
+            .load_super_key(user_id, &pw)
+            .context("In check_and_migrate_super_key: Trying to load legacy super key.")?
+        {
+            let (blob, blob_metadata) =
+                crate::super_key::SuperKeyManager::encrypt_with_password(&super_key, pw)
+                    .context("In check_and_migrate_super_key: Trying to encrypt super key.")?;
+
+            self.db
+                .store_super_key(
+                    user_id,
+                    &USER_SUPER_KEY,
+                    &blob,
+                    &blob_metadata,
+                    &KeyMetaData::new(),
+                )
+                .context(concat!(
+                    "In check_and_migrate_super_key: ",
+                    "Trying to insert legacy super_key into the database."
+                ))?;
+            self.legacy_loader.remove_super_key(user_id);
+            self.recently_migrated_super_key.insert(user_id);
+            Ok(())
+        } else {
+            Err(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+                .context("In check_and_migrate_super_key: No key found do migrate.")
+        }
+    }
+
+    /// Key migrator request to be run by do_serialized.
+    /// See LegacyMigrator::bulk_delete_uid and LegacyMigrator::bulk_delete_user.
+    fn bulk_delete(
+        &mut self,
+        bulk_delete_request: BulkDeleteRequest,
+        keep_non_super_encrypted_keys: bool,
+    ) -> Result<()> {
+        let (aliases, user_id) = match bulk_delete_request {
+            BulkDeleteRequest::Uid(uid) => (
+                self.legacy_loader
+                    .list_keystore_entries_for_uid(uid)
+                    .context("In bulk_delete: Trying to get aliases for uid.")
+                    .map(|aliases| {
+                        let mut h = HashMap::<u32, HashSet<String>>::new();
+                        h.insert(uid, aliases.into_iter().collect());
+                        h
+                    })?,
+                uid_to_android_user(uid),
+            ),
+            BulkDeleteRequest::User(user_id) => (
+                self.legacy_loader
+                    .list_keystore_entries_for_user(user_id)
+                    .context("In bulk_delete: Trying to get aliases for user_id.")?,
+                user_id,
+            ),
+        };
+
+        let super_key_id = self
+            .db
+            .load_super_key(&USER_SUPER_KEY, user_id)
+            .context("In bulk_delete: Failed to load super key")?
+            .map(|(_, entry)| entry.id());
+
+        for (uid, alias) in aliases
+            .into_iter()
+            .map(|(uid, aliases)| aliases.into_iter().map(move |alias| (uid, alias)))
+            .flatten()
+        {
+            let (km_blob_params, _, _) = self
+                .legacy_loader
+                .load_by_uid_alias(uid, &alias, None)
+                .context("In bulk_delete: Trying to load legacy blob.")?;
+
+            // Determine if the key needs special handling to be deleted.
+            let (need_gc, is_super_encrypted) = km_blob_params
+                .as_ref()
+                .map(|(blob, params)| {
+                    (
+                        params.iter().any(|kp| {
+                            KeyParameterValue::RollbackResistance == *kp.key_parameter_value()
+                        }),
+                        blob.is_encrypted(),
+                    )
+                })
+                .unwrap_or((false, false));
+
+            if keep_non_super_encrypted_keys && !is_super_encrypted {
+                continue;
+            }
+
+            if need_gc {
+                let mark_deleted = match km_blob_params
+                    .map(|(blob, _)| (blob.is_strongbox(), blob.take_value()))
+                {
+                    Some((is_strongbox, BlobValue::Encrypted { iv, tag, data })) => {
+                        let mut blob_metadata = BlobMetaData::new();
+                        if let (Ok(km_uuid), Some(super_key_id)) =
+                            (self.get_km_uuid(is_strongbox), super_key_id)
+                        {
+                            blob_metadata.add(BlobMetaEntry::KmUuid(km_uuid));
+                            blob_metadata.add(BlobMetaEntry::Iv(iv.to_vec()));
+                            blob_metadata.add(BlobMetaEntry::AeadTag(tag.to_vec()));
+                            blob_metadata
+                                .add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(super_key_id)));
+                            Some((LegacyBlob::Vec(data), blob_metadata))
+                        } else {
+                            // Oh well - we tried our best, but if we cannot determine which
+                            // KeyMint instance we have to send this blob to, we cannot
+                            // do more than delete the key from the file system.
+                            // And if we don't know which key wraps this key we cannot
+                            // unwrap it for KeyMint either.
+                            None
+                        }
+                    }
+                    Some((_, BlobValue::Decrypted(data))) => {
+                        Some((LegacyBlob::ZVec(data), BlobMetaData::new()))
+                    }
+                    _ => None,
+                };
+
+                if let Some((blob, blob_metadata)) = mark_deleted {
+                    self.db.set_deleted_blob(&blob, &blob_metadata).context(concat!(
+                        "In bulk_delete: Trying to insert deleted ",
+                        "blob into the database for garbage collection."
+                    ))?;
+                }
+            }
+
+            self.legacy_loader
+                .remove_keystore_entry(uid, &alias)
+                .context("In bulk_delete: Trying to remove migrated key.")?;
+        }
+        Ok(())
+    }
+
+    fn has_super_key(&mut self, user_id: u32) -> Result<bool> {
+        Ok(self.recently_migrated_super_key.contains(&user_id)
+            || self.legacy_loader.has_super_key(user_id))
+    }
+
+    fn check_empty(&self) -> u8 {
+        if self.legacy_loader.is_empty().unwrap_or(false) {
+            LegacyMigrator::STATE_EMPTY
+        } else {
+            LegacyMigrator::STATE_READY
+        }
+    }
+}
+
+enum LegacyBlob {
+    Vec(Vec<u8>),
+    ZVec(ZVec),
+}
+
+impl Deref for LegacyBlob {
+    type Target = [u8];
+
+    fn deref(&self) -> &Self::Target {
+        match self {
+            Self::Vec(v) => &v,
+            Self::ZVec(v) => &v,
+        }
+    }
+}
diff --git a/keystore2/src/lib.rs b/keystore2/src/lib.rs
new file mode 100644
index 0000000..c04c4b0
--- /dev/null
+++ b/keystore2/src/lib.rs
@@ -0,0 +1,52 @@
+// Copyright 2020, 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.
+
+//! This crate implements the Android Keystore 2.0 service.
+#![recursion_limit = "256"]
+
+pub mod apc;
+pub mod async_task;
+pub mod authorization;
+pub mod boot_level_keys;
+pub mod database;
+pub mod ec_crypto;
+pub mod enforcements;
+pub mod entropy;
+pub mod error;
+pub mod globals;
+pub mod id_rotation;
+/// Internal Representation of Key Parameter and convenience functions.
+pub mod key_parameter;
+pub mod legacy_blob;
+pub mod legacy_migrator;
+pub mod maintenance;
+pub mod metrics;
+pub mod operation;
+pub mod permission;
+pub mod raw_device;
+pub mod remote_provisioning;
+pub mod security_level;
+pub mod service;
+pub mod shared_secret_negotiation;
+pub mod try_insert;
+pub mod utils;
+
+mod attestation_key_utils;
+mod audit_log;
+mod db_utils;
+mod gc;
+mod super_key;
+
+#[cfg(feature = "watchdog")]
+mod watchdog;
diff --git a/keystore2/src/maintenance.rs b/keystore2/src/maintenance.rs
new file mode 100644
index 0000000..a099d18
--- /dev/null
+++ b/keystore2/src/maintenance.rs
@@ -0,0 +1,270 @@
+// Copyright 2021, 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.
+
+//! This module implements IKeystoreMaintenance AIDL interface.
+
+use crate::database::{KeyEntryLoadBits, KeyType, MonotonicRawTime};
+use crate::error::map_km_error;
+use crate::error::map_or_log_err;
+use crate::error::Error;
+use crate::globals::get_keymint_device;
+use crate::globals::{DB, LEGACY_MIGRATOR, SUPER_KEY};
+use crate::permission::{KeyPerm, KeystorePerm};
+use crate::super_key::UserState;
+use crate::utils::{check_key_permission, check_keystore_permission, watchdog as wd};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::IKeyMintDevice::IKeyMintDevice;
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
+use android_security_maintenance::aidl::android::security::maintenance::{
+    IKeystoreMaintenance::{BnKeystoreMaintenance, IKeystoreMaintenance},
+    UserState::UserState as AidlUserState,
+};
+use android_security_maintenance::binder::{
+    BinderFeatures, Interface, Result as BinderResult, Strong, ThreadState,
+};
+use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor,
+};
+use anyhow::{Context, Result};
+use keystore2_crypto::Password;
+
+/// This struct is defined to implement the aforementioned AIDL interface.
+/// As of now, it is an empty struct.
+pub struct Maintenance;
+
+impl Maintenance {
+    /// Create a new instance of Keystore User Manager service.
+    pub fn new_native_binder() -> Result<Strong<dyn IKeystoreMaintenance>> {
+        Ok(BnKeystoreMaintenance::new_binder(
+            Self,
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        ))
+    }
+
+    fn on_user_password_changed(user_id: i32, password: Option<Password>) -> Result<()> {
+        //Check permission. Function should return if this failed. Therefore having '?' at the end
+        //is very important.
+        check_keystore_permission(KeystorePerm::change_password())
+            .context("In on_user_password_changed.")?;
+
+        if let Some(pw) = password.as_ref() {
+            DB.with(|db| {
+                SUPER_KEY.unlock_screen_lock_bound_key(&mut db.borrow_mut(), user_id as u32, pw)
+            })
+            .context("In on_user_password_changed: unlock_screen_lock_bound_key failed")?;
+        }
+
+        match DB
+            .with(|db| {
+                UserState::get_with_password_changed(
+                    &mut db.borrow_mut(),
+                    &LEGACY_MIGRATOR,
+                    &SUPER_KEY,
+                    user_id as u32,
+                    password.as_ref(),
+                )
+            })
+            .context("In on_user_password_changed.")?
+        {
+            UserState::LskfLocked => {
+                // Error - password can not be changed when the device is locked
+                Err(Error::Rc(ResponseCode::LOCKED))
+                    .context("In on_user_password_changed. Device is locked.")
+            }
+            _ => {
+                // LskfLocked is the only error case for password change
+                Ok(())
+            }
+        }
+    }
+
+    fn add_or_remove_user(user_id: i32) -> Result<()> {
+        // Check permission. Function should return if this failed. Therefore having '?' at the end
+        // is very important.
+        check_keystore_permission(KeystorePerm::change_user()).context("In add_or_remove_user.")?;
+        DB.with(|db| {
+            UserState::reset_user(
+                &mut db.borrow_mut(),
+                &SUPER_KEY,
+                &LEGACY_MIGRATOR,
+                user_id as u32,
+                false,
+            )
+        })
+        .context("In add_or_remove_user: Trying to delete keys from db.")
+    }
+
+    fn clear_namespace(domain: Domain, nspace: i64) -> Result<()> {
+        // Permission check. Must return on error. Do not touch the '?'.
+        check_keystore_permission(KeystorePerm::clear_uid()).context("In clear_namespace.")?;
+
+        LEGACY_MIGRATOR
+            .bulk_delete_uid(domain, nspace)
+            .context("In clear_namespace: Trying to delete legacy keys.")?;
+        DB.with(|db| db.borrow_mut().unbind_keys_for_namespace(domain, nspace))
+            .context("In clear_namespace: Trying to delete keys from db.")
+    }
+
+    fn get_state(user_id: i32) -> Result<AidlUserState> {
+        // Check permission. Function should return if this failed. Therefore having '?' at the end
+        // is very important.
+        check_keystore_permission(KeystorePerm::get_state()).context("In get_state.")?;
+        let state = DB
+            .with(|db| {
+                UserState::get(&mut db.borrow_mut(), &LEGACY_MIGRATOR, &SUPER_KEY, user_id as u32)
+            })
+            .context("In get_state. Trying to get UserState.")?;
+
+        match state {
+            UserState::Uninitialized => Ok(AidlUserState::UNINITIALIZED),
+            UserState::LskfUnlocked(_) => Ok(AidlUserState::LSKF_UNLOCKED),
+            UserState::LskfLocked => Ok(AidlUserState::LSKF_LOCKED),
+        }
+    }
+
+    fn early_boot_ended_help(sec_level: SecurityLevel) -> Result<()> {
+        let (dev, _, _) = get_keymint_device(&sec_level)
+            .context("In early_boot_ended: getting keymint device")?;
+        let km_dev: Strong<dyn IKeyMintDevice> =
+            dev.get_interface().context("In early_boot_ended: getting keymint device interface")?;
+
+        let _wp = wd::watch_millis_with(
+            "In early_boot_ended_help: calling earlyBootEnded()",
+            500,
+            move || format!("Seclevel: {:?}", sec_level),
+        );
+        map_km_error(km_dev.earlyBootEnded())
+            .context("In keymint device: calling earlyBootEnded")?;
+        Ok(())
+    }
+
+    fn early_boot_ended() -> Result<()> {
+        check_keystore_permission(KeystorePerm::early_boot_ended())
+            .context("In early_boot_ended. Checking permission")?;
+        log::info!("In early_boot_ended.");
+
+        if let Err(e) = DB.with(|db| SUPER_KEY.set_up_boot_level_cache(&mut db.borrow_mut())) {
+            log::error!("SUPER_KEY.set_up_boot_level_cache failed:\n{:?}\n:(", e);
+        }
+
+        let sec_levels = [
+            (SecurityLevel::TRUSTED_ENVIRONMENT, "TRUSTED_ENVIRONMENT"),
+            (SecurityLevel::STRONGBOX, "STRONGBOX"),
+        ];
+        sec_levels.iter().fold(Ok(()), |result, (sec_level, sec_level_string)| {
+            let curr_result = Maintenance::early_boot_ended_help(*sec_level);
+            if curr_result.is_err() {
+                log::error!(
+                    "Call to earlyBootEnded failed for security level {}.",
+                    &sec_level_string
+                );
+            }
+            result.and(curr_result)
+        })
+    }
+
+    fn on_device_off_body() -> Result<()> {
+        // Security critical permission check. This statement must return on fail.
+        check_keystore_permission(KeystorePerm::report_off_body())
+            .context("In on_device_off_body.")?;
+
+        DB.with(|db| db.borrow_mut().update_last_off_body(MonotonicRawTime::now()))
+            .context("In on_device_off_body: Trying to update last off body time.")
+    }
+
+    fn migrate_key_namespace(source: &KeyDescriptor, destination: &KeyDescriptor) -> Result<()> {
+        let caller_uid = ThreadState::get_calling_uid();
+
+        DB.with(|db| {
+            let key_id_guard = match source.domain {
+                Domain::APP | Domain::SELINUX | Domain::KEY_ID => {
+                    let (key_id_guard, _) = LEGACY_MIGRATOR
+                        .with_try_migrate(&source, caller_uid, || {
+                            db.borrow_mut().load_key_entry(
+                                &source,
+                                KeyType::Client,
+                                KeyEntryLoadBits::NONE,
+                                caller_uid,
+                                |k, av| {
+                                    check_key_permission(KeyPerm::use_(), k, &av)?;
+                                    check_key_permission(KeyPerm::delete(), k, &av)?;
+                                    check_key_permission(KeyPerm::grant(), k, &av)
+                                },
+                            )
+                        })
+                        .context("In migrate_key_namespace: Failed to load key blob.")?;
+                    key_id_guard
+                }
+                _ => {
+                    return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(concat!(
+                        "In migrate_key_namespace: ",
+                        "Source domain must be one of APP, SELINUX, or KEY_ID."
+                    ))
+                }
+            };
+
+            db.borrow_mut().migrate_key_namespace(key_id_guard, destination, caller_uid, |k| {
+                check_key_permission(KeyPerm::rebind(), k, &None)
+            })
+        })
+    }
+}
+
+impl Interface for Maintenance {}
+
+impl IKeystoreMaintenance for Maintenance {
+    fn onUserPasswordChanged(&self, user_id: i32, password: Option<&[u8]>) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::onUserPasswordChanged", 500);
+        map_or_log_err(Self::on_user_password_changed(user_id, password.map(|pw| pw.into())), Ok)
+    }
+
+    fn onUserAdded(&self, user_id: i32) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::onUserAdded", 500);
+        map_or_log_err(Self::add_or_remove_user(user_id), Ok)
+    }
+
+    fn onUserRemoved(&self, user_id: i32) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::onUserRemoved", 500);
+        map_or_log_err(Self::add_or_remove_user(user_id), Ok)
+    }
+
+    fn clearNamespace(&self, domain: Domain, nspace: i64) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::clearNamespace", 500);
+        map_or_log_err(Self::clear_namespace(domain, nspace), Ok)
+    }
+
+    fn getState(&self, user_id: i32) -> BinderResult<AidlUserState> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::getState", 500);
+        map_or_log_err(Self::get_state(user_id), Ok)
+    }
+
+    fn earlyBootEnded(&self) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::earlyBootEnded", 500);
+        map_or_log_err(Self::early_boot_ended(), Ok)
+    }
+
+    fn onDeviceOffBody(&self) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::onDeviceOffBody", 500);
+        map_or_log_err(Self::on_device_off_body(), Ok)
+    }
+
+    fn migrateKeyNamespace(
+        &self,
+        source: &KeyDescriptor,
+        destination: &KeyDescriptor,
+    ) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::migrateKeyNamespace", 500);
+        map_or_log_err(Self::migrate_key_namespace(source, destination), Ok)
+    }
+}
diff --git a/keystore2/src/metrics.rs b/keystore2/src/metrics.rs
new file mode 100644
index 0000000..07c3d64
--- /dev/null
+++ b/keystore2/src/metrics.rs
@@ -0,0 +1,507 @@
+// Copyright 2021, 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.
+
+//! This module provides convenience functions for keystore2 logging.
+use crate::error::get_error_code;
+use crate::globals::{DB, LOGS_HANDLER};
+use crate::key_parameter::KeyParameterValue as KsKeyParamValue;
+use crate::operation::Outcome;
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
+    HardwareAuthenticatorType::HardwareAuthenticatorType, KeyOrigin::KeyOrigin,
+    KeyParameter::KeyParameter, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
+    SecurityLevel::SecurityLevel,
+};
+use anyhow::Result;
+use keystore2_system_property::PropertyWatcher;
+use statslog_rust::{
+    keystore2_key_creation_event_reported::{
+        Algorithm as StatsdAlgorithm, EcCurve as StatsdEcCurve, KeyOrigin as StatsdKeyOrigin,
+        Keystore2KeyCreationEventReported, SecurityLevel as StatsdKeyCreationSecurityLevel,
+        UserAuthType as StatsdUserAuthType,
+    },
+    keystore2_key_operation_event_reported::{
+        Keystore2KeyOperationEventReported, Outcome as StatsdOutcome, Purpose as StatsdKeyPurpose,
+        SecurityLevel as StatsdKeyOperationSecurityLevel,
+    },
+    keystore2_storage_stats::StorageType as StatsdStorageType,
+};
+use statslog_rust_header::Atoms;
+use statspull_rust::{set_pull_atom_callback, StatsPullResult};
+
+fn create_default_key_creation_atom() -> Keystore2KeyCreationEventReported {
+    // If a value is not present, fields represented by bitmaps and i32 fields
+    // will take 0, except error_code which defaults to 1 indicating NO_ERROR and key_size,
+    // and auth_time_out which default to -1.
+    // The boolean fields are set to false by default.
+    // Some keymint enums do have 0 as an enum variant value. In such cases, the corresponding
+    // enum variant value in atoms.proto is incremented by 1, in order to have 0 as the reserved
+    // value for unspecified fields.
+    Keystore2KeyCreationEventReported {
+        algorithm: StatsdAlgorithm::AlgorithmUnspecified,
+        key_size: -1,
+        key_origin: StatsdKeyOrigin::OriginUnspecified,
+        user_auth_type: StatsdUserAuthType::AuthTypeUnspecified,
+        user_auth_key_timeout_seconds: -1,
+        padding_mode_bitmap: 0,
+        digest_bitmap: 0,
+        block_mode_bitmap: 0,
+        purpose_bitmap: 0,
+        ec_curve: StatsdEcCurve::EcCurveUnspecified,
+        // as per keystore2/ResponseCode.aidl, 1 is reserved for NO_ERROR
+        error_code: 1,
+        attestation_requested: false,
+        security_level: StatsdKeyCreationSecurityLevel::SecurityLevelUnspecified,
+    }
+}
+
+fn create_default_key_operation_atom() -> Keystore2KeyOperationEventReported {
+    Keystore2KeyOperationEventReported {
+        purpose: StatsdKeyPurpose::KeyPurposeUnspecified,
+        padding_mode_bitmap: 0,
+        digest_bitmap: 0,
+        block_mode_bitmap: 0,
+        outcome: StatsdOutcome::OutcomeUnspecified,
+        error_code: 1,
+        key_upgraded: false,
+        security_level: StatsdKeyOperationSecurityLevel::SecurityLevelUnspecified,
+    }
+}
+
+/// Log key creation events via statsd API.
+pub fn log_key_creation_event_stats<U>(
+    sec_level: SecurityLevel,
+    key_params: &[KeyParameter],
+    result: &Result<U>,
+) {
+    let key_creation_event_stats =
+        construct_key_creation_event_stats(sec_level, key_params, result);
+
+    LOGS_HANDLER.queue_lo(move |_| {
+        let logging_result = key_creation_event_stats.stats_write();
+
+        if let Err(e) = logging_result {
+            log::error!("Error in logging key creation event in the async task. {:?}", e);
+        }
+    });
+}
+
+/// Log key operation events via statsd API.
+pub fn log_key_operation_event_stats(
+    sec_level: SecurityLevel,
+    key_purpose: KeyPurpose,
+    op_params: &[KeyParameter],
+    op_outcome: &Outcome,
+    key_upgraded: bool,
+) {
+    let key_operation_event_stats = construct_key_operation_event_stats(
+        sec_level,
+        key_purpose,
+        op_params,
+        op_outcome,
+        key_upgraded,
+    );
+
+    LOGS_HANDLER.queue_lo(move |_| {
+        let logging_result = key_operation_event_stats.stats_write();
+
+        if let Err(e) = logging_result {
+            log::error!("Error in logging key operation event in the async task. {:?}", e);
+        }
+    });
+}
+
+fn construct_key_creation_event_stats<U>(
+    sec_level: SecurityLevel,
+    key_params: &[KeyParameter],
+    result: &Result<U>,
+) -> Keystore2KeyCreationEventReported {
+    let mut key_creation_event_atom = create_default_key_creation_atom();
+
+    if let Err(ref e) = result {
+        key_creation_event_atom.error_code = get_error_code(e);
+    }
+
+    key_creation_event_atom.security_level = match sec_level {
+        SecurityLevel::SOFTWARE => StatsdKeyCreationSecurityLevel::SecurityLevelSoftware,
+        SecurityLevel::TRUSTED_ENVIRONMENT => {
+            StatsdKeyCreationSecurityLevel::SecurityLevelTrustedEnvironment
+        }
+        SecurityLevel::STRONGBOX => StatsdKeyCreationSecurityLevel::SecurityLevelStrongbox,
+        //KEYSTORE is not a valid variant here
+        _ => StatsdKeyCreationSecurityLevel::SecurityLevelUnspecified,
+    };
+
+    for key_param in key_params.iter().map(KsKeyParamValue::from) {
+        match key_param {
+            KsKeyParamValue::Algorithm(a) => {
+                key_creation_event_atom.algorithm = match a {
+                    Algorithm::RSA => StatsdAlgorithm::Rsa,
+                    Algorithm::EC => StatsdAlgorithm::Ec,
+                    Algorithm::AES => StatsdAlgorithm::Aes,
+                    Algorithm::TRIPLE_DES => StatsdAlgorithm::TripleDes,
+                    Algorithm::HMAC => StatsdAlgorithm::Hmac,
+                    _ => StatsdAlgorithm::AlgorithmUnspecified,
+                }
+            }
+            KsKeyParamValue::KeySize(s) => {
+                key_creation_event_atom.key_size = s;
+            }
+            KsKeyParamValue::KeyOrigin(o) => {
+                key_creation_event_atom.key_origin = match o {
+                    KeyOrigin::GENERATED => StatsdKeyOrigin::Generated,
+                    KeyOrigin::DERIVED => StatsdKeyOrigin::Derived,
+                    KeyOrigin::IMPORTED => StatsdKeyOrigin::Imported,
+                    KeyOrigin::RESERVED => StatsdKeyOrigin::Reserved,
+                    KeyOrigin::SECURELY_IMPORTED => StatsdKeyOrigin::SecurelyImported,
+                    _ => StatsdKeyOrigin::OriginUnspecified,
+                }
+            }
+            KsKeyParamValue::HardwareAuthenticatorType(a) => {
+                key_creation_event_atom.user_auth_type = match a {
+                    HardwareAuthenticatorType::NONE => StatsdUserAuthType::None,
+                    HardwareAuthenticatorType::PASSWORD => StatsdUserAuthType::Password,
+                    HardwareAuthenticatorType::FINGERPRINT => StatsdUserAuthType::Fingerprint,
+                    HardwareAuthenticatorType::ANY => StatsdUserAuthType::Any,
+                    _ => StatsdUserAuthType::AuthTypeUnspecified,
+                }
+            }
+            KsKeyParamValue::AuthTimeout(t) => {
+                key_creation_event_atom.user_auth_key_timeout_seconds = t;
+            }
+            KsKeyParamValue::PaddingMode(p) => {
+                key_creation_event_atom.padding_mode_bitmap =
+                    compute_padding_mode_bitmap(&key_creation_event_atom.padding_mode_bitmap, p);
+            }
+            KsKeyParamValue::Digest(d) => {
+                key_creation_event_atom.digest_bitmap =
+                    compute_digest_bitmap(&key_creation_event_atom.digest_bitmap, d);
+            }
+            KsKeyParamValue::BlockMode(b) => {
+                key_creation_event_atom.block_mode_bitmap =
+                    compute_block_mode_bitmap(&key_creation_event_atom.block_mode_bitmap, b);
+            }
+            KsKeyParamValue::KeyPurpose(k) => {
+                key_creation_event_atom.purpose_bitmap =
+                    compute_purpose_bitmap(&key_creation_event_atom.purpose_bitmap, k);
+            }
+            KsKeyParamValue::EcCurve(e) => {
+                key_creation_event_atom.ec_curve = match e {
+                    EcCurve::P_224 => StatsdEcCurve::P224,
+                    EcCurve::P_256 => StatsdEcCurve::P256,
+                    EcCurve::P_384 => StatsdEcCurve::P384,
+                    EcCurve::P_521 => StatsdEcCurve::P521,
+                    _ => StatsdEcCurve::EcCurveUnspecified,
+                }
+            }
+            KsKeyParamValue::AttestationChallenge(_) => {
+                key_creation_event_atom.attestation_requested = true;
+            }
+            _ => {}
+        }
+    }
+    key_creation_event_atom
+}
+
+fn construct_key_operation_event_stats(
+    sec_level: SecurityLevel,
+    key_purpose: KeyPurpose,
+    op_params: &[KeyParameter],
+    op_outcome: &Outcome,
+    key_upgraded: bool,
+) -> Keystore2KeyOperationEventReported {
+    let mut key_operation_event_atom = create_default_key_operation_atom();
+
+    key_operation_event_atom.security_level = match sec_level {
+        SecurityLevel::SOFTWARE => StatsdKeyOperationSecurityLevel::SecurityLevelSoftware,
+        SecurityLevel::TRUSTED_ENVIRONMENT => {
+            StatsdKeyOperationSecurityLevel::SecurityLevelTrustedEnvironment
+        }
+        SecurityLevel::STRONGBOX => StatsdKeyOperationSecurityLevel::SecurityLevelStrongbox,
+        //KEYSTORE is not a valid variant here
+        _ => StatsdKeyOperationSecurityLevel::SecurityLevelUnspecified,
+    };
+
+    key_operation_event_atom.key_upgraded = key_upgraded;
+
+    key_operation_event_atom.purpose = match key_purpose {
+        KeyPurpose::ENCRYPT => StatsdKeyPurpose::Encrypt,
+        KeyPurpose::DECRYPT => StatsdKeyPurpose::Decrypt,
+        KeyPurpose::SIGN => StatsdKeyPurpose::Sign,
+        KeyPurpose::VERIFY => StatsdKeyPurpose::Verify,
+        KeyPurpose::WRAP_KEY => StatsdKeyPurpose::WrapKey,
+        KeyPurpose::AGREE_KEY => StatsdKeyPurpose::AgreeKey,
+        KeyPurpose::ATTEST_KEY => StatsdKeyPurpose::AttestKey,
+        _ => StatsdKeyPurpose::KeyPurposeUnspecified,
+    };
+
+    key_operation_event_atom.outcome = match op_outcome {
+        Outcome::Unknown | Outcome::Dropped => StatsdOutcome::Dropped,
+        Outcome::Success => StatsdOutcome::Success,
+        Outcome::Abort => StatsdOutcome::Abort,
+        Outcome::Pruned => StatsdOutcome::Pruned,
+        Outcome::ErrorCode(e) => {
+            key_operation_event_atom.error_code = e.0;
+            StatsdOutcome::Error
+        }
+    };
+
+    for key_param in op_params.iter().map(KsKeyParamValue::from) {
+        match key_param {
+            KsKeyParamValue::PaddingMode(p) => {
+                key_operation_event_atom.padding_mode_bitmap =
+                    compute_padding_mode_bitmap(&key_operation_event_atom.padding_mode_bitmap, p);
+            }
+            KsKeyParamValue::Digest(d) => {
+                key_operation_event_atom.digest_bitmap =
+                    compute_digest_bitmap(&key_operation_event_atom.digest_bitmap, d);
+            }
+            KsKeyParamValue::BlockMode(b) => {
+                key_operation_event_atom.block_mode_bitmap =
+                    compute_block_mode_bitmap(&key_operation_event_atom.block_mode_bitmap, b);
+            }
+            _ => {}
+        }
+    }
+
+    key_operation_event_atom
+}
+
+fn compute_purpose_bitmap(purpose_bitmap: &i32, purpose: KeyPurpose) -> i32 {
+    let mut bitmap = *purpose_bitmap;
+    match purpose {
+        KeyPurpose::ENCRYPT => {
+            bitmap |= 1 << KeyPurposeBitPosition::ENCRYPT_BIT_POS as i32;
+        }
+        KeyPurpose::DECRYPT => {
+            bitmap |= 1 << KeyPurposeBitPosition::DECRYPT_BIT_POS as i32;
+        }
+        KeyPurpose::SIGN => {
+            bitmap |= 1 << KeyPurposeBitPosition::SIGN_BIT_POS as i32;
+        }
+        KeyPurpose::VERIFY => {
+            bitmap |= 1 << KeyPurposeBitPosition::VERIFY_BIT_POS as i32;
+        }
+        KeyPurpose::WRAP_KEY => {
+            bitmap |= 1 << KeyPurposeBitPosition::WRAP_KEY_BIT_POS as i32;
+        }
+        KeyPurpose::AGREE_KEY => {
+            bitmap |= 1 << KeyPurposeBitPosition::AGREE_KEY_BIT_POS as i32;
+        }
+        KeyPurpose::ATTEST_KEY => {
+            bitmap |= 1 << KeyPurposeBitPosition::ATTEST_KEY_BIT_POS as i32;
+        }
+        _ => {}
+    }
+    bitmap
+}
+
+fn compute_padding_mode_bitmap(padding_mode_bitmap: &i32, padding_mode: PaddingMode) -> i32 {
+    let mut bitmap = *padding_mode_bitmap;
+    match padding_mode {
+        PaddingMode::NONE => {
+            bitmap |= 1 << PaddingModeBitPosition::NONE_BIT_POSITION as i32;
+        }
+        PaddingMode::RSA_OAEP => {
+            bitmap |= 1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS as i32;
+        }
+        PaddingMode::RSA_PSS => {
+            bitmap |= 1 << PaddingModeBitPosition::RSA_PSS_BIT_POS as i32;
+        }
+        PaddingMode::RSA_PKCS1_1_5_ENCRYPT => {
+            bitmap |= 1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS as i32;
+        }
+        PaddingMode::RSA_PKCS1_1_5_SIGN => {
+            bitmap |= 1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS as i32;
+        }
+        PaddingMode::PKCS7 => {
+            bitmap |= 1 << PaddingModeBitPosition::PKCS7_BIT_POS as i32;
+        }
+        _ => {}
+    }
+    bitmap
+}
+
+fn compute_digest_bitmap(digest_bitmap: &i32, digest: Digest) -> i32 {
+    let mut bitmap = *digest_bitmap;
+    match digest {
+        Digest::NONE => {
+            bitmap |= 1 << DigestBitPosition::NONE_BIT_POSITION as i32;
+        }
+        Digest::MD5 => {
+            bitmap |= 1 << DigestBitPosition::MD5_BIT_POS as i32;
+        }
+        Digest::SHA1 => {
+            bitmap |= 1 << DigestBitPosition::SHA_1_BIT_POS as i32;
+        }
+        Digest::SHA_2_224 => {
+            bitmap |= 1 << DigestBitPosition::SHA_2_224_BIT_POS as i32;
+        }
+        Digest::SHA_2_256 => {
+            bitmap |= 1 << DigestBitPosition::SHA_2_256_BIT_POS as i32;
+        }
+        Digest::SHA_2_384 => {
+            bitmap |= 1 << DigestBitPosition::SHA_2_384_BIT_POS as i32;
+        }
+        Digest::SHA_2_512 => {
+            bitmap |= 1 << DigestBitPosition::SHA_2_512_BIT_POS as i32;
+        }
+        _ => {}
+    }
+    bitmap
+}
+
+fn compute_block_mode_bitmap(block_mode_bitmap: &i32, block_mode: BlockMode) -> i32 {
+    let mut bitmap = *block_mode_bitmap;
+    match block_mode {
+        BlockMode::ECB => {
+            bitmap |= 1 << BlockModeBitPosition::ECB_BIT_POS as i32;
+        }
+        BlockMode::CBC => {
+            bitmap |= 1 << BlockModeBitPosition::CBC_BIT_POS as i32;
+        }
+        BlockMode::CTR => {
+            bitmap |= 1 << BlockModeBitPosition::CTR_BIT_POS as i32;
+        }
+        BlockMode::GCM => {
+            bitmap |= 1 << BlockModeBitPosition::GCM_BIT_POS as i32;
+        }
+        _ => {}
+    }
+    bitmap
+}
+
+/// Registers pull metrics callbacks
+pub fn register_pull_metrics_callbacks() -> Result<()> {
+    // Before registering the callbacks with statsd, we have to wait for the system to finish
+    // booting up. This avoids possible races that may occur at startup. For example, statsd
+    // depends on a companion service, and if registration happens too soon it will fail since
+    // the companion service isn't up yet.
+    let mut watcher = PropertyWatcher::new("sys.boot_completed")?;
+    loop {
+        watcher.wait()?;
+        let value = watcher.read(|_name, value| Ok(value.trim().to_string()));
+        if value? == "1" {
+            set_pull_atom_callback(Atoms::Keystore2StorageStats, None, pull_metrics_callback);
+            break;
+        }
+    }
+    Ok(())
+}
+
+fn pull_metrics_callback() -> StatsPullResult {
+    let mut result = StatsPullResult::new();
+    let mut append = |stat| {
+        match stat {
+            Ok(s) => result.push(Box::new(s)),
+            Err(error) => {
+                log::error!("pull_metrics_callback: Error getting storage stat: {}", error)
+            }
+        };
+    };
+    DB.with(|db| {
+        let mut db = db.borrow_mut();
+        append(db.get_storage_stat(StatsdStorageType::Database));
+        append(db.get_storage_stat(StatsdStorageType::KeyEntry));
+        append(db.get_storage_stat(StatsdStorageType::KeyEntryIdIndex));
+        append(db.get_storage_stat(StatsdStorageType::KeyEntryDomainNamespaceIndex));
+        append(db.get_storage_stat(StatsdStorageType::BlobEntry));
+        append(db.get_storage_stat(StatsdStorageType::BlobEntryKeyEntryIdIndex));
+        append(db.get_storage_stat(StatsdStorageType::KeyParameter));
+        append(db.get_storage_stat(StatsdStorageType::KeyParameterKeyEntryIdIndex));
+        append(db.get_storage_stat(StatsdStorageType::KeyMetadata));
+        append(db.get_storage_stat(StatsdStorageType::KeyMetadataKeyEntryIdIndex));
+        append(db.get_storage_stat(StatsdStorageType::Grant));
+        append(db.get_storage_stat(StatsdStorageType::AuthToken));
+        append(db.get_storage_stat(StatsdStorageType::BlobMetadata));
+        append(db.get_storage_stat(StatsdStorageType::BlobMetadataBlobEntryIdIndex));
+    });
+    result
+}
+
+/// Enum defining the bit position for each padding mode. Since padding mode can be repeatable, it
+/// is represented using a bitmap.
+#[allow(non_camel_case_types)]
+#[repr(i32)]
+pub enum PaddingModeBitPosition {
+    ///Bit position in the PaddingMode bitmap for NONE.
+    NONE_BIT_POSITION = 0,
+    ///Bit position in the PaddingMode bitmap for RSA_OAEP.
+    RSA_OAEP_BIT_POS = 1,
+    ///Bit position in the PaddingMode bitmap for RSA_PSS.
+    RSA_PSS_BIT_POS = 2,
+    ///Bit position in the PaddingMode bitmap for RSA_PKCS1_1_5_ENCRYPT.
+    RSA_PKCS1_1_5_ENCRYPT_BIT_POS = 3,
+    ///Bit position in the PaddingMode bitmap for RSA_PKCS1_1_5_SIGN.
+    RSA_PKCS1_1_5_SIGN_BIT_POS = 4,
+    ///Bit position in the PaddingMode bitmap for RSA_PKCS7.
+    PKCS7_BIT_POS = 5,
+}
+
+/// Enum defining the bit position for each digest type. Since digest can be repeatable in
+/// key parameters, it is represented using a bitmap.
+#[allow(non_camel_case_types)]
+#[repr(i32)]
+pub enum DigestBitPosition {
+    ///Bit position in the Digest bitmap for NONE.
+    NONE_BIT_POSITION = 0,
+    ///Bit position in the Digest bitmap for MD5.
+    MD5_BIT_POS = 1,
+    ///Bit position in the Digest bitmap for SHA1.
+    SHA_1_BIT_POS = 2,
+    ///Bit position in the Digest bitmap for SHA_2_224.
+    SHA_2_224_BIT_POS = 3,
+    ///Bit position in the Digest bitmap for SHA_2_256.
+    SHA_2_256_BIT_POS = 4,
+    ///Bit position in the Digest bitmap for SHA_2_384.
+    SHA_2_384_BIT_POS = 5,
+    ///Bit position in the Digest bitmap for SHA_2_512.
+    SHA_2_512_BIT_POS = 6,
+}
+
+/// Enum defining the bit position for each block mode type. Since block mode can be repeatable in
+/// key parameters, it is represented using a bitmap.
+#[allow(non_camel_case_types)]
+#[repr(i32)]
+enum BlockModeBitPosition {
+    ///Bit position in the BlockMode bitmap for ECB.
+    ECB_BIT_POS = 1,
+    ///Bit position in the BlockMode bitmap for CBC.
+    CBC_BIT_POS = 2,
+    ///Bit position in the BlockMode bitmap for CTR.
+    CTR_BIT_POS = 3,
+    ///Bit position in the BlockMode bitmap for GCM.
+    GCM_BIT_POS = 4,
+}
+
+/// Enum defining the bit position for each key purpose. Since key purpose can be repeatable in
+/// key parameters, it is represented using a bitmap.
+#[allow(non_camel_case_types)]
+#[repr(i32)]
+enum KeyPurposeBitPosition {
+    ///Bit position in the KeyPurpose bitmap for Encrypt.
+    ENCRYPT_BIT_POS = 1,
+    ///Bit position in the KeyPurpose bitmap for Decrypt.
+    DECRYPT_BIT_POS = 2,
+    ///Bit position in the KeyPurpose bitmap for Sign.
+    SIGN_BIT_POS = 3,
+    ///Bit position in the KeyPurpose bitmap for Verify.
+    VERIFY_BIT_POS = 4,
+    ///Bit position in the KeyPurpose bitmap for Wrap Key.
+    WRAP_KEY_BIT_POS = 5,
+    ///Bit position in the KeyPurpose bitmap for Agree Key.
+    AGREE_KEY_BIT_POS = 6,
+    ///Bit position in the KeyPurpose bitmap for Attest Key.
+    ATTEST_KEY_BIT_POS = 7,
+}
diff --git a/keystore2/src/operation.rs b/keystore2/src/operation.rs
new file mode 100644
index 0000000..8d7ad0a
--- /dev/null
+++ b/keystore2/src/operation.rs
@@ -0,0 +1,900 @@
+// Copyright 2020, 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.
+
+//! This crate implements the `IKeystoreOperation` AIDL interface, which represents
+//! an ongoing key operation, as well as the operation database, which is mainly
+//! required for tracking operations for the purpose of pruning.
+//! This crate also implements an operation pruning strategy.
+//!
+//! Operations implement the API calls update, finish, and abort.
+//! Additionally, an operation can be dropped and pruned. The former
+//! happens if the client deletes a binder to the operation object.
+//! An existing operation may get pruned when running out of operation
+//! slots and a new operation takes precedence.
+//!
+//! ## Operation Lifecycle
+//! An operation gets created when the client calls `IKeystoreSecurityLevel::create`.
+//! It may receive zero or more update request. The lifecycle ends when:
+//!  * `update` yields an error.
+//!  * `finish` is called.
+//!  * `abort` is called.
+//!  * The operation gets dropped.
+//!  * The operation gets pruned.
+//! `Operation` has an `Outcome` member. While the outcome is `Outcome::Unknown`,
+//! the operation is active and in a good state. Any of the above conditions may
+//! change the outcome to one of the defined outcomes Success, Abort, Dropped,
+//! Pruned, or ErrorCode. The latter is chosen in the case of an unexpected error, during
+//! `update` or `finish`. `Success` is chosen iff `finish` completes without error.
+//! Note that all operations get dropped eventually in the sense that they lose
+//! their last reference and get destroyed. At that point, the fate of the operation
+//! gets logged. However, an operation will transition to `Outcome::Dropped` iff
+//! the operation was still active (`Outcome::Unknown`) at that time.
+//!
+//! ## Operation Dropping
+//! To observe the dropping of an operation, we have to make sure that there
+//! are no strong references to the IBinder representing this operation.
+//! This would be simple enough if the operation object would need to be accessed
+//! only by transactions. But to perform pruning, we have to retain a reference to the
+//! original operation object.
+//!
+//! ## Operation Pruning
+//! Pruning an operation happens during the creation of a new operation.
+//! We have to iterate through the operation database to find a suitable
+//! candidate. Then we abort and finalize this operation setting its outcome to
+//! `Outcome::Pruned`. The corresponding KeyMint operation slot will have been freed
+//! up at this point, but the `Operation` object lingers. When the client
+//! attempts to use the operation again they will receive
+//! ErrorCode::INVALID_OPERATION_HANDLE indicating that the operation no longer
+//! exits. This should be the cue for the client to destroy its binder.
+//! At that point the operation gets dropped.
+//!
+//! ## Architecture
+//! The `IKeystoreOperation` trait is implemented by `KeystoreOperation`.
+//! This acts as a proxy object holding a strong reference to actual operation
+//! implementation `Operation`.
+//!
+//! ```
+//! struct KeystoreOperation {
+//!     operation: Mutex<Option<Arc<Operation>>>,
+//! }
+//! ```
+//!
+//! The `Mutex` serves two purposes. It provides interior mutability allowing
+//! us to set the Option to None. We do this when the life cycle ends during
+//! a call to `update`, `finish`, or `abort`. As a result most of the Operation
+//! related resources are freed. The `KeystoreOperation` proxy object still
+//! lingers until dropped by the client.
+//! The second purpose is to protect operations against concurrent usage.
+//! Failing to lock this mutex yields `ResponseCode::OPERATION_BUSY` and indicates
+//! a programming error in the client.
+//!
+//! Note that the Mutex only protects the operation against concurrent client calls.
+//! We still retain weak references to the operation in the operation database:
+//!
+//! ```
+//! struct OperationDb {
+//!     operations: Mutex<Vec<Weak<Operation>>>
+//! }
+//! ```
+//!
+//! This allows us to access the operations for the purpose of pruning.
+//! We do this in three phases.
+//!  1. We gather the pruning information. Besides non mutable information,
+//!     we access `last_usage` which is protected by a mutex.
+//!     We only lock this mutex for single statements at a time. During
+//!     this phase we hold the operation db lock.
+//!  2. We choose a pruning candidate by computing the pruning resistance
+//!     of each operation. We do this entirely with information we now
+//!     have on the stack without holding any locks.
+//!     (See `OperationDb::prune` for more details on the pruning strategy.)
+//!  3. During pruning we briefly lock the operation database again to get the
+//!     the pruning candidate by index. We then attempt to abort the candidate.
+//!     If the candidate was touched in the meantime or is currently fulfilling
+//!     a request (i.e., the client calls update, finish, or abort),
+//!     we go back to 1 and try again.
+//!
+//! So the outer Mutex in `KeystoreOperation::operation` only protects
+//! operations against concurrent client calls but not against concurrent
+//! pruning attempts. This is what the `Operation::outcome` mutex is used for.
+//!
+//! ```
+//! struct Operation {
+//!     ...
+//!     outcome: Mutex<Outcome>,
+//!     ...
+//! }
+//! ```
+//!
+//! Any request that can change the outcome, i.e., `update`, `finish`, `abort`,
+//! `drop`, and `prune` has to take the outcome lock and check if the outcome
+//! is still `Outcome::Unknown` before entering. `prune` is special in that
+//! it will `try_lock`, because we don't want to be blocked on a potentially
+//! long running request at another operation. If it fails to get the lock
+//! the operation is either being touched, which changes its pruning resistance,
+//! or it transitions to its end-of-life, which means we may get a free slot.
+//! Either way, we have to revaluate the pruning scores.
+
+use crate::enforcements::AuthInfo;
+use crate::error::{map_err_with, map_km_error, map_or_log_err, Error, ErrorCode, ResponseCode};
+use crate::metrics::log_key_operation_event_stats;
+use crate::utils::{watchdog as wd, Asp};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    IKeyMintOperation::IKeyMintOperation, KeyParameter::KeyParameter, KeyPurpose::KeyPurpose,
+    SecurityLevel::SecurityLevel,
+};
+use android_hardware_security_keymint::binder::BinderFeatures;
+use android_system_keystore2::aidl::android::system::keystore2::{
+    IKeystoreOperation::BnKeystoreOperation, IKeystoreOperation::IKeystoreOperation,
+};
+use anyhow::{anyhow, Context, Result};
+use std::{
+    collections::HashMap,
+    sync::{Arc, Mutex, MutexGuard, Weak},
+    time::Duration,
+    time::Instant,
+};
+
+/// Operations have `Outcome::Unknown` as long as they are active. They transition
+/// to one of the other variants exactly once. The distinction in outcome is mainly
+/// for the statistic.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
+pub enum Outcome {
+    /// Operations have `Outcome::Unknown` as long as they are active.
+    Unknown,
+    /// Operation is successful.
+    Success,
+    /// Operation is aborted.
+    Abort,
+    /// Operation is dropped.
+    Dropped,
+    /// Operation is pruned.
+    Pruned,
+    /// Operation is failed with the error code.
+    ErrorCode(ErrorCode),
+}
+
+/// Operation bundles all of the operation related resources and tracks the operation's
+/// outcome.
+#[derive(Debug)]
+pub struct Operation {
+    // The index of this operation in the OperationDb.
+    index: usize,
+    km_op: Asp,
+    last_usage: Mutex<Instant>,
+    outcome: Mutex<Outcome>,
+    owner: u32, // Uid of the operation's owner.
+    auth_info: Mutex<AuthInfo>,
+    forced: bool,
+    logging_info: LoggingInfo,
+}
+
+/// Keeps track of the information required for logging operations.
+#[derive(Debug)]
+pub struct LoggingInfo {
+    sec_level: SecurityLevel,
+    purpose: KeyPurpose,
+    op_params: Vec<KeyParameter>,
+    key_upgraded: bool,
+}
+
+impl LoggingInfo {
+    /// Constructor
+    pub fn new(
+        sec_level: SecurityLevel,
+        purpose: KeyPurpose,
+        op_params: Vec<KeyParameter>,
+        key_upgraded: bool,
+    ) -> LoggingInfo {
+        Self { sec_level, purpose, op_params, key_upgraded }
+    }
+}
+
+struct PruningInfo {
+    last_usage: Instant,
+    owner: u32,
+    index: usize,
+    forced: bool,
+}
+
+// We don't except more than 32KiB of data in `update`, `updateAad`, and `finish`.
+const MAX_RECEIVE_DATA: usize = 0x8000;
+
+impl Operation {
+    /// Constructor
+    pub fn new(
+        index: usize,
+        km_op: binder::Strong<dyn IKeyMintOperation>,
+        owner: u32,
+        auth_info: AuthInfo,
+        forced: bool,
+        logging_info: LoggingInfo,
+    ) -> Self {
+        Self {
+            index,
+            km_op: Asp::new(km_op.as_binder()),
+            last_usage: Mutex::new(Instant::now()),
+            outcome: Mutex::new(Outcome::Unknown),
+            owner,
+            auth_info: Mutex::new(auth_info),
+            forced,
+            logging_info,
+        }
+    }
+
+    fn get_pruning_info(&self) -> Option<PruningInfo> {
+        // An operation may be finalized.
+        if let Ok(guard) = self.outcome.try_lock() {
+            match *guard {
+                Outcome::Unknown => {}
+                // If the outcome is any other than unknown, it has been finalized,
+                // and we can no longer consider it for pruning.
+                _ => return None,
+            }
+        }
+        // Else: If we could not grab the lock, this means that the operation is currently
+        //       being used and it may be transitioning to finalized or it was simply updated.
+        //       In any case it is fair game to consider it for pruning. If the operation
+        //       transitioned to a final state, we will notice when we attempt to prune, and
+        //       a subsequent attempt to create a new operation will succeed.
+        Some(PruningInfo {
+            // Expect safety:
+            // `last_usage` is locked only for primitive single line statements.
+            // There is no chance to panic and poison the mutex.
+            last_usage: *self.last_usage.lock().expect("In get_pruning_info."),
+            owner: self.owner,
+            index: self.index,
+            forced: self.forced,
+        })
+    }
+
+    fn prune(&self, last_usage: Instant) -> Result<(), Error> {
+        let mut locked_outcome = match self.outcome.try_lock() {
+            Ok(guard) => match *guard {
+                Outcome::Unknown => guard,
+                _ => return Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)),
+            },
+            Err(_) => return Err(Error::Rc(ResponseCode::OPERATION_BUSY)),
+        };
+
+        // In `OperationDb::prune`, which is our caller, we first gather the pruning
+        // information including the last usage. When we select a candidate
+        // we call `prune` on that candidate passing the last_usage
+        // that we gathered earlier. If the actual last usage
+        // has changed since than, it means the operation was busy in the
+        // meantime, which means that we have to reevaluate the pruning score.
+        //
+        // Expect safety:
+        // `last_usage` is locked only for primitive single line statements.
+        // There is no chance to panic and poison the mutex.
+        if *self.last_usage.lock().expect("In Operation::prune()") != last_usage {
+            return Err(Error::Rc(ResponseCode::OPERATION_BUSY));
+        }
+        *locked_outcome = Outcome::Pruned;
+
+        let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
+            match self.km_op.get_interface() {
+                Ok(km_op) => km_op,
+                Err(e) => {
+                    log::error!("In prune: Failed to get KeyMintOperation interface.\n    {:?}", e);
+                    return Err(Error::sys());
+                }
+            };
+
+        let _wp = wd::watch_millis("In Operation::prune: calling abort()", 500);
+
+        // We abort the operation. If there was an error we log it but ignore it.
+        if let Err(e) = map_km_error(km_op.abort()) {
+            log::error!("In prune: KeyMint::abort failed with {:?}.", e);
+        }
+
+        Ok(())
+    }
+
+    // This function takes a Result from a KeyMint call and inspects it for errors.
+    // If an error was found it updates the given `locked_outcome` accordingly.
+    // It forwards the Result unmodified.
+    // The precondition to this call must be *locked_outcome == Outcome::Unknown.
+    // Ideally the `locked_outcome` came from a successful call to `check_active`
+    // see below.
+    fn update_outcome<T>(
+        &self,
+        locked_outcome: &mut Outcome,
+        err: Result<T, Error>,
+    ) -> Result<T, Error> {
+        match &err {
+            Err(Error::Km(e)) => *locked_outcome = Outcome::ErrorCode(*e),
+            Err(_) => *locked_outcome = Outcome::ErrorCode(ErrorCode::UNKNOWN_ERROR),
+            Ok(_) => (),
+        }
+        err
+    }
+
+    // This function grabs the outcome lock and checks the current outcome state.
+    // If the outcome is still `Outcome::Unknown`, this function returns
+    // the locked outcome for further updates. In any other case it returns
+    // ErrorCode::INVALID_OPERATION_HANDLE indicating that this operation has
+    // been finalized and is no longer active.
+    fn check_active(&self) -> Result<MutexGuard<Outcome>> {
+        let guard = self.outcome.lock().expect("In check_active.");
+        match *guard {
+            Outcome::Unknown => Ok(guard),
+            _ => Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)).context(format!(
+                "In check_active: Call on finalized operation with outcome: {:?}.",
+                *guard
+            )),
+        }
+    }
+
+    // This function checks the amount of input data sent to us. We reject any buffer
+    // exceeding MAX_RECEIVE_DATA bytes as input to `update`, `update_aad`, and `finish`
+    // in order to force clients into using reasonable limits.
+    fn check_input_length(data: &[u8]) -> Result<()> {
+        if data.len() > MAX_RECEIVE_DATA {
+            // This error code is unique, no context required here.
+            return Err(anyhow!(Error::Rc(ResponseCode::TOO_MUCH_DATA)));
+        }
+        Ok(())
+    }
+
+    // Update the last usage to now.
+    fn touch(&self) {
+        // Expect safety:
+        // `last_usage` is locked only for primitive single line statements.
+        // There is no chance to panic and poison the mutex.
+        *self.last_usage.lock().expect("In touch.") = Instant::now();
+    }
+
+    /// Implementation of `IKeystoreOperation::updateAad`.
+    /// Refer to the AIDL spec at system/hardware/interfaces/keystore2 for details.
+    fn update_aad(&self, aad_input: &[u8]) -> Result<()> {
+        let mut outcome = self.check_active().context("In update_aad")?;
+        Self::check_input_length(aad_input).context("In update_aad")?;
+        self.touch();
+
+        let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
+            self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
+
+        let (hat, tst) = self
+            .auth_info
+            .lock()
+            .unwrap()
+            .before_update()
+            .context("In update_aad: Trying to get auth tokens.")?;
+
+        self.update_outcome(&mut *outcome, {
+            let _wp = wd::watch_millis("Operation::update_aad: calling updateAad", 500);
+            map_km_error(km_op.updateAad(aad_input, hat.as_ref(), tst.as_ref()))
+        })
+        .context("In update_aad: KeyMint::update failed.")?;
+
+        Ok(())
+    }
+
+    /// Implementation of `IKeystoreOperation::update`.
+    /// Refer to the AIDL spec at system/hardware/interfaces/keystore2 for details.
+    fn update(&self, input: &[u8]) -> Result<Option<Vec<u8>>> {
+        let mut outcome = self.check_active().context("In update")?;
+        Self::check_input_length(input).context("In update")?;
+        self.touch();
+
+        let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
+            self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
+
+        let (hat, tst) = self
+            .auth_info
+            .lock()
+            .unwrap()
+            .before_update()
+            .context("In update: Trying to get auth tokens.")?;
+
+        let output = self
+            .update_outcome(&mut *outcome, {
+                let _wp = wd::watch_millis("Operation::update: calling update", 500);
+                map_km_error(km_op.update(input, hat.as_ref(), tst.as_ref()))
+            })
+            .context("In update: KeyMint::update failed.")?;
+
+        if output.is_empty() {
+            Ok(None)
+        } else {
+            Ok(Some(output))
+        }
+    }
+
+    /// Implementation of `IKeystoreOperation::finish`.
+    /// Refer to the AIDL spec at system/hardware/interfaces/keystore2 for details.
+    fn finish(&self, input: Option<&[u8]>, signature: Option<&[u8]>) -> Result<Option<Vec<u8>>> {
+        let mut outcome = self.check_active().context("In finish")?;
+        if let Some(input) = input {
+            Self::check_input_length(input).context("In finish")?;
+        }
+        self.touch();
+
+        let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
+            self.km_op.get_interface().context("In finish: Failed to get KeyMintOperation.")?;
+
+        let (hat, tst, confirmation_token) = self
+            .auth_info
+            .lock()
+            .unwrap()
+            .before_finish()
+            .context("In finish: Trying to get auth tokens.")?;
+
+        let output = self
+            .update_outcome(&mut *outcome, {
+                let _wp = wd::watch_millis("Operation::finish: calling finish", 500);
+                map_km_error(km_op.finish(
+                    input,
+                    signature,
+                    hat.as_ref(),
+                    tst.as_ref(),
+                    confirmation_token.as_deref(),
+                ))
+            })
+            .context("In finish: KeyMint::finish failed.")?;
+
+        self.auth_info.lock().unwrap().after_finish().context("In finish.")?;
+
+        // At this point the operation concluded successfully.
+        *outcome = Outcome::Success;
+
+        if output.is_empty() {
+            Ok(None)
+        } else {
+            Ok(Some(output))
+        }
+    }
+
+    /// Aborts the operation if it is active. IFF the operation is aborted the outcome is
+    /// set to `outcome`. `outcome` must reflect the reason for the abort. Since the operation
+    /// gets aborted `outcome` must not be `Operation::Success` or `Operation::Unknown`.
+    fn abort(&self, outcome: Outcome) -> Result<()> {
+        let mut locked_outcome = self.check_active().context("In abort")?;
+        *locked_outcome = outcome;
+        let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
+            self.km_op.get_interface().context("In abort: Failed to get KeyMintOperation.")?;
+
+        {
+            let _wp = wd::watch_millis("Operation::abort: calling abort", 500);
+            map_km_error(km_op.abort()).context("In abort: KeyMint::abort failed.")
+        }
+    }
+}
+
+impl Drop for Operation {
+    fn drop(&mut self) {
+        let guard = self.outcome.lock().expect("In drop.");
+        log_key_operation_event_stats(
+            self.logging_info.sec_level,
+            self.logging_info.purpose,
+            &(self.logging_info.op_params),
+            &guard,
+            self.logging_info.key_upgraded,
+        );
+        if let Outcome::Unknown = *guard {
+            drop(guard);
+            // If the operation was still active we call abort, setting
+            // the outcome to `Outcome::Dropped`
+            if let Err(e) = self.abort(Outcome::Dropped) {
+                log::error!("While dropping Operation: abort failed:\n    {:?}", e);
+            }
+        }
+    }
+}
+
+/// The OperationDb holds weak references to all ongoing operations.
+/// Its main purpose is to facilitate operation pruning.
+#[derive(Debug, Default)]
+pub struct OperationDb {
+    // TODO replace Vec with WeakTable when the weak_table crate becomes
+    // available.
+    operations: Mutex<Vec<Weak<Operation>>>,
+}
+
+impl OperationDb {
+    /// Creates a new OperationDb.
+    pub fn new() -> Self {
+        Self { operations: Mutex::new(Vec::new()) }
+    }
+
+    /// Creates a new operation.
+    /// This function takes a KeyMint operation and an associated
+    /// owner uid and returns a new Operation wrapped in a `std::sync::Arc`.
+    pub fn create_operation(
+        &self,
+        km_op: binder::public_api::Strong<dyn IKeyMintOperation>,
+        owner: u32,
+        auth_info: AuthInfo,
+        forced: bool,
+        logging_info: LoggingInfo,
+    ) -> Arc<Operation> {
+        // We use unwrap because we don't allow code that can panic while locked.
+        let mut operations = self.operations.lock().expect("In create_operation.");
+
+        let mut index: usize = 0;
+        // First we iterate through the operation slots to try and find an unused
+        // slot. If we don't find one, we append the new entry instead.
+        match (*operations).iter_mut().find(|s| {
+            index += 1;
+            s.upgrade().is_none()
+        }) {
+            Some(free_slot) => {
+                let new_op = Arc::new(Operation::new(
+                    index - 1,
+                    km_op,
+                    owner,
+                    auth_info,
+                    forced,
+                    logging_info,
+                ));
+                *free_slot = Arc::downgrade(&new_op);
+                new_op
+            }
+            None => {
+                let new_op = Arc::new(Operation::new(
+                    operations.len(),
+                    km_op,
+                    owner,
+                    auth_info,
+                    forced,
+                    logging_info,
+                ));
+                operations.push(Arc::downgrade(&new_op));
+                new_op
+            }
+        }
+    }
+
+    fn get(&self, index: usize) -> Option<Arc<Operation>> {
+        self.operations.lock().expect("In OperationDb::get.").get(index).and_then(|op| op.upgrade())
+    }
+
+    /// Attempts to prune an operation.
+    ///
+    /// This function is used during operation creation, i.e., by
+    /// `KeystoreSecurityLevel::create_operation`, to try and free up an operation slot
+    /// if it got `ErrorCode::TOO_MANY_OPERATIONS` from the KeyMint backend. It is not
+    /// guaranteed that an operation slot is available after this call successfully
+    /// returned for various reasons. E.g., another thread may have snatched up the newly
+    /// available slot. Callers may have to call prune multiple times before they get a
+    /// free operation slot. Prune may also return `Err(Error::Rc(ResponseCode::BACKEND_BUSY))`
+    /// which indicates that no prunable operation was found.
+    ///
+    /// To find a suitable candidate we compute the malus for the caller and each existing
+    /// operation. The malus is the inverse of the pruning power (caller) or pruning
+    /// resistance (existing operation).
+    ///
+    /// The malus is based on the number of sibling operations and age. Sibling
+    /// operations are operations that have the same owner (UID).
+    ///
+    /// Every operation, existing or new, starts with a malus of 1. Every sibling
+    /// increases the malus by one. The age is the time since an operation was last touched.
+    /// It increases the malus by log6(<age in seconds> + 1) rounded down to the next
+    /// integer. So the malus increases stepwise after 5s, 35s, 215s, ...
+    /// Of two operations with the same malus the least recently used one is considered
+    /// weaker.
+    ///
+    /// For the caller to be able to prune an operation it must find an operation
+    /// with a malus higher than its own.
+    ///
+    /// The malus can be expressed as
+    /// ```
+    /// malus = 1 + no_of_siblings + floor(log6(age_in_seconds + 1))
+    /// ```
+    /// where the constant `1` accounts for the operation under consideration.
+    /// In reality we compute it as
+    /// ```
+    /// caller_malus = 1 + running_siblings
+    /// ```
+    /// because the new operation has no age and is not included in the `running_siblings`,
+    /// and
+    /// ```
+    /// running_malus = running_siblings + floor(log6(age_in_seconds + 1))
+    /// ```
+    /// because a running operation is included in the `running_siblings` and it has
+    /// an age.
+    ///
+    /// ## Example
+    /// A caller with no running operations has a malus of 1. Young (age < 5s) operations
+    /// also with no siblings have a malus of one and cannot be pruned by the caller.
+    /// We have to find an operation that has at least one sibling or is older than 5s.
+    ///
+    /// A caller with one running operation has a malus of 2. Now even young siblings
+    /// or single child aging (5s <= age < 35s) operations are off limit. An aging
+    /// sibling of two, however, would have a malus of 3 and would be fair game.
+    ///
+    /// ## Rationale
+    /// Due to the limitation of KeyMint operation slots, we cannot get around pruning or
+    /// a single app could easily DoS KeyMint.
+    /// Keystore 1.0 used to always prune the least recently used operation. This at least
+    /// guaranteed that new operations can always be started. With the increased usage
+    /// of Keystore we saw increased pruning activity which can lead to a livelock
+    /// situation in the worst case.
+    ///
+    /// With the new pruning strategy we want to provide well behaved clients with
+    /// progress assurances while punishing DoS attempts. As a result of this
+    /// strategy we can be in the situation where no operation can be pruned and the
+    /// creation of a new operation fails. This allows single child operations which
+    /// are frequently updated to complete, thereby breaking up livelock situations
+    /// and facilitating system wide progress.
+    ///
+    /// ## Update
+    /// We also allow callers to cannibalize their own sibling operations if no other
+    /// slot can be found. In this case the least recently used sibling is pruned.
+    pub fn prune(&self, caller: u32, forced: bool) -> Result<(), Error> {
+        loop {
+            // Maps the uid of the owner to the number of operations that owner has
+            // (running_siblings). More operations per owner lowers the pruning
+            // resistance of the operations of that owner. Whereas the number of
+            // ongoing operations of the caller lowers the pruning power of the caller.
+            let mut owners: HashMap<u32, u64> = HashMap::new();
+            let mut pruning_info: Vec<PruningInfo> = Vec::new();
+
+            let now = Instant::now();
+            self.operations
+                .lock()
+                .expect("In OperationDb::prune: Trying to lock self.operations.")
+                .iter()
+                .for_each(|op| {
+                    if let Some(op) = op.upgrade() {
+                        if let Some(p_info) = op.get_pruning_info() {
+                            let owner = p_info.owner;
+                            pruning_info.push(p_info);
+                            // Count operations per owner.
+                            *owners.entry(owner).or_insert(0) += 1;
+                        }
+                    }
+                });
+
+            // If the operation is forced, the caller has a malus of 0.
+            let caller_malus = if forced { 0 } else { 1u64 + *owners.entry(caller).or_default() };
+
+            // We iterate through all operations computing the malus and finding
+            // the candidate with the highest malus which must also be higher
+            // than the caller_malus.
+            struct CandidateInfo {
+                index: usize,
+                malus: u64,
+                last_usage: Instant,
+                age: Duration,
+            }
+            let mut oldest_caller_op: Option<CandidateInfo> = None;
+            let candidate = pruning_info.iter().fold(
+                None,
+                |acc: Option<CandidateInfo>, &PruningInfo { last_usage, owner, index, forced }| {
+                    // Compute the age of the current operation.
+                    let age = now
+                        .checked_duration_since(last_usage)
+                        .unwrap_or_else(|| Duration::new(0, 0));
+
+                    // Find the least recently used sibling as an alternative pruning candidate.
+                    if owner == caller {
+                        if let Some(CandidateInfo { age: a, .. }) = oldest_caller_op {
+                            if age > a {
+                                oldest_caller_op =
+                                    Some(CandidateInfo { index, malus: 0, last_usage, age });
+                            }
+                        } else {
+                            oldest_caller_op =
+                                Some(CandidateInfo { index, malus: 0, last_usage, age });
+                        }
+                    }
+
+                    // Compute the malus of the current operation.
+                    let malus = if forced {
+                        // Forced operations have a malus of 0. And cannot even be pruned
+                        // by other forced operations.
+                        0
+                    } else {
+                        // Expect safety: Every owner in pruning_info was counted in
+                        // the owners map. So this unwrap cannot panic.
+                        *owners.get(&owner).expect(
+                            "This is odd. We should have counted every owner in pruning_info.",
+                        ) + ((age.as_secs() + 1) as f64).log(6.0).floor() as u64
+                    };
+
+                    // Now check if the current operation is a viable/better candidate
+                    // the one currently stored in the accumulator.
+                    match acc {
+                        // First we have to find any operation that is prunable by the caller.
+                        None => {
+                            if caller_malus < malus {
+                                Some(CandidateInfo { index, malus, last_usage, age })
+                            } else {
+                                None
+                            }
+                        }
+                        // If we have found one we look for the operation with the worst score.
+                        // If there is a tie, the older operation is considered weaker.
+                        Some(CandidateInfo { index: i, malus: m, last_usage: l, age: a }) => {
+                            if malus > m || (malus == m && age > a) {
+                                Some(CandidateInfo { index, malus, last_usage, age })
+                            } else {
+                                Some(CandidateInfo { index: i, malus: m, last_usage: l, age: a })
+                            }
+                        }
+                    }
+                },
+            );
+
+            // If we did not find a suitable candidate we may cannibalize our oldest sibling.
+            let candidate = candidate.or(oldest_caller_op);
+
+            match candidate {
+                Some(CandidateInfo { index, malus: _, last_usage, age: _ }) => {
+                    match self.get(index) {
+                        Some(op) => {
+                            match op.prune(last_usage) {
+                                // We successfully freed up a slot.
+                                Ok(()) => break Ok(()),
+                                // This means the operation we tried to prune was on its way
+                                // out. It also means that the slot it had occupied was freed up.
+                                Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)) => break Ok(()),
+                                // This means the operation we tried to prune was currently
+                                // servicing a request. There are two options.
+                                // * Assume that it was touched, which means that its
+                                //   pruning resistance increased. In that case we have
+                                //   to start over and find another candidate.
+                                // * Assume that the operation is transitioning to end-of-life.
+                                //   which means that we got a free slot for free.
+                                // If we assume the first but the second is true, we prune
+                                // a good operation without need (aggressive approach).
+                                // If we assume the second but the first is true, our
+                                // caller will attempt to create a new KeyMint operation,
+                                // fail with `ErrorCode::TOO_MANY_OPERATIONS`, and call
+                                // us again (conservative approach).
+                                Err(Error::Rc(ResponseCode::OPERATION_BUSY)) => {
+                                    // We choose the conservative approach, because
+                                    // every needlessly pruned operation can impact
+                                    // the user experience.
+                                    // To switch to the aggressive approach replace
+                                    // the following line with `continue`.
+                                    break Ok(());
+                                }
+
+                                // The candidate may have been touched so the score
+                                // has changed since our evaluation.
+                                _ => continue,
+                            }
+                        }
+                        // This index does not exist any more. The operation
+                        // in this slot was dropped. Good news, a slot
+                        // has freed up.
+                        None => break Ok(()),
+                    }
+                }
+                // We did not get a pruning candidate.
+                None => break Err(Error::Rc(ResponseCode::BACKEND_BUSY)),
+            }
+        }
+    }
+}
+
+/// Implementation of IKeystoreOperation.
+pub struct KeystoreOperation {
+    operation: Mutex<Option<Arc<Operation>>>,
+}
+
+impl KeystoreOperation {
+    /// Creates a new operation instance wrapped in a
+    /// BnKeystoreOperation proxy object. It also enables
+    /// `BinderFeatures::set_requesting_sid` on the new interface, because
+    /// we need it for checking Keystore permissions.
+    pub fn new_native_binder(
+        operation: Arc<Operation>,
+    ) -> binder::public_api::Strong<dyn IKeystoreOperation> {
+        BnKeystoreOperation::new_binder(
+            Self { operation: Mutex::new(Some(operation)) },
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        )
+    }
+
+    /// Grabs the outer operation mutex and calls `f` on the locked operation.
+    /// The function also deletes the operation if it returns with an error or if
+    /// `delete_op` is true.
+    fn with_locked_operation<T, F>(&self, f: F, delete_op: bool) -> Result<T>
+    where
+        for<'a> F: FnOnce(&'a Operation) -> Result<T>,
+    {
+        let mut delete_op: bool = delete_op;
+        match self.operation.try_lock() {
+            Ok(mut mutex_guard) => {
+                let result = match &*mutex_guard {
+                    Some(op) => {
+                        let result = f(&*op);
+                        // Any error here means we can discard the operation.
+                        if result.is_err() {
+                            delete_op = true;
+                        }
+                        result
+                    }
+                    None => Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE))
+                        .context("In KeystoreOperation::with_locked_operation"),
+                };
+
+                if delete_op {
+                    // We give up our reference to the Operation, thereby freeing up our
+                    // internal resources and ending the wrapped KeyMint operation.
+                    // This KeystoreOperation object will still be owned by an SpIBinder
+                    // until the client drops its remote reference.
+                    *mutex_guard = None;
+                }
+                result
+            }
+            Err(_) => Err(Error::Rc(ResponseCode::OPERATION_BUSY))
+                .context("In KeystoreOperation::with_locked_operation"),
+        }
+    }
+}
+
+impl binder::Interface for KeystoreOperation {}
+
+impl IKeystoreOperation for KeystoreOperation {
+    fn updateAad(&self, aad_input: &[u8]) -> binder::public_api::Result<()> {
+        let _wp = wd::watch_millis("IKeystoreOperation::updateAad", 500);
+        map_or_log_err(
+            self.with_locked_operation(
+                |op| op.update_aad(aad_input).context("In KeystoreOperation::updateAad"),
+                false,
+            ),
+            Ok,
+        )
+    }
+
+    fn update(&self, input: &[u8]) -> binder::public_api::Result<Option<Vec<u8>>> {
+        let _wp = wd::watch_millis("IKeystoreOperation::update", 500);
+        map_or_log_err(
+            self.with_locked_operation(
+                |op| op.update(input).context("In KeystoreOperation::update"),
+                false,
+            ),
+            Ok,
+        )
+    }
+    fn finish(
+        &self,
+        input: Option<&[u8]>,
+        signature: Option<&[u8]>,
+    ) -> binder::public_api::Result<Option<Vec<u8>>> {
+        let _wp = wd::watch_millis("IKeystoreOperation::finish", 500);
+        map_or_log_err(
+            self.with_locked_operation(
+                |op| op.finish(input, signature).context("In KeystoreOperation::finish"),
+                true,
+            ),
+            Ok,
+        )
+    }
+
+    fn abort(&self) -> binder::public_api::Result<()> {
+        let _wp = wd::watch_millis("IKeystoreOperation::abort", 500);
+        map_err_with(
+            self.with_locked_operation(
+                |op| op.abort(Outcome::Abort).context("In KeystoreOperation::abort"),
+                true,
+            ),
+            |e| {
+                match e.root_cause().downcast_ref::<Error>() {
+                    // Calling abort on expired operations is something very common.
+                    // There is no reason to clutter the log with it. It is never the cause
+                    // for a true problem.
+                    Some(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)) => {}
+                    _ => log::error!("{:?}", e),
+                };
+                e
+            },
+            Ok,
+        )
+    }
+}
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs
new file mode 100644
index 0000000..726c2ec
--- /dev/null
+++ b/keystore2/src/permission.rs
@@ -0,0 +1,1064 @@
+// Copyright 2020, 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.
+
+//! This crate provides access control primitives for Keystore 2.0.
+//! It provides high level functions for checking permissions in the keystore2 and keystore2_key
+//! SELinux classes based on the keystore2_selinux backend.
+//! It also provides KeystorePerm and KeyPerm as convenience wrappers for the SELinux permission
+//! defined by keystore2 and keystore2_key respectively.
+
+#![allow(clippy::from_over_into)]
+
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor, KeyPermission::KeyPermission,
+};
+
+use std::cmp::PartialEq;
+use std::convert::From;
+use std::ffi::CStr;
+
+use crate::error::Error as KsError;
+use keystore2_selinux as selinux;
+
+use anyhow::Context as AnyhowContext;
+
+use selinux::Backend;
+
+use lazy_static::lazy_static;
+
+// Replace getcon with a mock in the test situation
+#[cfg(not(test))]
+use selinux::getcon;
+#[cfg(test)]
+use tests::test_getcon as getcon;
+
+lazy_static! {
+    // Panicking here is allowed because keystore cannot function without this backend
+    // and it would happen early and indicate a gross misconfiguration of the device.
+    static ref KEYSTORE2_KEY_LABEL_BACKEND: selinux::KeystoreKeyBackend =
+            selinux::KeystoreKeyBackend::new().unwrap();
+}
+
+fn lookup_keystore2_key_context(namespace: i64) -> anyhow::Result<selinux::Context> {
+    KEYSTORE2_KEY_LABEL_BACKEND.lookup(&namespace.to_string())
+}
+
+/// ## Background
+///
+/// AIDL enums are represented as constants of the form:
+/// ```
+/// mod EnumName {
+///     pub type EnumName = i32;
+///     pub const Variant1: EnumName = <value1>;
+///     pub const Variant2: EnumName = <value2>;
+///     ...
+/// }
+///```
+/// This macro wraps the enum in a new type, e.g., `MyPerm` and maps each variant to an SELinux
+/// permission while providing the following interface:
+///  * From<EnumName> and Into<EnumName> are implemented. Where the implementation of From maps
+///    any variant not specified to the default.
+///  * Every variant has a constructor with a name corresponding to its lower case SELinux string
+///    representation.
+///  * `MyPerm.to_selinux(&self)` returns the SELinux string representation of the
+///    represented permission.
+///
+/// ## Special behavior
+/// If the keyword `use` appears as an selinux name `use_` is used as identifier for the
+/// constructor function (e.g. `MePerm::use_()`) but the string returned by `to_selinux` will
+/// still be `"use"`.
+///
+/// ## Example
+/// ```
+///
+/// implement_permission!(
+///     /// MyPerm documentation.
+///     #[derive(Clone, Copy, Debug, PartialEq)]
+///     MyPerm from EnumName with default (None, none) {}
+///         Variant1,    selinux name: variant1;
+///         Variant2,    selinux name: variant1;
+///     }
+/// );
+/// ```
+macro_rules! implement_permission_aidl {
+    // This rule provides the public interface of the macro. And starts the preprocessing
+    // recursion (see below).
+    ($(#[$m:meta])* $name:ident from $aidl_name:ident with default ($($def:tt)*)
+        { $($element:tt)* })
+    => {
+        implement_permission_aidl!(@replace_use $($m)*, $name, $aidl_name, ($($def)*), [],
+            $($element)*);
+    };
+
+    // The following three rules recurse through the elements of the form
+    // `<enum variant>, selinux name: <selinux_name>;`
+    // preprocessing the input.
+
+    // The first rule terminates the recursion and passes the processed arguments to the final
+    // rule that spills out the implementation.
+    (@replace_use $($m:meta)*, $name:ident, $aidl_name:ident, ($($def:tt)*), [$($out:tt)*], ) => {
+        implement_permission_aidl!(@end $($m)*, $name, $aidl_name, ($($def)*) { $($out)* } );
+    };
+
+    // The second rule is triggered if the selinux name of an element is literally `use`.
+    // It produces the tuple `<enum variant>, use_, use;`
+    // and appends it to the out list.
+    (@replace_use $($m:meta)*, $name:ident, $aidl_name:ident, ($($def:tt)*), [$($out:tt)*],
+        $e_name:ident, selinux name: use; $($element:tt)*)
+    => {
+        implement_permission_aidl!(@replace_use $($m)*, $name, $aidl_name, ($($def)*),
+                              [$($out)* $e_name, use_, use;], $($element)*);
+    };
+
+    // The third rule is the default rule which replaces every input tuple with
+    // `<enum variant>, <selinux_name>, <selinux_name>;`
+    // and appends the result to the out list.
+    (@replace_use $($m:meta)*, $name:ident, $aidl_name:ident, ($($def:tt)*), [$($out:tt)*],
+        $e_name:ident, selinux name: $e_str:ident; $($element:tt)*)
+    => {
+        implement_permission_aidl!(@replace_use $($m)*, $name, $aidl_name, ($($def)*),
+                              [$($out)* $e_name, $e_str, $e_str;], $($element)*);
+    };
+
+    (@end $($m:meta)*, $name:ident, $aidl_name:ident,
+        ($def_name:ident, $def_selinux_name:ident) {
+            $($element_name:ident, $element_identifier:ident,
+                $selinux_name:ident;)*
+        })
+    =>
+    {
+        $(#[$m])*
+        pub struct $name(pub $aidl_name);
+
+        impl From<$aidl_name> for $name {
+            fn from (p: $aidl_name) -> Self {
+                match p {
+                    $aidl_name::$def_name => Self($aidl_name::$def_name),
+                    $($aidl_name::$element_name => Self($aidl_name::$element_name),)*
+                    _ => Self($aidl_name::$def_name),
+                }
+            }
+        }
+
+        impl Into<$aidl_name> for $name {
+            fn into(self) -> $aidl_name {
+                self.0
+            }
+        }
+
+        impl $name {
+            /// Returns a string representation of the permission as required by
+            /// `selinux::check_access`.
+            pub fn to_selinux(&self) -> &'static str {
+                match self {
+                    Self($aidl_name::$def_name) => stringify!($def_selinux_name),
+                    $(Self($aidl_name::$element_name) => stringify!($selinux_name),)*
+                    _ => stringify!($def_selinux_name),
+                }
+            }
+
+            /// Creates an instance representing a permission with the same name.
+            pub const fn $def_selinux_name() -> Self { Self($aidl_name::$def_name) }
+            $(
+                /// Creates an instance representing a permission with the same name.
+                pub const fn $element_identifier() -> Self { Self($aidl_name::$element_name) }
+            )*
+        }
+    };
+}
+
+implement_permission_aidl!(
+    /// KeyPerm provides a convenient abstraction from the SELinux class `keystore2_key`.
+    /// At the same time it maps `KeyPermissions` from the Keystore 2.0 AIDL Grant interface to
+    /// the SELinux permissions. With the implement_permission macro, we conveniently
+    /// provide mappings between the wire type bit field values, the rust enum and the SELinux
+    /// string representation.
+    ///
+    /// ## Example
+    ///
+    /// In this access check `KeyPerm::get_info().to_selinux()` would return the SELinux representation
+    /// "info".
+    /// ```
+    /// selinux::check_access(source_context, target_context, "keystore2_key",
+    ///                       KeyPerm::get_info().to_selinux());
+    /// ```
+    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+    KeyPerm from KeyPermission with default (NONE, none) {
+        CONVERT_STORAGE_KEY_TO_EPHEMERAL,   selinux name: convert_storage_key_to_ephemeral;
+        DELETE,         selinux name: delete;
+        GEN_UNIQUE_ID,  selinux name: gen_unique_id;
+        GET_INFO,       selinux name: get_info;
+        GRANT,          selinux name: grant;
+        MANAGE_BLOB,    selinux name: manage_blob;
+        REBIND,         selinux name: rebind;
+        REQ_FORCED_OP,  selinux name: req_forced_op;
+        UPDATE,         selinux name: update;
+        USE,            selinux name: use;
+        USE_DEV_ID,     selinux name: use_dev_id;
+    }
+);
+
+/// This macro implements an enum with values mapped to SELinux permission names.
+/// The below example wraps the enum MyPermission in the tuple struct `MyPerm` and implements
+///  * From<i32> and Into<i32> are implemented. Where the implementation of From maps
+///    any variant not specified to the default.
+///  * Every variant has a constructor with a name corresponding to its lower case SELinux string
+///    representation.
+///  * `MyPerm.to_selinux(&self)` returns the SELinux string representation of the
+///    represented permission.
+///
+/// ## Example
+/// ```
+/// implement_permission!(
+///     /// MyPerm documentation.
+///     #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+///     MyPerm with default (None = 0, none) {
+///         Foo = 1,           selinux name: foo;
+///         Bar = 2,           selinux name: bar;
+///     }
+/// );
+/// ```
+macro_rules! implement_permission {
+    // This rule provides the public interface of the macro. And starts the preprocessing
+    // recursion (see below).
+    ($(#[$m:meta])* $name:ident with default
+        ($def_name:ident = $def_val:expr, $def_selinux_name:ident)
+        {
+            $($(#[$element_meta:meta])*
+            $element_name:ident = $element_val:expr, selinux name: $selinux_name:ident;)*
+        })
+    => {
+        $(#[$m])*
+        pub enum $name {
+            /// The default variant of an enum.
+            $def_name = $def_val,
+            $(
+                $(#[$element_meta])*
+                $element_name = $element_val,
+            )*
+        }
+
+        impl From<i32> for $name {
+            fn from (p: i32) -> Self {
+                match p {
+                    $def_val => Self::$def_name,
+                    $($element_val => Self::$element_name,)*
+                    _ => Self::$def_name,
+                }
+            }
+        }
+
+        impl Into<i32> for $name {
+            fn into(self) -> i32 {
+                self as i32
+            }
+        }
+
+        impl $name {
+            /// Returns a string representation of the permission as required by
+            /// `selinux::check_access`.
+            pub fn to_selinux(&self) -> &'static str {
+                match self {
+                    Self::$def_name => stringify!($def_selinux_name),
+                    $(Self::$element_name => stringify!($selinux_name),)*
+                }
+            }
+
+            /// Creates an instance representing a permission with the same name.
+            pub const fn $def_selinux_name() -> Self { Self::$def_name }
+            $(
+                /// Creates an instance representing a permission with the same name.
+                pub const fn $selinux_name() -> Self { Self::$element_name }
+            )*
+        }
+    };
+}
+
+implement_permission!(
+    /// KeystorePerm provides a convenient abstraction from the SELinux class `keystore2`.
+    /// Using the implement_permission macro we get the same features as `KeyPerm`.
+    #[derive(Clone, Copy, Debug, PartialEq)]
+    KeystorePerm with default (None = 0, none) {
+        /// Checked when a new auth token is installed.
+        AddAuth = 1,    selinux name: add_auth;
+        /// Checked when an app is uninstalled or wiped.
+        ClearNs = 2,    selinux name: clear_ns;
+        /// Checked when the user state is queried from Keystore 2.0.
+        GetState = 4,   selinux name: get_state;
+        /// Checked when Keystore 2.0 is asked to list a namespace that the caller
+        /// does not have the get_info permission for.
+        List = 8,       selinux name: list;
+        /// Checked when Keystore 2.0 gets locked.
+        Lock = 0x10,       selinux name: lock;
+        /// Checked when Keystore 2.0 shall be reset.
+        Reset = 0x20,    selinux name: reset;
+        /// Checked when Keystore 2.0 shall be unlocked.
+        Unlock = 0x40,    selinux name: unlock;
+        /// Checked when user is added or removed.
+        ChangeUser = 0x80,    selinux name: change_user;
+        /// Checked when password of the user is changed.
+        ChangePassword = 0x100,    selinux name: change_password;
+        /// Checked when a UID is cleared.
+        ClearUID = 0x200,    selinux name: clear_uid;
+        /// Checked when Credstore calls IKeystoreAuthorization to obtain auth tokens.
+        GetAuthToken = 0x400,  selinux name: get_auth_token;
+        /// Checked when earlyBootEnded() is called.
+        EarlyBootEnded = 0x800,   selinux name: early_boot_ended;
+        /// Checked when IKeystoreMaintenance::onDeviceOffBody is called.
+        ReportOffBody = 0x1000, selinux name: report_off_body;
+    }
+);
+
+/// Represents a set of `KeyPerm` permissions.
+/// `IntoIterator` is implemented for this struct allowing the iteration through all the
+/// permissions in the set.
+/// It also implements a function `includes(self, other)` that checks if the permissions
+/// in `other` are included in `self`.
+///
+/// KeyPermSet can be created with the macro `key_perm_set![]`.
+///
+/// ## Example
+/// ```
+/// let perms1 = key_perm_set![KeyPerm::use_(), KeyPerm::manage_blob(), KeyPerm::grant()];
+/// let perms2 = key_perm_set![KeyPerm::use_(), KeyPerm::manage_blob()];
+///
+/// assert!(perms1.includes(perms2))
+/// assert!(!perms2.includes(perms1))
+///
+/// let i = perms1.into_iter();
+/// // iteration in ascending order of the permission's numeric representation.
+/// assert_eq(Some(KeyPerm::manage_blob()), i.next());
+/// assert_eq(Some(KeyPerm::grant()), i.next());
+/// assert_eq(Some(KeyPerm::use_()), i.next());
+/// assert_eq(None, i.next());
+/// ```
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
+pub struct KeyPermSet(pub i32);
+
+mod perm {
+    use super::*;
+
+    pub struct IntoIter {
+        vec: KeyPermSet,
+        pos: u8,
+    }
+
+    impl IntoIter {
+        pub fn new(v: KeyPermSet) -> Self {
+            Self { vec: v, pos: 0 }
+        }
+    }
+
+    impl std::iter::Iterator for IntoIter {
+        type Item = KeyPerm;
+
+        fn next(&mut self) -> Option<Self::Item> {
+            loop {
+                if self.pos == 32 {
+                    return None;
+                }
+                let p = self.vec.0 & (1 << self.pos);
+                self.pos += 1;
+                if p != 0 {
+                    return Some(KeyPerm::from(KeyPermission(p)));
+                }
+            }
+        }
+    }
+}
+
+impl From<KeyPerm> for KeyPermSet {
+    fn from(p: KeyPerm) -> Self {
+        Self((p.0).0 as i32)
+    }
+}
+
+/// allow conversion from the AIDL wire type i32 to a permission set.
+impl From<i32> for KeyPermSet {
+    fn from(p: i32) -> Self {
+        Self(p)
+    }
+}
+
+impl From<KeyPermSet> for i32 {
+    fn from(p: KeyPermSet) -> i32 {
+        p.0
+    }
+}
+
+impl KeyPermSet {
+    /// Returns true iff this permission set has all of the permissions that are in `other`.
+    pub fn includes<T: Into<KeyPermSet>>(&self, other: T) -> bool {
+        let o: KeyPermSet = other.into();
+        (self.0 & o.0) == o.0
+    }
+}
+
+/// This macro can be used to create a `KeyPermSet` from a list of `KeyPerm` values.
+///
+/// ## Example
+/// ```
+/// let v = key_perm_set![Perm::delete(), Perm::manage_blob()];
+/// ```
+#[macro_export]
+macro_rules! key_perm_set {
+    () => { KeyPermSet(0) };
+    ($head:expr $(, $tail:expr)* $(,)?) => {
+        KeyPermSet(($head.0).0 $(| ($tail.0).0)*)
+    };
+}
+
+impl IntoIterator for KeyPermSet {
+    type Item = KeyPerm;
+    type IntoIter = perm::IntoIter;
+
+    fn into_iter(self) -> Self::IntoIter {
+        Self::IntoIter::new(self)
+    }
+}
+
+/// Uses `selinux::check_access` to check if the given caller context `caller_cxt` may access
+/// the given permision `perm` of the `keystore2` security class.
+pub fn check_keystore_permission(caller_ctx: &CStr, perm: KeystorePerm) -> anyhow::Result<()> {
+    let target_context = getcon().context("check_keystore_permission: getcon failed.")?;
+    selinux::check_access(caller_ctx, &target_context, "keystore2", perm.to_selinux())
+}
+
+/// Uses `selinux::check_access` to check if the given caller context `caller_cxt` has
+/// all the permissions indicated in `access_vec` for the target domain indicated by the key
+/// descriptor `key` in the security class `keystore2_key`.
+///
+/// Also checks if the caller has the grant permission for the given target domain.
+///
+/// Attempts to grant the grant permission are always denied.
+///
+/// The only viable target domains are
+///  * `Domain::APP` in which case u:r:keystore:s0 is used as target context and
+///  * `Domain::SELINUX` in which case the `key.nspace` parameter is looked up in
+///                      SELinux keystore key backend, and the result is used
+///                      as target context.
+pub fn check_grant_permission(
+    caller_ctx: &CStr,
+    access_vec: KeyPermSet,
+    key: &KeyDescriptor,
+) -> anyhow::Result<()> {
+    let target_context = match key.domain {
+        Domain::APP => getcon().context("check_grant_permission: getcon failed.")?,
+        Domain::SELINUX => lookup_keystore2_key_context(key.nspace)
+            .context("check_grant_permission: Domain::SELINUX: Failed to lookup namespace.")?,
+        _ => return Err(KsError::sys()).context(format!("Cannot grant {:?}.", key.domain)),
+    };
+
+    selinux::check_access(caller_ctx, &target_context, "keystore2_key", "grant")
+        .context("Grant permission is required when granting.")?;
+
+    if access_vec.includes(KeyPerm::grant()) {
+        return Err(selinux::Error::perm()).context("Grant permission cannot be granted.");
+    }
+
+    for p in access_vec.into_iter() {
+        selinux::check_access(caller_ctx, &target_context, "keystore2_key", p.to_selinux())
+            .context(format!(
+                concat!(
+                    "check_grant_permission: check_access failed. ",
+                    "The caller may have tried to grant a permission that they don't possess. {:?}"
+                ),
+                p
+            ))?
+    }
+    Ok(())
+}
+
+/// Uses `selinux::check_access` to check if the given caller context `caller_cxt`
+/// has the permissions indicated by `perm` for the target domain indicated by the key
+/// descriptor `key` in the security class `keystore2_key`.
+///
+/// The behavior differs slightly depending on the selected target domain:
+///  * `Domain::APP` u:r:keystore:s0 is used as target context.
+///  * `Domain::SELINUX` `key.nspace` parameter is looked up in the SELinux keystore key
+///                      backend, and the result is used as target context.
+///  * `Domain::BLOB` Same as SELinux but the "manage_blob" permission is always checked additionally
+///                   to the one supplied in `perm`.
+///  * `Domain::GRANT` Does not use selinux::check_access. Instead the `access_vector`
+///                    parameter is queried for permission, which must be supplied in this case.
+///
+/// ## Return values.
+///  * Ok(()) If the requested permissions were granted.
+///  * Err(selinux::Error::perm()) If the requested permissions were denied.
+///  * Err(KsError::sys()) This error is produced if `Domain::GRANT` is selected but no `access_vec`
+///                      was supplied. It is also produced if `Domain::KEY_ID` was selected, and
+///                      on various unexpected backend failures.
+pub fn check_key_permission(
+    caller_uid: u32,
+    caller_ctx: &CStr,
+    perm: KeyPerm,
+    key: &KeyDescriptor,
+    access_vector: &Option<KeyPermSet>,
+) -> anyhow::Result<()> {
+    // If an access vector was supplied, the key is either accessed by GRANT or by KEY_ID.
+    // In the former case, key.domain was set to GRANT and we check the failure cases
+    // further below. If the access is requested by KEY_ID, key.domain would have been
+    // resolved to APP or SELINUX depending on where the key actually resides.
+    // Either way we can return here immediately if the access vector covers the requested
+    // permission. If it does not, we can still check if the caller has access by means of
+    // ownership.
+    if let Some(access_vector) = access_vector {
+        if access_vector.includes(perm) {
+            return Ok(());
+        }
+    }
+
+    let target_context = match key.domain {
+        // apps get the default keystore context
+        Domain::APP => {
+            if caller_uid as i64 != key.nspace {
+                return Err(selinux::Error::perm())
+                    .context("Trying to access key without ownership.");
+            }
+            getcon().context("check_key_permission: getcon failed.")?
+        }
+        Domain::SELINUX => lookup_keystore2_key_context(key.nspace)
+            .context("check_key_permission: Domain::SELINUX: Failed to lookup namespace.")?,
+        Domain::GRANT => {
+            match access_vector {
+                Some(_) => {
+                    return Err(selinux::Error::perm())
+                        .context(format!("\"{}\" not granted", perm.to_selinux()));
+                }
+                None => {
+                    // If DOMAIN_GRANT was selected an access vector must be supplied.
+                    return Err(KsError::sys()).context(
+                        "Cannot check permission for Domain::GRANT without access vector.",
+                    );
+                }
+            }
+        }
+        Domain::KEY_ID => {
+            // We should never be called with `Domain::KEY_ID. The database
+            // lookup should have converted this into one of `Domain::APP`
+            // or `Domain::SELINUX`.
+            return Err(KsError::sys()).context("Cannot check permission for Domain::KEY_ID.");
+        }
+        Domain::BLOB => {
+            let tctx = lookup_keystore2_key_context(key.nspace)
+                .context("Domain::BLOB: Failed to lookup namespace.")?;
+            // If DOMAIN_KEY_BLOB was specified, we check for the "manage_blob"
+            // permission in addition to the requested permission.
+            selinux::check_access(
+                caller_ctx,
+                &tctx,
+                "keystore2_key",
+                KeyPerm::manage_blob().to_selinux(),
+            )?;
+
+            tctx
+        }
+        _ => {
+            return Err(KsError::sys())
+                .context(format!("Unknown domain value: \"{:?}\".", key.domain))
+        }
+    };
+
+    selinux::check_access(caller_ctx, &target_context, "keystore2_key", perm.to_selinux())
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use anyhow::anyhow;
+    use anyhow::Result;
+    use keystore2_selinux::*;
+
+    const ALL_PERMS: KeyPermSet = key_perm_set![
+        KeyPerm::manage_blob(),
+        KeyPerm::delete(),
+        KeyPerm::use_dev_id(),
+        KeyPerm::req_forced_op(),
+        KeyPerm::gen_unique_id(),
+        KeyPerm::grant(),
+        KeyPerm::get_info(),
+        KeyPerm::rebind(),
+        KeyPerm::update(),
+        KeyPerm::use_(),
+        KeyPerm::convert_storage_key_to_ephemeral(),
+    ];
+
+    const SYSTEM_SERVER_PERMISSIONS_NO_GRANT: KeyPermSet = key_perm_set![
+        KeyPerm::delete(),
+        KeyPerm::use_dev_id(),
+        // No KeyPerm::grant()
+        KeyPerm::get_info(),
+        KeyPerm::rebind(),
+        KeyPerm::update(),
+        KeyPerm::use_(),
+    ];
+
+    const NOT_GRANT_PERMS: KeyPermSet = key_perm_set![
+        KeyPerm::manage_blob(),
+        KeyPerm::delete(),
+        KeyPerm::use_dev_id(),
+        KeyPerm::req_forced_op(),
+        KeyPerm::gen_unique_id(),
+        // No KeyPerm::grant()
+        KeyPerm::get_info(),
+        KeyPerm::rebind(),
+        KeyPerm::update(),
+        KeyPerm::use_(),
+        KeyPerm::convert_storage_key_to_ephemeral(),
+    ];
+
+    const UNPRIV_PERMS: KeyPermSet = key_perm_set![
+        KeyPerm::delete(),
+        KeyPerm::get_info(),
+        KeyPerm::rebind(),
+        KeyPerm::update(),
+        KeyPerm::use_(),
+    ];
+
+    /// The su_key namespace as defined in su.te and keystore_key_contexts of the
+    /// SePolicy (system/sepolicy).
+    const SU_KEY_NAMESPACE: i32 = 0;
+    /// The shell_key namespace as defined in shell.te and keystore_key_contexts of the
+    /// SePolicy (system/sepolicy).
+    const SHELL_KEY_NAMESPACE: i32 = 1;
+
+    pub fn test_getcon() -> Result<Context> {
+        Context::new("u:object_r:keystore:s0")
+    }
+
+    // This macro evaluates the given expression and checks that
+    // a) evaluated to Result::Err() and that
+    // b) the wrapped error is selinux::Error::perm() (permission denied).
+    // We use a macro here because a function would mask which invocation caused the failure.
+    //
+    // TODO b/164121720 Replace this macro with a function when `track_caller` is available.
+    macro_rules! assert_perm_failed {
+        ($test_function:expr) => {
+            let result = $test_function;
+            assert!(result.is_err(), "Permission check should have failed.");
+            assert_eq!(
+                Some(&selinux::Error::perm()),
+                result.err().unwrap().root_cause().downcast_ref::<selinux::Error>()
+            );
+        };
+    }
+
+    fn check_context() -> Result<(selinux::Context, i32, bool)> {
+        // Calling the non mocked selinux::getcon here intended.
+        let context = selinux::getcon()?;
+        match context.to_str().unwrap() {
+            "u:r:su:s0" => Ok((context, SU_KEY_NAMESPACE, true)),
+            "u:r:shell:s0" => Ok((context, SHELL_KEY_NAMESPACE, false)),
+            c => Err(anyhow!(format!(
+                "This test must be run as \"su\" or \"shell\". Current context: \"{}\"",
+                c
+            ))),
+        }
+    }
+
+    #[test]
+    fn check_keystore_permission_test() -> Result<()> {
+        let system_server_ctx = Context::new("u:r:system_server:s0")?;
+        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::add_auth()).is_ok());
+        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::clear_ns()).is_ok());
+        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::get_state()).is_ok());
+        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::lock()).is_ok());
+        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::reset()).is_ok());
+        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::unlock()).is_ok());
+        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::change_user()).is_ok());
+        assert!(
+            check_keystore_permission(&system_server_ctx, KeystorePerm::change_password()).is_ok()
+        );
+        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::clear_uid()).is_ok());
+        let shell_ctx = Context::new("u:r:shell:s0")?;
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::add_auth()));
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::clear_ns()));
+        assert!(check_keystore_permission(&shell_ctx, KeystorePerm::get_state()).is_ok());
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::list()));
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::lock()));
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::reset()));
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::unlock()));
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::change_user()));
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::change_password()));
+        assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::clear_uid()));
+        Ok(())
+    }
+
+    #[test]
+    fn check_grant_permission_app() -> Result<()> {
+        let system_server_ctx = Context::new("u:r:system_server:s0")?;
+        let shell_ctx = Context::new("u:r:shell:s0")?;
+        let key = KeyDescriptor { domain: Domain::APP, nspace: 0, alias: None, blob: None };
+        check_grant_permission(&system_server_ctx, SYSTEM_SERVER_PERMISSIONS_NO_GRANT, &key)
+            .expect("Grant permission check failed.");
+
+        // attempts to grant the grant permission must always fail even when privileged.
+        assert_perm_failed!(check_grant_permission(
+            &system_server_ctx,
+            KeyPerm::grant().into(),
+            &key
+        ));
+        // unprivileged grant attempts always fail. shell does not have the grant permission.
+        assert_perm_failed!(check_grant_permission(&shell_ctx, UNPRIV_PERMS, &key));
+        Ok(())
+    }
+
+    #[test]
+    fn check_grant_permission_selinux() -> Result<()> {
+        let (sctx, namespace, is_su) = check_context()?;
+        let key = KeyDescriptor {
+            domain: Domain::SELINUX,
+            nspace: namespace as i64,
+            alias: None,
+            blob: None,
+        };
+        if is_su {
+            assert!(check_grant_permission(&sctx, NOT_GRANT_PERMS, &key).is_ok());
+            // attempts to grant the grant permission must always fail even when privileged.
+            assert_perm_failed!(check_grant_permission(&sctx, KeyPerm::grant().into(), &key));
+        } else {
+            // unprivileged grant attempts always fail. shell does not have the grant permission.
+            assert_perm_failed!(check_grant_permission(&sctx, UNPRIV_PERMS, &key));
+        }
+        Ok(())
+    }
+
+    #[test]
+    fn check_key_permission_domain_grant() -> Result<()> {
+        let key = KeyDescriptor { domain: Domain::GRANT, nspace: 0, alias: None, blob: None };
+
+        assert_perm_failed!(check_key_permission(
+            0,
+            &selinux::Context::new("ignored").unwrap(),
+            KeyPerm::grant(),
+            &key,
+            &Some(UNPRIV_PERMS)
+        ));
+
+        check_key_permission(
+            0,
+            &selinux::Context::new("ignored").unwrap(),
+            KeyPerm::use_(),
+            &key,
+            &Some(ALL_PERMS),
+        )
+    }
+
+    #[test]
+    fn check_key_permission_domain_app() -> Result<()> {
+        let system_server_ctx = Context::new("u:r:system_server:s0")?;
+        let shell_ctx = Context::new("u:r:shell:s0")?;
+        let gmscore_app = Context::new("u:r:gmscore_app:s0")?;
+
+        let key = KeyDescriptor { domain: Domain::APP, nspace: 0, alias: None, blob: None };
+
+        assert!(check_key_permission(0, &system_server_ctx, KeyPerm::use_(), &key, &None).is_ok());
+        assert!(check_key_permission(0, &system_server_ctx, KeyPerm::delete(), &key, &None).is_ok());
+        assert!(
+            check_key_permission(0, &system_server_ctx, KeyPerm::get_info(), &key, &None).is_ok()
+        );
+        assert!(check_key_permission(0, &system_server_ctx, KeyPerm::rebind(), &key, &None).is_ok());
+        assert!(check_key_permission(0, &system_server_ctx, KeyPerm::update(), &key, &None).is_ok());
+        assert!(check_key_permission(0, &system_server_ctx, KeyPerm::grant(), &key, &None).is_ok());
+        assert!(
+            check_key_permission(0, &system_server_ctx, KeyPerm::use_dev_id(), &key, &None).is_ok()
+        );
+        assert!(
+            check_key_permission(0, &gmscore_app, KeyPerm::gen_unique_id(), &key, &None).is_ok()
+        );
+
+        assert!(check_key_permission(0, &shell_ctx, KeyPerm::use_(), &key, &None).is_ok());
+        assert!(check_key_permission(0, &shell_ctx, KeyPerm::delete(), &key, &None).is_ok());
+        assert!(check_key_permission(0, &shell_ctx, KeyPerm::get_info(), &key, &None).is_ok());
+        assert!(check_key_permission(0, &shell_ctx, KeyPerm::rebind(), &key, &None).is_ok());
+        assert!(check_key_permission(0, &shell_ctx, KeyPerm::update(), &key, &None).is_ok());
+        assert_perm_failed!(check_key_permission(0, &shell_ctx, KeyPerm::grant(), &key, &None));
+        assert_perm_failed!(check_key_permission(
+            0,
+            &shell_ctx,
+            KeyPerm::req_forced_op(),
+            &key,
+            &None
+        ));
+        assert_perm_failed!(check_key_permission(
+            0,
+            &shell_ctx,
+            KeyPerm::manage_blob(),
+            &key,
+            &None
+        ));
+        assert_perm_failed!(check_key_permission(
+            0,
+            &shell_ctx,
+            KeyPerm::use_dev_id(),
+            &key,
+            &None
+        ));
+        assert_perm_failed!(check_key_permission(
+            0,
+            &shell_ctx,
+            KeyPerm::gen_unique_id(),
+            &key,
+            &None
+        ));
+
+        // Also make sure that the permission fails if the caller is not the owner.
+        assert_perm_failed!(check_key_permission(
+            1, // the owner is 0
+            &system_server_ctx,
+            KeyPerm::use_(),
+            &key,
+            &None
+        ));
+        // Unless there was a grant.
+        assert!(check_key_permission(
+            1,
+            &system_server_ctx,
+            KeyPerm::use_(),
+            &key,
+            &Some(key_perm_set![KeyPerm::use_()])
+        )
+        .is_ok());
+        // But fail if the grant did not cover the requested permission.
+        assert_perm_failed!(check_key_permission(
+            1,
+            &system_server_ctx,
+            KeyPerm::use_(),
+            &key,
+            &Some(key_perm_set![KeyPerm::get_info()])
+        ));
+
+        Ok(())
+    }
+
+    #[test]
+    fn check_key_permission_domain_selinux() -> Result<()> {
+        let (sctx, namespace, is_su) = check_context()?;
+        let key = KeyDescriptor {
+            domain: Domain::SELINUX,
+            nspace: namespace as i64,
+            alias: None,
+            blob: None,
+        };
+
+        if is_su {
+            assert!(check_key_permission(0, &sctx, KeyPerm::use_(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::delete(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::get_info(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::rebind(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::update(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::grant(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::manage_blob(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::use_dev_id(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::gen_unique_id(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::req_forced_op(), &key, &None).is_ok());
+        } else {
+            assert!(check_key_permission(0, &sctx, KeyPerm::use_(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::delete(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::get_info(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::rebind(), &key, &None).is_ok());
+            assert!(check_key_permission(0, &sctx, KeyPerm::update(), &key, &None).is_ok());
+            assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::grant(), &key, &None));
+            assert_perm_failed!(check_key_permission(
+                0,
+                &sctx,
+                KeyPerm::req_forced_op(),
+                &key,
+                &None
+            ));
+            assert_perm_failed!(check_key_permission(
+                0,
+                &sctx,
+                KeyPerm::manage_blob(),
+                &key,
+                &None
+            ));
+            assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::use_dev_id(), &key, &None));
+            assert_perm_failed!(check_key_permission(
+                0,
+                &sctx,
+                KeyPerm::gen_unique_id(),
+                &key,
+                &None
+            ));
+        }
+        Ok(())
+    }
+
+    #[test]
+    fn check_key_permission_domain_blob() -> Result<()> {
+        let (sctx, namespace, is_su) = check_context()?;
+        let key = KeyDescriptor {
+            domain: Domain::BLOB,
+            nspace: namespace as i64,
+            alias: None,
+            blob: None,
+        };
+
+        if is_su {
+            check_key_permission(0, &sctx, KeyPerm::use_(), &key, &None)
+        } else {
+            assert_perm_failed!(check_key_permission(0, &sctx, KeyPerm::use_(), &key, &None));
+            Ok(())
+        }
+    }
+
+    #[test]
+    fn check_key_permission_domain_key_id() -> Result<()> {
+        let key = KeyDescriptor { domain: Domain::KEY_ID, nspace: 0, alias: None, blob: None };
+
+        assert_eq!(
+            Some(&KsError::sys()),
+            check_key_permission(
+                0,
+                &selinux::Context::new("ignored").unwrap(),
+                KeyPerm::use_(),
+                &key,
+                &None
+            )
+            .err()
+            .unwrap()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+        Ok(())
+    }
+
+    #[test]
+    fn key_perm_set_all_test() {
+        let v = key_perm_set![
+            KeyPerm::manage_blob(),
+            KeyPerm::delete(),
+            KeyPerm::use_dev_id(),
+            KeyPerm::req_forced_op(),
+            KeyPerm::gen_unique_id(),
+            KeyPerm::grant(),
+            KeyPerm::get_info(),
+            KeyPerm::rebind(),
+            KeyPerm::update(),
+            KeyPerm::use_() // Test if the macro accepts missing comma at the end of the list.
+        ];
+        let mut i = v.into_iter();
+        assert_eq!(i.next().unwrap().to_selinux(), "delete");
+        assert_eq!(i.next().unwrap().to_selinux(), "gen_unique_id");
+        assert_eq!(i.next().unwrap().to_selinux(), "get_info");
+        assert_eq!(i.next().unwrap().to_selinux(), "grant");
+        assert_eq!(i.next().unwrap().to_selinux(), "manage_blob");
+        assert_eq!(i.next().unwrap().to_selinux(), "rebind");
+        assert_eq!(i.next().unwrap().to_selinux(), "req_forced_op");
+        assert_eq!(i.next().unwrap().to_selinux(), "update");
+        assert_eq!(i.next().unwrap().to_selinux(), "use");
+        assert_eq!(i.next().unwrap().to_selinux(), "use_dev_id");
+        assert_eq!(None, i.next());
+    }
+    #[test]
+    fn key_perm_set_sparse_test() {
+        let v = key_perm_set![
+            KeyPerm::manage_blob(),
+            KeyPerm::req_forced_op(),
+            KeyPerm::gen_unique_id(),
+            KeyPerm::update(),
+            KeyPerm::use_(), // Test if macro accepts the comma at the end of the list.
+        ];
+        let mut i = v.into_iter();
+        assert_eq!(i.next().unwrap().to_selinux(), "gen_unique_id");
+        assert_eq!(i.next().unwrap().to_selinux(), "manage_blob");
+        assert_eq!(i.next().unwrap().to_selinux(), "req_forced_op");
+        assert_eq!(i.next().unwrap().to_selinux(), "update");
+        assert_eq!(i.next().unwrap().to_selinux(), "use");
+        assert_eq!(None, i.next());
+    }
+    #[test]
+    fn key_perm_set_empty_test() {
+        let v = key_perm_set![];
+        let mut i = v.into_iter();
+        assert_eq!(None, i.next());
+    }
+    #[test]
+    fn key_perm_set_include_subset_test() {
+        let v1 = key_perm_set![
+            KeyPerm::manage_blob(),
+            KeyPerm::delete(),
+            KeyPerm::use_dev_id(),
+            KeyPerm::req_forced_op(),
+            KeyPerm::gen_unique_id(),
+            KeyPerm::grant(),
+            KeyPerm::get_info(),
+            KeyPerm::rebind(),
+            KeyPerm::update(),
+            KeyPerm::use_(),
+        ];
+        let v2 = key_perm_set![
+            KeyPerm::manage_blob(),
+            KeyPerm::delete(),
+            KeyPerm::rebind(),
+            KeyPerm::update(),
+            KeyPerm::use_(),
+        ];
+        assert!(v1.includes(v2));
+        assert!(!v2.includes(v1));
+    }
+    #[test]
+    fn key_perm_set_include_equal_test() {
+        let v1 = key_perm_set![
+            KeyPerm::manage_blob(),
+            KeyPerm::delete(),
+            KeyPerm::rebind(),
+            KeyPerm::update(),
+            KeyPerm::use_(),
+        ];
+        let v2 = key_perm_set![
+            KeyPerm::manage_blob(),
+            KeyPerm::delete(),
+            KeyPerm::rebind(),
+            KeyPerm::update(),
+            KeyPerm::use_(),
+        ];
+        assert!(v1.includes(v2));
+        assert!(v2.includes(v1));
+    }
+    #[test]
+    fn key_perm_set_include_overlap_test() {
+        let v1 = key_perm_set![
+            KeyPerm::manage_blob(),
+            KeyPerm::delete(),
+            KeyPerm::grant(), // only in v1
+            KeyPerm::rebind(),
+            KeyPerm::update(),
+            KeyPerm::use_(),
+        ];
+        let v2 = key_perm_set![
+            KeyPerm::manage_blob(),
+            KeyPerm::delete(),
+            KeyPerm::req_forced_op(), // only in v2
+            KeyPerm::rebind(),
+            KeyPerm::update(),
+            KeyPerm::use_(),
+        ];
+        assert!(!v1.includes(v2));
+        assert!(!v2.includes(v1));
+    }
+    #[test]
+    fn key_perm_set_include_no_overlap_test() {
+        let v1 = key_perm_set![KeyPerm::manage_blob(), KeyPerm::delete(), KeyPerm::grant(),];
+        let v2 = key_perm_set![
+            KeyPerm::req_forced_op(),
+            KeyPerm::rebind(),
+            KeyPerm::update(),
+            KeyPerm::use_(),
+        ];
+        assert!(!v1.includes(v2));
+        assert!(!v2.includes(v1));
+    }
+}
diff --git a/keystore2/src/raw_device.rs b/keystore2/src/raw_device.rs
new file mode 100644
index 0000000..9e6ef41
--- /dev/null
+++ b/keystore2/src/raw_device.rs
@@ -0,0 +1,248 @@
+// Copyright 2021, 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.
+
+//! Provide the [`KeyMintDevice`] wrapper for operating directly on a KeyMint device.
+
+use crate::{
+    database::{
+        BlobMetaData, BlobMetaEntry, CertificateInfo, DateTime, KeyEntry, KeyEntryLoadBits,
+        KeyIdGuard, KeyMetaData, KeyMetaEntry, KeyType, KeystoreDB, SubComponentType, Uuid,
+    },
+    error::{map_km_error, Error},
+    globals::get_keymint_device,
+    super_key::KeyBlob,
+    utils::{key_characteristics_to_internal, watchdog as wd, Asp, AID_KEYSTORE},
+};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    BeginResult::BeginResult, ErrorCode::ErrorCode, HardwareAuthToken::HardwareAuthToken,
+    IKeyMintDevice::IKeyMintDevice, IKeyMintOperation::IKeyMintOperation,
+    KeyCreationResult::KeyCreationResult, KeyParameter::KeyParameter, KeyPurpose::KeyPurpose,
+    SecurityLevel::SecurityLevel,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor, ResponseCode::ResponseCode,
+};
+use anyhow::{Context, Result};
+use binder::Strong;
+
+/// Wrapper for operating directly on a KeyMint device.
+/// These methods often mirror methods in [`crate::security_level`]. However
+/// the functions in [`crate::security_level`] make assumptions that hold, and has side effects
+/// that make sense, only if called by an external client through binder.
+/// In addition we are trying to maintain a separation between interface services
+/// so that the architecture is compatible with a future move to multiple thread pools.
+/// So the simplest approach today is to write new implementations of them for internal use.
+/// Because these methods run very early, we don't even try to cooperate with
+/// the operation slot database; we assume there will be plenty of slots.
+pub struct KeyMintDevice {
+    asp: Asp,
+    km_uuid: Uuid,
+}
+
+impl KeyMintDevice {
+    /// Get a [`KeyMintDevice`] for the given [`SecurityLevel`]
+    pub fn get(security_level: SecurityLevel) -> Result<KeyMintDevice> {
+        let (asp, _hw_info, km_uuid) = get_keymint_device(&security_level)
+            .context("In KeyMintDevice::get: get_keymint_device failed")?;
+        Ok(KeyMintDevice { asp, km_uuid })
+    }
+
+    /// Create a KM key and store in the database.
+    pub fn create_and_store_key<F>(
+        &self,
+        db: &mut KeystoreDB,
+        key_desc: &KeyDescriptor,
+        creator: F,
+    ) -> Result<()>
+    where
+        F: FnOnce(Strong<dyn IKeyMintDevice>) -> Result<KeyCreationResult, binder::Status>,
+    {
+        let km_dev: Strong<dyn IKeyMintDevice> = self
+            .asp
+            .get_interface()
+            .context("In create_and_store_key: Failed to get KeyMint device")?;
+        let creation_result =
+            map_km_error(creator(km_dev)).context("In create_and_store_key: creator failed")?;
+        let key_parameters = key_characteristics_to_internal(creation_result.keyCharacteristics);
+
+        let creation_date =
+            DateTime::now().context("In create_and_store_key: DateTime::now() failed")?;
+
+        let mut key_metadata = KeyMetaData::new();
+        key_metadata.add(KeyMetaEntry::CreationDate(creation_date));
+        let mut blob_metadata = BlobMetaData::new();
+        blob_metadata.add(BlobMetaEntry::KmUuid(self.km_uuid));
+
+        db.store_new_key(
+            &key_desc,
+            &key_parameters,
+            &(&creation_result.keyBlob, &blob_metadata),
+            &CertificateInfo::new(None, None),
+            &key_metadata,
+            &self.km_uuid,
+        )
+        .context("In create_and_store_key: store_new_key failed")?;
+        Ok(())
+    }
+
+    /// Generate a KeyDescriptor for internal-use keys.
+    pub fn internal_descriptor(alias: String) -> KeyDescriptor {
+        KeyDescriptor {
+            domain: Domain::APP,
+            nspace: AID_KEYSTORE as i64,
+            alias: Some(alias),
+            blob: None,
+        }
+    }
+
+    /// Look up an internal-use key in the database given a key descriptor.
+    pub fn lookup_from_desc(
+        db: &mut KeystoreDB,
+        key_desc: &KeyDescriptor,
+    ) -> Result<(KeyIdGuard, KeyEntry)> {
+        db.load_key_entry(&key_desc, KeyType::Client, KeyEntryLoadBits::KM, AID_KEYSTORE, |_, _| {
+            Ok(())
+        })
+        .context("In lookup_from_desc: load_key_entry failed")
+    }
+
+    /// Look up the key in the database, and return None if it is absent.
+    pub fn not_found_is_none(
+        lookup: Result<(KeyIdGuard, KeyEntry)>,
+    ) -> Result<Option<(KeyIdGuard, KeyEntry)>> {
+        match lookup {
+            Ok(result) => Ok(Some(result)),
+            Err(e) => match e.root_cause().downcast_ref::<Error>() {
+                Some(&Error::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None),
+                _ => Err(e),
+            },
+        }
+    }
+
+    /// This does the lookup and store in separate transactions; caller must
+    /// hold a lock before calling.
+    pub fn lookup_or_generate_key(
+        &self,
+        db: &mut KeystoreDB,
+        key_desc: &KeyDescriptor,
+        params: &[KeyParameter],
+    ) -> Result<(KeyIdGuard, KeyEntry)> {
+        // We use a separate transaction for the lookup than for the store
+        // - to keep the code simple
+        // - because the caller needs to hold a lock in any case
+        // - because it avoids holding database locks during slow
+        //   KeyMint operations
+        let lookup = Self::not_found_is_none(Self::lookup_from_desc(db, key_desc))
+            .context("In lookup_or_generate_key: first lookup failed")?;
+        if let Some(result) = lookup {
+            Ok(result)
+        } else {
+            self.create_and_store_key(db, &key_desc, |km_dev| km_dev.generateKey(&params, None))
+                .context("In lookup_or_generate_key: generate_and_store_key failed")?;
+            Self::lookup_from_desc(db, key_desc)
+                .context("In lookup_or_generate_key: second lookup failed")
+        }
+    }
+
+    /// Call the passed closure; if it returns `KEY_REQUIRES_UPGRADE`, call upgradeKey, and
+    /// write the upgraded key to the database.
+    fn upgrade_keyblob_if_required_with<T, F>(
+        &self,
+        db: &mut KeystoreDB,
+        km_dev: &Strong<dyn IKeyMintDevice>,
+        key_id_guard: &KeyIdGuard,
+        key_blob: &KeyBlob,
+        f: F,
+    ) -> Result<T>
+    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,
+                    );
+                    km_dev.upgradeKey(key_blob, &[])
+                })
+                .context("In upgrade_keyblob_if_required_with: Upgrade failed")?;
+
+                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(&new_blob_metadata),
+                )
+                .context(concat!(
+                    "In upgrade_keyblob_if_required_with: ",
+                    "Failed to insert upgraded blob into the database"
+                ))?;
+
+                Ok(f(&upgraded_blob).context(concat!(
+                    "In upgrade_keyblob_if_required_with: ",
+                    "Closure failed after upgrade"
+                ))?)
+            }
+            result => Ok(result.context("In upgrade_keyblob_if_required_with: Closure failed")?),
+        }
+    }
+
+    /// Use the created key in an operation that can be done with
+    /// a call to begin followed by a call to finish.
+    #[allow(clippy::too_many_arguments)]
+    pub fn use_key_in_one_step(
+        &self,
+        db: &mut KeystoreDB,
+        key_id_guard: &KeyIdGuard,
+        key_entry: &KeyEntry,
+        purpose: KeyPurpose,
+        operation_parameters: &[KeyParameter],
+        auth_token: Option<&HardwareAuthToken>,
+        input: &[u8],
+    ) -> Result<Vec<u8>> {
+        let km_dev: Strong<dyn IKeyMintDevice> = self
+            .asp
+            .get_interface()
+            .context("In use_key_in_one_step: Failed to get KeyMint device")?;
+
+        let (key_blob, _blob_metadata) = key_entry
+            .key_blob_info()
+            .as_ref()
+            .ok_or_else(Error::sys)
+            .context("use_key_in_one_step: Keyblob missing")?;
+        let key_blob = KeyBlob::Ref(&key_blob);
+
+        let begin_result: BeginResult = self
+            .upgrade_keyblob_if_required_with(db, &km_dev, key_id_guard, &key_blob, |blob| {
+                map_km_error({
+                    let _wp = wd::watch_millis("In use_key_in_one_step: calling: begin", 500);
+                    km_dev.begin(purpose, blob, operation_parameters, auth_token)
+                })
+            })
+            .context("In use_key_in_one_step: Failed to begin operation.")?;
+        let operation: Strong<dyn IKeyMintOperation> = begin_result
+            .operation
+            .ok_or_else(Error::sys)
+            .context("In use_key_in_one_step: Operation missing")?;
+        map_km_error({
+            let _wp = wd::watch_millis("In use_key_in_one_step: calling: finish", 500);
+            operation.finish(Some(input), None, None, None, None)
+        })
+        .context("In use_key_in_one_step: Failed to finish operation.")
+    }
+}
diff --git a/keystore2/src/remote_provisioning.rs b/keystore2/src/remote_provisioning.rs
new file mode 100644
index 0000000..fc1a6ad
--- /dev/null
+++ b/keystore2/src/remote_provisioning.rs
@@ -0,0 +1,457 @@
+// Copyright 2020, 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.
+
+//! This is the implementation for the remote provisioning AIDL interface between
+//! the network providers for remote provisioning and the system. This interface
+//! allows the caller to prompt the Remote Provisioning HAL to generate keys and
+//! CBOR blobs that can be ferried to a provisioning server that will return
+//! certificate chains signed by some root authority and stored in a keystore SQLite
+//! DB.
+
+#![allow(clippy::from_over_into, clippy::needless_question_mark, clippy::vec_init_then_push)]
+
+use std::collections::HashMap;
+
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, AttestationKey::AttestationKey, Certificate::Certificate,
+    DeviceInfo::DeviceInfo, IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
+    KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue,
+    MacedPublicKey::MacedPublicKey, ProtectedData::ProtectedData, SecurityLevel::SecurityLevel,
+    Tag::Tag,
+};
+use android_security_remoteprovisioning::aidl::android::security::remoteprovisioning::{
+    AttestationPoolStatus::AttestationPoolStatus, IRemoteProvisioning::BnRemoteProvisioning,
+    IRemoteProvisioning::IRemoteProvisioning,
+};
+use android_security_remoteprovisioning::binder::{BinderFeatures, Strong};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor,
+};
+use anyhow::{Context, Result};
+use keystore2_crypto::parse_subject_from_certificate;
+use std::sync::atomic::{AtomicBool, Ordering};
+
+use crate::database::{CertificateChain, KeystoreDB, Uuid};
+use crate::error::{self, map_or_log_err, map_rem_prov_error, Error};
+use crate::globals::{get_keymint_device, get_remotely_provisioned_component, DB};
+use crate::utils::{watchdog as wd, Asp};
+
+/// Contains helper functions to check if remote provisioning is enabled on the system and, if so,
+/// to assign and retrieve attestation keys and certificate chains.
+#[derive(Default)]
+pub struct RemProvState {
+    security_level: SecurityLevel,
+    km_uuid: Uuid,
+    is_hal_present: AtomicBool,
+}
+
+impl RemProvState {
+    /// Creates a RemProvState struct.
+    pub fn new(security_level: SecurityLevel, km_uuid: Uuid) -> Self {
+        Self { security_level, km_uuid, is_hal_present: AtomicBool::new(true) }
+    }
+
+    /// Checks if remote provisioning is enabled and partially caches the result. On a hybrid system
+    /// remote provisioning can flip from being disabled to enabled depending on responses from the
+    /// server, so unfortunately caching the presence or absence of the HAL is not enough to fully
+    /// make decisions about the state of remote provisioning during runtime.
+    fn check_rem_prov_enabled(&self, db: &mut KeystoreDB) -> Result<bool> {
+        if !self.is_hal_present.load(Ordering::Relaxed)
+            || get_remotely_provisioned_component(&self.security_level).is_err()
+        {
+            self.is_hal_present.store(false, Ordering::Relaxed);
+            return Ok(false);
+        }
+        // To check if remote provisioning is enabled on a system that supports both remote
+        // provisioning and factory provisioned keys, we only need to check if there are any
+        // keys at all generated to indicate if the app has gotten the signal to begin filling
+        // the key pool from the server.
+        let pool_status = db
+            .get_attestation_pool_status(0 /* date */, &self.km_uuid)
+            .context("In check_rem_prov_enabled: failed to get attestation pool status.")?;
+        Ok(pool_status.total != 0)
+    }
+
+    /// Fetches a remote provisioning attestation key and certificate chain inside of the
+    /// returned `CertificateChain` struct if one exists for the given caller_uid. If one has not
+    /// been assigned, this function will assign it. If there are no signed attestation keys
+    /// available to be assigned, it will return the ResponseCode `OUT_OF_KEYS`
+    fn get_rem_prov_attest_key(
+        &self,
+        key: &KeyDescriptor,
+        caller_uid: u32,
+        db: &mut KeystoreDB,
+    ) -> Result<Option<CertificateChain>> {
+        match key.domain {
+            Domain::APP => {
+                // Attempt to get an Attestation Key once. If it fails, then the app doesn't
+                // have a valid chain assigned to it. The helper function will return None after
+                // attempting to assign a key. An error will be thrown if the pool is simply out
+                // of usable keys. Then another attempt to fetch the just-assigned key will be
+                // made. If this fails too, something is very wrong.
+                self.get_rem_prov_attest_key_helper(key, caller_uid, db)
+                    .context("In get_rem_prov_attest_key: Failed to get a key")?
+                    .map_or_else(
+                        || self.get_rem_prov_attest_key_helper(key, caller_uid, db),
+                        |v| Ok(Some(v)),
+                    )
+                    .context(concat!(
+                        "In get_rem_prov_attest_key: Failed to get a key after",
+                        "attempting to assign one."
+                    ))?
+                    .map_or_else(
+                        || {
+                            Err(Error::sys()).context(concat!(
+                                "In get_rem_prov_attest_key: Attempted to assign a ",
+                                "key and failed silently. Something is very wrong."
+                            ))
+                        },
+                        |cert_chain| Ok(Some(cert_chain)),
+                    )
+            }
+            _ => Ok(None),
+        }
+    }
+
+    /// Returns None if an AttestationKey fails to be assigned. Errors if no keys are available.
+    fn get_rem_prov_attest_key_helper(
+        &self,
+        key: &KeyDescriptor,
+        caller_uid: u32,
+        db: &mut KeystoreDB,
+    ) -> Result<Option<CertificateChain>> {
+        let cert_chain = db
+            .retrieve_attestation_key_and_cert_chain(key.domain, caller_uid as i64, &self.km_uuid)
+            .context("In get_rem_prov_attest_key_helper: Failed to retrieve a key + cert chain")?;
+        match cert_chain {
+            Some(cert_chain) => Ok(Some(cert_chain)),
+            // Either this app needs to be assigned a key, or the pool is empty. An error will
+            // be thrown if there is no key available to assign. This will indicate that the app
+            // should be nudged to provision more keys so keystore can retry.
+            None => {
+                db.assign_attestation_key(key.domain, caller_uid as i64, &self.km_uuid)
+                    .context("In get_rem_prov_attest_key_helper: Failed to assign a key")?;
+                Ok(None)
+            }
+        }
+    }
+
+    fn is_asymmetric_key(&self, params: &[KeyParameter]) -> bool {
+        params.iter().any(|kp| {
+            matches!(
+                kp,
+                KeyParameter {
+                    tag: Tag::ALGORITHM,
+                    value: KeyParameterValue::Algorithm(Algorithm::RSA)
+                } | KeyParameter {
+                    tag: Tag::ALGORITHM,
+                    value: KeyParameterValue::Algorithm(Algorithm::EC)
+                }
+            )
+        })
+    }
+
+    /// Checks to see (1) if the key in question should be attested to based on the algorithm and
+    /// (2) if remote provisioning is present and enabled on the system. If these conditions are
+    /// met, it makes an attempt to fetch the attestation key assigned to the `caller_uid`.
+    ///
+    /// It returns the ResponseCode `OUT_OF_KEYS` if there is not one key currently assigned to the
+    /// `caller_uid` and there are none available to assign.
+    pub fn get_remotely_provisioned_attestation_key_and_certs(
+        &self,
+        key: &KeyDescriptor,
+        caller_uid: u32,
+        params: &[KeyParameter],
+        db: &mut KeystoreDB,
+    ) -> Result<Option<(AttestationKey, Certificate)>> {
+        if !self.is_asymmetric_key(params) || !self.check_rem_prov_enabled(db)? {
+            // There is no remote provisioning component for this security level on the
+            // device. Return None so the underlying KM instance knows to use its
+            // factory provisioned key instead. Alternatively, it's not an asymmetric key
+            // and therefore will not be attested.
+            Ok(None)
+        } else {
+            match self.get_rem_prov_attest_key(&key, caller_uid, db).context(concat!(
+                "In get_remote_provisioning_key_and_certs: Failed to get ",
+                "attestation key"
+            ))? {
+                Some(cert_chain) => Ok(Some((
+                    AttestationKey {
+                        keyBlob: cert_chain.private_key.to_vec(),
+                        attestKeyParams: vec![],
+                        issuerSubjectName: parse_subject_from_certificate(&cert_chain.batch_cert)
+                            .context(concat!(
+                            "In get_remote_provisioning_key_and_certs: Failed to ",
+                            "parse subject."
+                        ))?,
+                    },
+                    Certificate { encodedCertificate: cert_chain.cert_chain },
+                ))),
+                None => Ok(None),
+            }
+        }
+    }
+}
+/// Implementation of the IRemoteProvisioning service.
+#[derive(Default)]
+pub struct RemoteProvisioningService {
+    device_by_sec_level: HashMap<SecurityLevel, Asp>,
+}
+
+impl RemoteProvisioningService {
+    fn get_dev_by_sec_level(
+        &self,
+        sec_level: &SecurityLevel,
+    ) -> Result<Strong<dyn IRemotelyProvisionedComponent>> {
+        if let Some(dev) = self.device_by_sec_level.get(sec_level) {
+            dev.get_interface().context("In get_dev_by_sec_level.")
+        } else {
+            Err(error::Error::sys()).context(concat!(
+                "In get_dev_by_sec_level: Remote instance for requested security level",
+                " not found."
+            ))
+        }
+    }
+
+    /// Creates a new instance of the remote provisioning service
+    pub fn new_native_binder() -> Result<Strong<dyn IRemoteProvisioning>> {
+        let mut result: Self = Default::default();
+        let dev = get_remotely_provisioned_component(&SecurityLevel::TRUSTED_ENVIRONMENT)
+            .context("In new_native_binder: Failed to get TEE Remote Provisioner instance.")?;
+        result.device_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, dev);
+        if let Ok(dev) = get_remotely_provisioned_component(&SecurityLevel::STRONGBOX) {
+            result.device_by_sec_level.insert(SecurityLevel::STRONGBOX, dev);
+        }
+        Ok(BnRemoteProvisioning::new_binder(result, BinderFeatures::default()))
+    }
+
+    /// Populates the AttestationPoolStatus parcelable with information about how many
+    /// certs will be expiring by the date provided in `expired_by` along with how many
+    /// keys have not yet been assigned.
+    pub fn get_pool_status(
+        &self,
+        expired_by: i64,
+        sec_level: SecurityLevel,
+    ) -> Result<AttestationPoolStatus> {
+        let (_, _, uuid) = get_keymint_device(&sec_level)?;
+        DB.with::<_, Result<AttestationPoolStatus>>(|db| {
+            let mut db = db.borrow_mut();
+            // delete_expired_attestation_keys is always safe to call, and will remove anything
+            // older than the date at the time of calling. No work should be done on the
+            // attestation keys unless the pool status is checked first, so this call should be
+            // enough to routinely clean out expired keys.
+            db.delete_expired_attestation_keys()?;
+            Ok(db.get_attestation_pool_status(expired_by, &uuid)?)
+        })
+    }
+
+    /// Generates a CBOR blob which will be assembled by the calling code into a larger
+    /// CBOR blob intended for delivery to a provisioning serever. This blob will contain
+    /// `num_csr` certificate signing requests for attestation keys generated in the TEE,
+    /// along with a server provided `eek` and `challenge`. The endpoint encryption key will
+    /// be used to encrypt the sensitive contents being transmitted to the server, and the
+    /// challenge will ensure freshness. A `test_mode` flag will instruct the remote provisioning
+    /// HAL if it is okay to accept EEKs that aren't signed by something that chains back to the
+    /// baked in root of trust in the underlying IRemotelyProvisionedComponent instance.
+    #[allow(clippy::too_many_arguments)]
+    pub fn generate_csr(
+        &self,
+        test_mode: bool,
+        num_csr: i32,
+        eek: &[u8],
+        challenge: &[u8],
+        sec_level: SecurityLevel,
+        protected_data: &mut ProtectedData,
+        device_info: &mut DeviceInfo,
+    ) -> Result<Vec<u8>> {
+        let dev = self.get_dev_by_sec_level(&sec_level)?;
+        let (_, _, uuid) = get_keymint_device(&sec_level)?;
+        let keys_to_sign = DB.with::<_, Result<Vec<MacedPublicKey>>>(|db| {
+            let mut db = db.borrow_mut();
+            Ok(db
+                .fetch_unsigned_attestation_keys(num_csr, &uuid)?
+                .iter()
+                .map(|key| MacedPublicKey { macedKey: key.to_vec() })
+                .collect())
+        })?;
+        let mut mac = map_rem_prov_error(dev.generateCertificateRequest(
+            test_mode,
+            &keys_to_sign,
+            eek,
+            challenge,
+            device_info,
+            protected_data,
+        ))
+        .context("In generate_csr: Failed to generate csr")?;
+        let mut cose_mac_0 = Vec::<u8>::new();
+        // TODO(b/180392379): Replace this manual CBOR generation with the cbor-serde crate as well.
+        //                    This generates an array consisting of the mac and the public key Maps.
+        //                    Just generate the actual MacedPublicKeys structure when the crate is
+        //                    available.
+        cose_mac_0.push((0b100_00000 | (keys_to_sign.len() + 1)) as u8);
+        cose_mac_0.push(0b010_11000); //push mac
+        cose_mac_0.push(mac.len() as u8);
+        cose_mac_0.append(&mut mac);
+        for maced_public_key in keys_to_sign {
+            if maced_public_key.macedKey.len() > 83 + 8 {
+                cose_mac_0.extend_from_slice(&maced_public_key.macedKey[8..83 + 8]);
+            }
+        }
+        Ok(cose_mac_0)
+    }
+
+    /// Provisions a certificate chain for a key whose CSR was included in generate_csr. The
+    /// `public_key` is used to index into the SQL database in order to insert the `certs` blob
+    /// which represents a PEM encoded X.509 certificate chain. The `expiration_date` is provided
+    /// as a convenience from the caller to avoid having to parse the certificates semantically
+    /// here.
+    pub fn provision_cert_chain(
+        &self,
+        public_key: &[u8],
+        batch_cert: &[u8],
+        certs: &[u8],
+        expiration_date: i64,
+        sec_level: SecurityLevel,
+    ) -> Result<()> {
+        DB.with::<_, Result<()>>(|db| {
+            let mut db = db.borrow_mut();
+            let (_, _, uuid) = get_keymint_device(&sec_level)?;
+            Ok(db.store_signed_attestation_certificate_chain(
+                public_key,
+                batch_cert,
+                certs, /* DER encoded certificate chain */
+                expiration_date,
+                &uuid,
+            )?)
+        })
+    }
+
+    /// Submits a request to the Remote Provisioner HAL to generate a signing key pair.
+    /// `is_test_mode` indicates whether or not the returned public key should be marked as being
+    /// for testing in order to differentiate them from private keys. If the call is successful,
+    /// the key pair is then added to the database.
+    pub fn generate_key_pair(&self, is_test_mode: bool, sec_level: SecurityLevel) -> Result<()> {
+        let (_, _, uuid) = get_keymint_device(&sec_level)?;
+        let dev = self.get_dev_by_sec_level(&sec_level)?;
+        let mut maced_key = MacedPublicKey { macedKey: Vec::new() };
+        let priv_key =
+            map_rem_prov_error(dev.generateEcdsaP256KeyPair(is_test_mode, &mut maced_key))
+                .context("In generate_key_pair: Failed to generated ECDSA keypair.")?;
+        // TODO(b/180392379): This is a brittle hack that relies on the consistent formatting of
+        //                    the returned CBOR blob in order to extract the public key.
+        let data = &maced_key.macedKey;
+        if data.len() < 85 {
+            return Err(error::Error::sys()).context(concat!(
+                "In generate_key_pair: CBOR blob returned from",
+                "RemotelyProvisionedComponent is definitely malformatted or empty."
+            ));
+        }
+        let mut raw_key: Vec<u8> = vec![0; 64];
+        raw_key[0..32].clone_from_slice(&data[18..18 + 32]);
+        raw_key[32..64].clone_from_slice(&data[53..53 + 32]);
+        DB.with::<_, Result<()>>(|db| {
+            let mut db = db.borrow_mut();
+            Ok(db.create_attestation_key_entry(&maced_key.macedKey, &raw_key, &priv_key, &uuid)?)
+        })
+    }
+
+    /// Checks the security level of each available IRemotelyProvisionedComponent hal and returns
+    /// all levels in an array to the caller.
+    pub fn get_security_levels(&self) -> Result<Vec<SecurityLevel>> {
+        Ok(self.device_by_sec_level.keys().cloned().collect())
+    }
+
+    /// Deletes all attestation keys generated by the IRemotelyProvisionedComponent from the device,
+    /// regardless of what state of the attestation key lifecycle they were in.
+    pub fn delete_all_keys(&self) -> Result<i64> {
+        DB.with::<_, Result<i64>>(|db| {
+            let mut db = db.borrow_mut();
+            Ok(db.delete_all_attestation_keys()?)
+        })
+    }
+}
+
+impl binder::Interface for RemoteProvisioningService {}
+
+// Implementation of IRemoteProvisioning. See AIDL spec at
+// :aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
+impl IRemoteProvisioning for RemoteProvisioningService {
+    fn getPoolStatus(
+        &self,
+        expired_by: i64,
+        sec_level: SecurityLevel,
+    ) -> binder::public_api::Result<AttestationPoolStatus> {
+        let _wp = wd::watch_millis("IRemoteProvisioning::getPoolStatus", 500);
+        map_or_log_err(self.get_pool_status(expired_by, sec_level), Ok)
+    }
+
+    fn generateCsr(
+        &self,
+        test_mode: bool,
+        num_csr: i32,
+        eek: &[u8],
+        challenge: &[u8],
+        sec_level: SecurityLevel,
+        protected_data: &mut ProtectedData,
+        device_info: &mut DeviceInfo,
+    ) -> binder::public_api::Result<Vec<u8>> {
+        let _wp = wd::watch_millis("IRemoteProvisioning::generateCsr", 500);
+        map_or_log_err(
+            self.generate_csr(
+                test_mode,
+                num_csr,
+                eek,
+                challenge,
+                sec_level,
+                protected_data,
+                device_info,
+            ),
+            Ok,
+        )
+    }
+
+    fn provisionCertChain(
+        &self,
+        public_key: &[u8],
+        batch_cert: &[u8],
+        certs: &[u8],
+        expiration_date: i64,
+        sec_level: SecurityLevel,
+    ) -> binder::public_api::Result<()> {
+        let _wp = wd::watch_millis("IRemoteProvisioning::provisionCertChain", 500);
+        map_or_log_err(
+            self.provision_cert_chain(public_key, batch_cert, certs, expiration_date, sec_level),
+            Ok,
+        )
+    }
+
+    fn generateKeyPair(
+        &self,
+        is_test_mode: bool,
+        sec_level: SecurityLevel,
+    ) -> binder::public_api::Result<()> {
+        let _wp = wd::watch_millis("IRemoteProvisioning::generateKeyPair", 500);
+        map_or_log_err(self.generate_key_pair(is_test_mode, sec_level), Ok)
+    }
+
+    fn getSecurityLevels(&self) -> binder::public_api::Result<Vec<SecurityLevel>> {
+        let _wp = wd::watch_millis("IRemoteProvisioning::getSecurityLevels", 500);
+        map_or_log_err(self.get_security_levels(), Ok)
+    }
+
+    fn deleteAllKeys(&self) -> binder::public_api::Result<i64> {
+        let _wp = wd::watch_millis("IRemoteProvisioning::deleteAllKeys", 500);
+        map_or_log_err(self.delete_all_keys(), Ok)
+    }
+}
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
new file mode 100644
index 0000000..d10aba0
--- /dev/null
+++ b/keystore2/src/security_level.rs
@@ -0,0 +1,1015 @@
+// Copyright 2020, 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.
+
+//! This crate implements the IKeystoreSecurityLevel interface.
+
+use crate::attestation_key_utils::{get_attest_key_info, AttestationKeyInfo};
+use crate::audit_log::{log_key_deleted, log_key_generated, log_key_imported};
+use crate::database::{CertificateInfo, KeyIdGuard};
+use crate::error::{self, map_km_error, map_or_log_err, Error, ErrorCode};
+use crate::globals::{DB, ENFORCEMENTS, LEGACY_MIGRATOR, SUPER_KEY};
+use crate::key_parameter::KeyParameter as KsKeyParam;
+use crate::key_parameter::KeyParameterValue as KsKeyParamValue;
+use crate::metrics::log_key_creation_event_stats;
+use crate::remote_provisioning::RemProvState;
+use crate::super_key::{KeyBlob, SuperKeyManager};
+use crate::utils::{
+    check_device_attestation_permissions, check_key_permission, is_device_id_attestation_tag,
+    key_characteristics_to_internal, uid_to_android_user, watchdog as wd, Asp,
+};
+use crate::{
+    database::{
+        BlobMetaData, BlobMetaEntry, DateTime, KeyEntry, KeyEntryLoadBits, KeyMetaData,
+        KeyMetaEntry, KeyType, SubComponentType, Uuid,
+    },
+    operation::KeystoreOperation,
+    operation::LoggingInfo,
+    operation::OperationDb,
+    permission::KeyPerm,
+};
+use crate::{globals::get_keymint_device, id_rotation::IdRotationState};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, AttestationKey::AttestationKey,
+    HardwareAuthenticatorType::HardwareAuthenticatorType, IKeyMintDevice::IKeyMintDevice,
+    KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat,
+    KeyMintHardwareInfo::KeyMintHardwareInfo, KeyParameter::KeyParameter,
+    KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, Tag::Tag,
+};
+use android_hardware_security_keymint::binder::{BinderFeatures, Strong, ThreadState};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    AuthenticatorSpec::AuthenticatorSpec, CreateOperationResponse::CreateOperationResponse,
+    Domain::Domain, EphemeralStorageKeyResponse::EphemeralStorageKeyResponse,
+    IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
+    IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
+    KeyMetadata::KeyMetadata, KeyParameters::KeyParameters,
+};
+use anyhow::{anyhow, Context, Result};
+
+/// Implementation of the IKeystoreSecurityLevel Interface.
+pub struct KeystoreSecurityLevel {
+    security_level: SecurityLevel,
+    keymint: Asp,
+    hw_info: KeyMintHardwareInfo,
+    km_uuid: Uuid,
+    operation_db: OperationDb,
+    rem_prov_state: RemProvState,
+    id_rotation_state: IdRotationState,
+}
+
+// Blob of 32 zeroes used as empty masking key.
+static ZERO_BLOB_32: &[u8] = &[0; 32];
+
+// Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to GeneralizedTime
+// 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
+const UNDEFINED_NOT_AFTER: i64 = 253402300799000i64;
+
+impl KeystoreSecurityLevel {
+    /// Creates a new security level instance wrapped in a
+    /// BnKeystoreSecurityLevel proxy object. It also enables
+    /// `BinderFeatures::set_requesting_sid` on the new interface, because
+    /// we need it for checking keystore permissions.
+    pub fn new_native_binder(
+        security_level: SecurityLevel,
+        id_rotation_state: IdRotationState,
+    ) -> Result<(Strong<dyn IKeystoreSecurityLevel>, Uuid)> {
+        let (dev, hw_info, km_uuid) = get_keymint_device(&security_level)
+            .context("In KeystoreSecurityLevel::new_native_binder.")?;
+        let result = BnKeystoreSecurityLevel::new_binder(
+            Self {
+                security_level,
+                keymint: dev,
+                hw_info,
+                km_uuid,
+                operation_db: OperationDb::new(),
+                rem_prov_state: RemProvState::new(security_level, km_uuid),
+                id_rotation_state,
+            },
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        );
+        Ok((result, km_uuid))
+    }
+
+    fn watch_millis(&self, id: &'static str, millis: u64) -> Option<wd::WatchPoint> {
+        let sec_level = self.security_level;
+        wd::watch_millis_with(id, millis, move || format!("SecurityLevel {:?}", sec_level))
+    }
+
+    fn store_new_key(
+        &self,
+        key: KeyDescriptor,
+        creation_result: KeyCreationResult,
+        user_id: u32,
+        flags: Option<i32>,
+    ) -> Result<KeyMetadata> {
+        let KeyCreationResult {
+            keyBlob: key_blob,
+            keyCharacteristics: key_characteristics,
+            certificateChain: mut certificate_chain,
+        } = creation_result;
+
+        let mut cert_info: CertificateInfo = CertificateInfo::new(
+            match certificate_chain.len() {
+                0 => None,
+                _ => Some(certificate_chain.remove(0).encodedCertificate),
+            },
+            match certificate_chain.len() {
+                0 => None,
+                _ => Some(
+                    certificate_chain
+                        .iter()
+                        .map(|c| c.encodedCertificate.iter())
+                        .flatten()
+                        .copied()
+                        .collect(),
+                ),
+            },
+        );
+
+        let mut key_parameters = key_characteristics_to_internal(key_characteristics);
+
+        key_parameters.push(KsKeyParam::new(
+            KsKeyParamValue::UserID(user_id as i32),
+            SecurityLevel::SOFTWARE,
+        ));
+
+        let creation_date = DateTime::now().context("Trying to make creation time.")?;
+
+        let key = match key.domain {
+            Domain::BLOB => KeyDescriptor {
+                domain: Domain::BLOB,
+                blob: Some(key_blob.to_vec()),
+                ..Default::default()
+            },
+            _ => DB
+                .with::<_, Result<KeyDescriptor>>(|db| {
+                    let mut db = db.borrow_mut();
+
+                    let (key_blob, mut blob_metadata) = SUPER_KEY
+                        .handle_super_encryption_on_key_init(
+                            &mut db,
+                            &LEGACY_MIGRATOR,
+                            &(key.domain),
+                            &key_parameters,
+                            flags,
+                            user_id,
+                            &key_blob,
+                        )
+                        .context("In store_new_key. Failed to handle super encryption.")?;
+
+                    let mut key_metadata = KeyMetaData::new();
+                    key_metadata.add(KeyMetaEntry::CreationDate(creation_date));
+                    blob_metadata.add(BlobMetaEntry::KmUuid(self.km_uuid));
+
+                    let key_id = db
+                        .store_new_key(
+                            &key,
+                            &key_parameters,
+                            &(&key_blob, &blob_metadata),
+                            &cert_info,
+                            &key_metadata,
+                            &self.km_uuid,
+                        )
+                        .context("In store_new_key.")?;
+                    Ok(KeyDescriptor {
+                        domain: Domain::KEY_ID,
+                        nspace: key_id.id(),
+                        ..Default::default()
+                    })
+                })
+                .context("In store_new_key.")?,
+        };
+
+        Ok(KeyMetadata {
+            key,
+            keySecurityLevel: self.security_level,
+            certificate: cert_info.take_cert(),
+            certificateChain: cert_info.take_cert_chain(),
+            authorizations: crate::utils::key_parameters_to_authorizations(key_parameters),
+            modificationTimeMs: creation_date.to_millis_epoch(),
+        })
+    }
+
+    fn create_operation(
+        &self,
+        key: &KeyDescriptor,
+        operation_parameters: &[KeyParameter],
+        forced: bool,
+    ) -> Result<CreateOperationResponse> {
+        let caller_uid = ThreadState::get_calling_uid();
+        // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
+        // so that we can use it by reference like the blob provided by the key descriptor.
+        // Otherwise, we would have to clone the blob from the key descriptor.
+        let scoping_blob: Vec<u8>;
+        let (km_blob, key_properties, key_id_guard, blob_metadata) = match key.domain {
+            Domain::BLOB => {
+                check_key_permission(KeyPerm::use_(), key, &None)
+                    .context("In create_operation: checking use permission for Domain::BLOB.")?;
+                if forced {
+                    check_key_permission(KeyPerm::req_forced_op(), key, &None).context(
+                        "In create_operation: checking forced permission for Domain::BLOB.",
+                    )?;
+                }
+                (
+                    match &key.blob {
+                        Some(blob) => blob,
+                        None => {
+                            return Err(Error::sys()).context(concat!(
+                                "In create_operation: Key blob must be specified when",
+                                " using Domain::BLOB."
+                            ))
+                        }
+                    },
+                    None,
+                    None,
+                    BlobMetaData::new(),
+                )
+            }
+            _ => {
+                let (key_id_guard, mut key_entry) = DB
+                    .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
+                        LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+                            db.borrow_mut().load_key_entry(
+                                &key,
+                                KeyType::Client,
+                                KeyEntryLoadBits::KM,
+                                caller_uid,
+                                |k, av| {
+                                    check_key_permission(KeyPerm::use_(), k, &av)?;
+                                    if forced {
+                                        check_key_permission(KeyPerm::req_forced_op(), k, &av)?;
+                                    }
+                                    Ok(())
+                                },
+                            )
+                        })
+                    })
+                    .context("In create_operation: Failed to load key blob.")?;
+
+                let (blob, blob_metadata) =
+                    key_entry.take_key_blob_info().ok_or_else(Error::sys).context(concat!(
+                        "In create_operation: Successfully loaded key entry, ",
+                        "but KM blob was missing."
+                    ))?;
+                scoping_blob = blob;
+
+                (
+                    &scoping_blob,
+                    Some((key_id_guard.id(), key_entry.into_key_parameters())),
+                    Some(key_id_guard),
+                    blob_metadata,
+                )
+            }
+        };
+
+        let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE).map_or(
+            Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
+                .context("In create_operation: No operation purpose specified."),
+            |kp| match kp.value {
+                KeyParameterValue::KeyPurpose(p) => Ok(p),
+                _ => Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
+                    .context("In create_operation: Malformed KeyParameter."),
+            },
+        )?;
+
+        // Remove Tag::PURPOSE from the operation_parameters, since some keymaster devices return
+        // an error on begin() if Tag::PURPOSE is in the operation_parameters.
+        let op_params: Vec<KeyParameter> =
+            operation_parameters.iter().filter(|p| p.tag != Tag::PURPOSE).cloned().collect();
+        let operation_parameters = op_params.as_slice();
+
+        let (immediate_hat, mut auth_info) = ENFORCEMENTS
+            .authorize_create(
+                purpose,
+                key_properties.as_ref(),
+                operation_parameters.as_ref(),
+                self.hw_info.timestampTokenRequired,
+            )
+            .context("In create_operation.")?;
+
+        let km_blob = SUPER_KEY
+            .unwrap_key_if_required(&blob_metadata, km_blob)
+            .context("In create_operation. Failed to handle super encryption.")?;
+
+        let km_dev: Strong<dyn IKeyMintDevice> = self
+            .keymint
+            .get_interface()
+            .context("In create_operation: Failed to get KeyMint device")?;
+
+        let (begin_result, upgraded_blob) = self
+            .upgrade_keyblob_if_required_with(
+                &*km_dev,
+                key_id_guard,
+                &km_blob,
+                &blob_metadata,
+                &operation_parameters,
+                |blob| loop {
+                    match map_km_error({
+                        let _wp = self.watch_millis(
+                            "In KeystoreSecurityLevel::create_operation: calling begin",
+                            500,
+                        );
+                        km_dev.begin(purpose, blob, &operation_parameters, immediate_hat.as_ref())
+                    }) {
+                        Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
+                            self.operation_db.prune(caller_uid, forced)?;
+                            continue;
+                        }
+                        v => return v,
+                    }
+                },
+            )
+            .context("In create_operation: Failed to begin operation.")?;
+
+        let operation_challenge = auth_info.finalize_create_authorization(begin_result.challenge);
+
+        let op_params: Vec<KeyParameter> = operation_parameters.to_vec();
+
+        let operation = match begin_result.operation {
+            Some(km_op) => self.operation_db.create_operation(
+                km_op,
+                caller_uid,
+                auth_info,
+                forced,
+                LoggingInfo::new(self.security_level, purpose, op_params, upgraded_blob.is_some()),
+            ),
+            None => {
+                return Err(Error::sys()).context(concat!(
+                    "In create_operation: Begin operation returned successfully, ",
+                    "but did not return a valid operation."
+                ))
+            }
+        };
+
+        let op_binder: binder::public_api::Strong<dyn IKeystoreOperation> =
+            KeystoreOperation::new_native_binder(operation)
+                .as_binder()
+                .into_interface()
+                .context("In create_operation: Failed to create IKeystoreOperation.")?;
+
+        Ok(CreateOperationResponse {
+            iOperation: Some(op_binder),
+            operationChallenge: operation_challenge,
+            parameters: match begin_result.params.len() {
+                0 => None,
+                _ => Some(KeyParameters { keyParameter: begin_result.params }),
+            },
+            // An upgraded blob should only be returned if the caller has permission
+            // to use Domain::BLOB keys. If we got to this point, we already checked
+            // that the caller had that permission.
+            upgradedBlob: if key.domain == Domain::BLOB { upgraded_blob } else { None },
+        })
+    }
+
+    fn add_certificate_parameters(
+        &self,
+        uid: u32,
+        params: &[KeyParameter],
+        key: &KeyDescriptor,
+    ) -> Result<Vec<KeyParameter>> {
+        let mut result = params.to_vec();
+        // If there is an attestation challenge we need to get an application id.
+        if params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE) {
+            let aaid = {
+                let _wp = self.watch_millis(
+                    "In KeystoreSecurityLevel::add_certificate_parameters calling: get_aaid",
+                    500,
+                );
+                keystore2_aaid::get_aaid(uid).map_err(|e| {
+                    anyhow!(format!(
+                        "In add_certificate_parameters: get_aaid returned status {}.",
+                        e
+                    ))
+                })
+            }?;
+
+            result.push(KeyParameter {
+                tag: Tag::ATTESTATION_APPLICATION_ID,
+                value: KeyParameterValue::Blob(aaid),
+            });
+        }
+
+        if params.iter().any(|kp| kp.tag == Tag::INCLUDE_UNIQUE_ID) {
+            check_key_permission(KeyPerm::gen_unique_id(), key, &None).context(concat!(
+                "In add_certificate_parameters: ",
+                "Caller does not have the permission to generate a unique ID"
+            ))?;
+            if self.id_rotation_state.had_factory_reset_since_id_rotation().context(
+                "In add_certificate_parameters: Call to had_factory_reset_since_id_rotation failed."
+            )? {
+                result.push(KeyParameter{
+                    tag: Tag::RESET_SINCE_ID_ROTATION,
+                    value: KeyParameterValue::BoolValue(true),
+                })
+            }
+        }
+
+        // If the caller requests any device identifier attestation tag, check that they hold the
+        // correct Android permission.
+        if params.iter().any(|kp| is_device_id_attestation_tag(kp.tag)) {
+            check_device_attestation_permissions().context(concat!(
+                "In add_certificate_parameters: ",
+                "Caller does not have the permission to attest device identifiers."
+            ))?;
+        }
+
+        // If we are generating/importing an asymmetric key, we need to make sure
+        // that NOT_BEFORE and NOT_AFTER are present.
+        match params.iter().find(|kp| kp.tag == Tag::ALGORITHM) {
+            Some(KeyParameter { tag: _, value: KeyParameterValue::Algorithm(Algorithm::RSA) })
+            | Some(KeyParameter { tag: _, value: KeyParameterValue::Algorithm(Algorithm::EC) }) => {
+                if !params.iter().any(|kp| kp.tag == Tag::CERTIFICATE_NOT_BEFORE) {
+                    result.push(KeyParameter {
+                        tag: Tag::CERTIFICATE_NOT_BEFORE,
+                        value: KeyParameterValue::DateTime(0),
+                    })
+                }
+                if !params.iter().any(|kp| kp.tag == Tag::CERTIFICATE_NOT_AFTER) {
+                    result.push(KeyParameter {
+                        tag: Tag::CERTIFICATE_NOT_AFTER,
+                        value: KeyParameterValue::DateTime(UNDEFINED_NOT_AFTER),
+                    })
+                }
+            }
+            _ => {}
+        }
+        Ok(result)
+    }
+
+    fn generate_key(
+        &self,
+        key: &KeyDescriptor,
+        attest_key_descriptor: Option<&KeyDescriptor>,
+        params: &[KeyParameter],
+        flags: i32,
+        _entropy: &[u8],
+    ) -> Result<KeyMetadata> {
+        if key.domain != Domain::BLOB && key.alias.is_none() {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                .context("In generate_key: Alias must be specified");
+        }
+        let caller_uid = ThreadState::get_calling_uid();
+
+        let key = match key.domain {
+            Domain::APP => KeyDescriptor {
+                domain: key.domain,
+                nspace: caller_uid as i64,
+                alias: key.alias.clone(),
+                blob: None,
+            },
+            _ => key.clone(),
+        };
+
+        // generate_key requires the rebind permission.
+        // Must return on error for security reasons.
+        check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
+
+        let attestation_key_info = match (key.domain, attest_key_descriptor) {
+            (Domain::BLOB, _) => None,
+            _ => DB
+                .with(|db| {
+                    get_attest_key_info(
+                        &key,
+                        caller_uid,
+                        attest_key_descriptor,
+                        params,
+                        &self.rem_prov_state,
+                        &mut db.borrow_mut(),
+                    )
+                })
+                .context("In generate_key: Trying to get an attestation 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()?;
+
+        let creation_result = match attestation_key_info {
+            Some(AttestationKeyInfo::UserGenerated {
+                key_id_guard,
+                blob,
+                blob_metadata,
+                issuer_subject,
+            }) => self
+                .upgrade_keyblob_if_required_with(
+                    &*km_dev,
+                    Some(key_id_guard),
+                    &KeyBlob::Ref(&blob),
+                    &blob_metadata,
+                    &params,
+                    |blob| {
+                        let attest_key = Some(AttestationKey {
+                            keyBlob: blob.to_vec(),
+                            attestKeyParams: vec![],
+                            issuerSubjectName: issuer_subject.clone(),
+                        });
+                        map_km_error({
+                            let _wp = self.watch_millis(
+                                concat!(
+                                    "In KeystoreSecurityLevel::generate_key (UserGenerated): ",
+                                    "calling generate_key."
+                                ),
+                                5000, // Generate can take a little longer.
+                            );
+                            km_dev.generateKey(&params, attest_key.as_ref())
+                        })
+                    },
+                )
+                .context("In generate_key: Using user generated attestation key.")
+                .map(|(result, _)| result),
+            Some(AttestationKeyInfo::RemoteProvisioned { attestation_key, attestation_certs }) => {
+                map_km_error({
+                    let _wp = self.watch_millis(
+                        concat!(
+                            "In KeystoreSecurityLevel::generate_key (RemoteProvisioned): ",
+                            "calling generate_key.",
+                        ),
+                        5000, // Generate can take a little longer.
+                    );
+                    km_dev.generateKey(&params, Some(&attestation_key))
+                })
+                .context("While generating Key with remote provisioned attestation key.")
+                .map(|mut creation_result| {
+                    creation_result.certificateChain.push(attestation_certs);
+                    creation_result
+                })
+            }
+            None => map_km_error({
+                let _wp = self.watch_millis(
+                    concat!(
+                        "In KeystoreSecurityLevel::generate_key (No attestation): ",
+                        "calling generate_key.",
+                    ),
+                    5000, // Generate can take a little longer.
+                );
+                km_dev.generateKey(&params, None)
+            })
+            .context("While generating Key without explicit attestation key."),
+        }
+        .context("In generate_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 import_key(
+        &self,
+        key: &KeyDescriptor,
+        _attestation_key: Option<&KeyDescriptor>,
+        params: &[KeyParameter],
+        flags: i32,
+        key_data: &[u8],
+    ) -> Result<KeyMetadata> {
+        if key.domain != Domain::BLOB && key.alias.is_none() {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                .context("In import_key: Alias must be specified");
+        }
+        let caller_uid = ThreadState::get_calling_uid();
+
+        let key = match key.domain {
+            Domain::APP => KeyDescriptor {
+                domain: key.domain,
+                nspace: caller_uid as i64,
+                alias: key.alias.clone(),
+                blob: None,
+            },
+            _ => key.clone(),
+        };
+
+        // import_key requires the rebind permission.
+        check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
+
+        let params = self
+            .add_certificate_parameters(caller_uid, params, &key)
+            .context("In import_key: Trying to get aaid.")?;
+
+        let format = params
+            .iter()
+            .find(|p| p.tag == Tag::ALGORITHM)
+            .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+            .context("No KeyParameter 'Algorithm'.")
+            .and_then(|p| match &p.value {
+                KeyParameterValue::Algorithm(Algorithm::AES)
+                | KeyParameterValue::Algorithm(Algorithm::HMAC)
+                | KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES) => Ok(KeyFormat::RAW),
+                KeyParameterValue::Algorithm(Algorithm::RSA)
+                | KeyParameterValue::Algorithm(Algorithm::EC) => Ok(KeyFormat::PKCS8),
+                v => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                    .context(format!("Unknown Algorithm {:?}.", v)),
+            })
+            .context("In import_key.")?;
+
+        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({
+            let _wp =
+                self.watch_millis("In KeystoreSecurityLevel::import_key: calling importKey.", 500);
+            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.")
+    }
+
+    fn import_wrapped_key(
+        &self,
+        key: &KeyDescriptor,
+        wrapping_key: &KeyDescriptor,
+        masking_key: Option<&[u8]>,
+        params: &[KeyParameter],
+        authenticators: &[AuthenticatorSpec],
+    ) -> Result<KeyMetadata> {
+        let wrapped_data: &[u8] = match key {
+            KeyDescriptor { domain: Domain::APP, blob: Some(ref blob), alias: Some(_), .. }
+            | KeyDescriptor {
+                domain: Domain::SELINUX, blob: Some(ref blob), alias: Some(_), ..
+            } => blob,
+            _ => {
+                return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(format!(
+                    concat!(
+                        "In import_wrapped_key: Alias and blob must be specified ",
+                        "and domain must be APP or SELINUX. {:?}"
+                    ),
+                    key
+                ))
+            }
+        };
+
+        if wrapping_key.domain == Domain::BLOB {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
+                "In import_wrapped_key: Import wrapped key not supported for self managed blobs.",
+            );
+        }
+
+        let caller_uid = ThreadState::get_calling_uid();
+        let user_id = uid_to_android_user(caller_uid);
+
+        let key = match key.domain {
+            Domain::APP => KeyDescriptor {
+                domain: key.domain,
+                nspace: caller_uid as i64,
+                alias: key.alias.clone(),
+                blob: None,
+            },
+            Domain::SELINUX => KeyDescriptor {
+                domain: Domain::SELINUX,
+                nspace: key.nspace,
+                alias: key.alias.clone(),
+                blob: None,
+            },
+            _ => panic!("Unreachable."),
+        };
+
+        // Import_wrapped_key requires the rebind permission for the new key.
+        check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
+
+        let (wrapping_key_id_guard, mut wrapping_key_entry) = DB
+            .with(|db| {
+                LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+                    db.borrow_mut().load_key_entry(
+                        &wrapping_key,
+                        KeyType::Client,
+                        KeyEntryLoadBits::KM,
+                        caller_uid,
+                        |k, av| check_key_permission(KeyPerm::use_(), k, &av),
+                    )
+                })
+            })
+            .context("Failed to load wrapping key.")?;
+
+        let (wrapping_key_blob, wrapping_blob_metadata) = wrapping_key_entry
+            .take_key_blob_info()
+            .ok_or_else(error::Error::sys)
+            .context("No km_blob after successfully loading key. This should never happen.")?;
+
+        let wrapping_key_blob =
+            SUPER_KEY.unwrap_key_if_required(&wrapping_blob_metadata, &wrapping_key_blob).context(
+                "In import_wrapped_key. Failed to handle super encryption for wrapping key.",
+            )?;
+
+        // km_dev.importWrappedKey does not return a certificate chain.
+        // TODO Do we assume that all wrapped keys are symmetric?
+        // let certificate_chain: Vec<KmCertificate> = Default::default();
+
+        let pw_sid = authenticators
+            .iter()
+            .find_map(|a| match a.authenticatorType {
+                HardwareAuthenticatorType::PASSWORD => Some(a.authenticatorId),
+                _ => None,
+            })
+            .unwrap_or(-1);
+
+        let fp_sid = authenticators
+            .iter()
+            .find_map(|a| match a.authenticatorType {
+                HardwareAuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
+                _ => None,
+            })
+            .unwrap_or(-1);
+
+        let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
+
+        let km_dev: Strong<dyn IKeyMintDevice> = self.keymint.get_interface()?;
+        let (creation_result, _) = self
+            .upgrade_keyblob_if_required_with(
+                &*km_dev,
+                Some(wrapping_key_id_guard),
+                &wrapping_key_blob,
+                &wrapping_blob_metadata,
+                &[],
+                |wrapping_blob| {
+                    let _wp = self.watch_millis(
+                        "In KeystoreSecurityLevel::import_wrapped_key: calling importWrappedKey.",
+                        500,
+                    );
+                    let creation_result = map_km_error(km_dev.importWrappedKey(
+                        wrapped_data,
+                        wrapping_blob,
+                        masking_key,
+                        &params,
+                        pw_sid,
+                        fp_sid,
+                    ))?;
+                    Ok(creation_result)
+                },
+            )
+            .context("In import_wrapped_key.")?;
+
+        self.store_new_key(key, creation_result, user_id, None)
+            .context("In import_wrapped_key: Trying to store the new key.")
+    }
+
+    fn store_upgraded_keyblob(
+        key_id_guard: KeyIdGuard,
+        km_uuid: Option<&Uuid>,
+        key_blob: &KeyBlob,
+        upgraded_blob: &[u8],
+    ) -> Result<()> {
+        let (upgraded_blob_to_be_stored, new_blob_metadata) =
+            SuperKeyManager::reencrypt_if_required(key_blob, &upgraded_blob)
+                .context("In store_upgraded_keyblob: Failed to handle super encryption.")?;
+
+        let mut new_blob_metadata = new_blob_metadata.unwrap_or_default();
+        if let Some(uuid) = km_uuid {
+            new_blob_metadata.add(BlobMetaEntry::KmUuid(*uuid));
+        }
+
+        DB.with(|db| {
+            let mut db = db.borrow_mut();
+            db.set_blob(
+                &key_id_guard,
+                SubComponentType::KEY_BLOB,
+                Some(&upgraded_blob_to_be_stored),
+                Some(&new_blob_metadata),
+            )
+        })
+        .context("In store_upgraded_keyblob: Failed to insert upgraded blob into the database.")
+    }
+
+    fn upgrade_keyblob_if_required_with<T, F>(
+        &self,
+        km_dev: &dyn IKeyMintDevice,
+        key_id_guard: Option<KeyIdGuard>,
+        key_blob: &KeyBlob,
+        blob_metadata: &BlobMetaData,
+        params: &[KeyParameter],
+        f: F,
+    ) -> Result<(T, Option<Vec<u8>>)>
+    where
+        F: Fn(&[u8]) -> Result<T, Error>,
+    {
+        match f(key_blob) {
+            Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
+                let upgraded_blob = {
+                    let _wp = self.watch_millis(
+                        concat!(
+                            "In KeystoreSecurityLevel::upgrade_keyblob_if_required_with: ",
+                            "calling upgradeKey."
+                        ),
+                        500,
+                    );
+                    map_km_error(km_dev.upgradeKey(key_blob, params))
+                }
+                .context("In upgrade_keyblob_if_required_with: Upgrade failed.")?;
+
+                if let Some(kid) = key_id_guard {
+                    Self::store_upgraded_keyblob(
+                        kid,
+                        blob_metadata.km_uuid(),
+                        key_blob,
+                        &upgraded_blob,
+                    )
+                    .context(
+                        "In upgrade_keyblob_if_required_with: store_upgraded_keyblob failed",
+                    )?;
+                }
+
+                match f(&upgraded_blob) {
+                    Ok(v) => Ok((v, Some(upgraded_blob))),
+                    Err(e) => Err(e).context(concat!(
+                        "In upgrade_keyblob_if_required_with: ",
+                        "Failed to perform operation on second try."
+                    )),
+                }
+            }
+            result => {
+                if let Some(kid) = key_id_guard {
+                    if key_blob.force_reencrypt() {
+                        Self::store_upgraded_keyblob(
+                            kid,
+                            blob_metadata.km_uuid(),
+                            key_blob,
+                            key_blob,
+                        )
+                        .context(concat!(
+                            "In upgrade_keyblob_if_required_with: ",
+                            "store_upgraded_keyblob failed in forced reencrypt"
+                        ))?;
+                    }
+                }
+                result
+                    .map(|v| (v, None))
+                    .context("In upgrade_keyblob_if_required_with: Called closure failed.")
+            }
+        }
+    }
+
+    fn convert_storage_key_to_ephemeral(
+        &self,
+        storage_key: &KeyDescriptor,
+    ) -> Result<EphemeralStorageKeyResponse> {
+        if storage_key.domain != Domain::BLOB {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(concat!(
+                "In IKeystoreSecurityLevel convert_storage_key_to_ephemeral: ",
+                "Key must be of Domain::BLOB"
+            ));
+        }
+        let key_blob = storage_key
+            .blob
+            .as_ref()
+            .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+            .context(
+                "In IKeystoreSecurityLevel convert_storage_key_to_ephemeral: No key blob specified",
+            )?;
+
+        // convert_storage_key_to_ephemeral requires the associated permission
+        check_key_permission(KeyPerm::convert_storage_key_to_ephemeral(), storage_key, &None)
+            .context("In convert_storage_key_to_ephemeral: Check permission")?;
+
+        let km_dev: Strong<dyn IKeyMintDevice> = self.keymint.get_interface().context(concat!(
+            "In IKeystoreSecurityLevel convert_storage_key_to_ephemeral: ",
+            "Getting keymint device interface"
+        ))?;
+        match {
+            let _wp = self.watch_millis(
+                concat!(
+                    "In IKeystoreSecurityLevel::convert_storage_key_to_ephemeral: ",
+                    "calling convertStorageKeyToEphemeral (1)"
+                ),
+                500,
+            );
+            map_km_error(km_dev.convertStorageKeyToEphemeral(key_blob))
+        } {
+            Ok(result) => {
+                Ok(EphemeralStorageKeyResponse { ephemeralKey: result, upgradedBlob: None })
+            }
+            Err(error::Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
+                let upgraded_blob = {
+                    let _wp = self.watch_millis(
+                        "In convert_storage_key_to_ephemeral: calling upgradeKey",
+                        500,
+                    );
+                    map_km_error(km_dev.upgradeKey(key_blob, &[]))
+                }
+                .context("In convert_storage_key_to_ephemeral: Failed to upgrade key blob.")?;
+                let ephemeral_key = {
+                    let _wp = self.watch_millis(
+                        "In convert_storage_key_to_ephemeral: calling convertStorageKeyToEphemeral (2)",
+                        500,
+                    );
+                    map_km_error(km_dev.convertStorageKeyToEphemeral(key_blob))
+                }
+                    .context(concat!(
+                        "In convert_storage_key_to_ephemeral: ",
+                        "Failed to retrieve ephemeral key (after upgrade)."
+                    ))?;
+                Ok(EphemeralStorageKeyResponse {
+                    ephemeralKey: ephemeral_key,
+                    upgradedBlob: Some(upgraded_blob),
+                })
+            }
+            Err(e) => Err(e)
+                .context("In convert_storage_key_to_ephemeral: Failed to retrieve ephemeral key."),
+        }
+    }
+
+    fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
+        if key.domain != Domain::BLOB {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                .context("In IKeystoreSecurityLevel delete_key: Key must be of Domain::BLOB");
+        }
+
+        let key_blob = key
+            .blob
+            .as_ref()
+            .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+            .context("In IKeystoreSecurityLevel delete_key: No key blob specified")?;
+
+        check_key_permission(KeyPerm::delete(), key, &None)
+            .context("In IKeystoreSecurityLevel delete_key: Checking delete permissions")?;
+
+        let km_dev: Strong<dyn IKeyMintDevice> = self
+            .keymint
+            .get_interface()
+            .context("In IKeystoreSecurityLevel delete_key: Getting keymint device interface")?;
+        {
+            let _wp =
+                self.watch_millis("In KeystoreSecuritylevel::delete_key: calling deleteKey", 500);
+            map_km_error(km_dev.deleteKey(&key_blob)).context("In keymint device deleteKey")
+        }
+    }
+}
+
+impl binder::Interface for KeystoreSecurityLevel {}
+
+impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
+    fn createOperation(
+        &self,
+        key: &KeyDescriptor,
+        operation_parameters: &[KeyParameter],
+        forced: bool,
+    ) -> binder::public_api::Result<CreateOperationResponse> {
+        let _wp = self.watch_millis("IKeystoreSecurityLevel::createOperation", 500);
+        map_or_log_err(self.create_operation(key, operation_parameters, forced), Ok)
+    }
+    fn generateKey(
+        &self,
+        key: &KeyDescriptor,
+        attestation_key: Option<&KeyDescriptor>,
+        params: &[KeyParameter],
+        flags: i32,
+        entropy: &[u8],
+    ) -> binder::public_api::Result<KeyMetadata> {
+        // Duration is set to 5 seconds, because generateKey - especially for RSA keys, takes more
+        // time than other operations
+        let _wp = self.watch_millis("IKeystoreSecurityLevel::generateKey", 5000);
+        let result = self.generate_key(key, attestation_key, params, flags, entropy);
+        log_key_creation_event_stats(self.security_level, params, &result);
+        log_key_generated(key, ThreadState::get_calling_uid(), result.is_ok());
+        map_or_log_err(result, Ok)
+    }
+    fn importKey(
+        &self,
+        key: &KeyDescriptor,
+        attestation_key: Option<&KeyDescriptor>,
+        params: &[KeyParameter],
+        flags: i32,
+        key_data: &[u8],
+    ) -> binder::public_api::Result<KeyMetadata> {
+        let _wp = self.watch_millis("IKeystoreSecurityLevel::importKey", 500);
+        let result = self.import_key(key, attestation_key, params, flags, key_data);
+        log_key_creation_event_stats(self.security_level, params, &result);
+        log_key_imported(key, ThreadState::get_calling_uid(), result.is_ok());
+        map_or_log_err(result, Ok)
+    }
+    fn importWrappedKey(
+        &self,
+        key: &KeyDescriptor,
+        wrapping_key: &KeyDescriptor,
+        masking_key: Option<&[u8]>,
+        params: &[KeyParameter],
+        authenticators: &[AuthenticatorSpec],
+    ) -> binder::public_api::Result<KeyMetadata> {
+        let _wp = self.watch_millis("IKeystoreSecurityLevel::importWrappedKey", 500);
+        let result =
+            self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators);
+        log_key_creation_event_stats(self.security_level, params, &result);
+        log_key_imported(key, ThreadState::get_calling_uid(), result.is_ok());
+        map_or_log_err(result, Ok)
+    }
+    fn convertStorageKeyToEphemeral(
+        &self,
+        storage_key: &KeyDescriptor,
+    ) -> binder::public_api::Result<EphemeralStorageKeyResponse> {
+        let _wp = self.watch_millis("IKeystoreSecurityLevel::convertStorageKeyToEphemeral", 500);
+        map_or_log_err(self.convert_storage_key_to_ephemeral(storage_key), Ok)
+    }
+    fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
+        let _wp = self.watch_millis("IKeystoreSecurityLevel::deleteKey", 500);
+        let result = self.delete_key(key);
+        log_key_deleted(key, ThreadState::get_calling_uid(), result.is_ok());
+        map_or_log_err(result, Ok)
+    }
+}
diff --git a/keystore2/src/service.rs b/keystore2/src/service.rs
new file mode 100644
index 0000000..3ce0550
--- /dev/null
+++ b/keystore2/src/service.rs
@@ -0,0 +1,402 @@
+// Copyright 2020, 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.
+
+//! This crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0
+//! AIDL spec.
+
+use std::collections::HashMap;
+
+use crate::audit_log::log_key_deleted;
+use crate::permission::{KeyPerm, KeystorePerm};
+use crate::security_level::KeystoreSecurityLevel;
+use crate::utils::{
+    check_grant_permission, check_key_permission, check_keystore_permission,
+    key_parameters_to_authorizations, watchdog as wd, Asp,
+};
+use crate::{
+    database::Uuid,
+    globals::{create_thread_local_db, DB, LEGACY_BLOB_LOADER, LEGACY_MIGRATOR},
+};
+use crate::{database::KEYSTORE_UUID, permission};
+use crate::{
+    database::{KeyEntryLoadBits, KeyType, SubComponentType},
+    error::ResponseCode,
+};
+use crate::{
+    error::{self, map_or_log_err, ErrorCode},
+    id_rotation::IdRotationState,
+};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
+use android_hardware_security_keymint::binder::{BinderFeatures, Strong, ThreadState};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
+    IKeystoreService::BnKeystoreService, IKeystoreService::IKeystoreService,
+    KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
+};
+use anyhow::{Context, Result};
+use error::Error;
+use keystore2_selinux as selinux;
+
+/// Implementation of the IKeystoreService.
+#[derive(Default)]
+pub struct KeystoreService {
+    i_sec_level_by_uuid: HashMap<Uuid, Asp>,
+    uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
+}
+
+impl KeystoreService {
+    /// Create a new instance of the Keystore 2.0 service.
+    pub fn new_native_binder(
+        id_rotation_state: IdRotationState,
+    ) -> Result<Strong<dyn IKeystoreService>> {
+        let mut result: Self = Default::default();
+        let (dev, uuid) = KeystoreSecurityLevel::new_native_binder(
+            SecurityLevel::TRUSTED_ENVIRONMENT,
+            id_rotation_state.clone(),
+        )
+        .context(concat!(
+            "In KeystoreService::new_native_binder: ",
+            "Trying to construct mandatory security level TEE."
+        ))
+        .map(|(dev, uuid)| (Asp::new(dev.as_binder()), uuid))?;
+        result.i_sec_level_by_uuid.insert(uuid, dev);
+        result.uuid_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, uuid);
+
+        // Strongbox is optional, so we ignore errors and turn the result into an Option.
+        if let Ok((dev, uuid)) =
+            KeystoreSecurityLevel::new_native_binder(SecurityLevel::STRONGBOX, id_rotation_state)
+                .map(|(dev, uuid)| (Asp::new(dev.as_binder()), uuid))
+        {
+            result.i_sec_level_by_uuid.insert(uuid, dev);
+            result.uuid_by_sec_level.insert(SecurityLevel::STRONGBOX, uuid);
+        }
+
+        let uuid_by_sec_level = result.uuid_by_sec_level.clone();
+        LEGACY_MIGRATOR
+            .set_init(move || {
+                (create_thread_local_db(), uuid_by_sec_level, LEGACY_BLOB_LOADER.clone())
+            })
+            .context(
+                "In KeystoreService::new_native_binder: Trying to initialize the legacy migrator.",
+            )?;
+
+        Ok(BnKeystoreService::new_binder(
+            result,
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        ))
+    }
+
+    fn uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel {
+        self.uuid_by_sec_level
+            .iter()
+            .find(|(_, v)| **v == *uuid)
+            .map(|(s, _)| *s)
+            .unwrap_or(SecurityLevel::SOFTWARE)
+    }
+
+    fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
+        if let Some(dev) = self.i_sec_level_by_uuid.get(uuid) {
+            dev.get_interface().context("In get_i_sec_level_by_uuid.")
+        } else {
+            Err(error::Error::sys())
+                .context("In get_i_sec_level_by_uuid: KeyMint instance for key not found.")
+        }
+    }
+
+    fn get_security_level(
+        &self,
+        sec_level: SecurityLevel,
+    ) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
+        if let Some(dev) = self
+            .uuid_by_sec_level
+            .get(&sec_level)
+            .and_then(|uuid| self.i_sec_level_by_uuid.get(uuid))
+        {
+            dev.get_interface().context("In get_security_level.")
+        } else {
+            Err(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
+                .context("In get_security_level: No such security level.")
+        }
+    }
+
+    fn get_key_entry(&self, key: &KeyDescriptor) -> Result<KeyEntryResponse> {
+        let caller_uid = ThreadState::get_calling_uid();
+        let (key_id_guard, mut key_entry) = DB
+            .with(|db| {
+                LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+                    db.borrow_mut().load_key_entry(
+                        &key,
+                        KeyType::Client,
+                        KeyEntryLoadBits::PUBLIC,
+                        caller_uid,
+                        |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
+                    )
+                })
+            })
+            .context("In get_key_entry, while trying to load key info.")?;
+
+        let i_sec_level = if !key_entry.pure_cert() {
+            Some(
+                self.get_i_sec_level_by_uuid(key_entry.km_uuid())
+                    .context("In get_key_entry: Trying to get security level proxy.")?,
+            )
+        } else {
+            None
+        };
+
+        Ok(KeyEntryResponse {
+            iSecurityLevel: i_sec_level,
+            metadata: KeyMetadata {
+                key: KeyDescriptor {
+                    domain: Domain::KEY_ID,
+                    nspace: key_id_guard.id(),
+                    ..Default::default()
+                },
+                keySecurityLevel: self.uuid_to_sec_level(key_entry.km_uuid()),
+                certificate: key_entry.take_cert(),
+                certificateChain: key_entry.take_cert_chain(),
+                modificationTimeMs: key_entry
+                    .metadata()
+                    .creation_date()
+                    .map(|d| d.to_millis_epoch())
+                    .ok_or(Error::Rc(ResponseCode::VALUE_CORRUPTED))
+                    .context("In get_key_entry: Trying to get creation date.")?,
+                authorizations: key_parameters_to_authorizations(key_entry.into_key_parameters()),
+            },
+        })
+    }
+
+    fn update_subcomponent(
+        &self,
+        key: &KeyDescriptor,
+        public_cert: Option<&[u8]>,
+        certificate_chain: Option<&[u8]>,
+    ) -> Result<()> {
+        let caller_uid = ThreadState::get_calling_uid();
+        DB.with::<_, Result<()>>(|db| {
+            let entry = match LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+                db.borrow_mut().load_key_entry(
+                    &key,
+                    KeyType::Client,
+                    KeyEntryLoadBits::NONE,
+                    caller_uid,
+                    |k, av| {
+                        check_key_permission(KeyPerm::update(), k, &av)
+                            .context("In update_subcomponent.")
+                    },
+                )
+            }) {
+                Err(e) => match e.root_cause().downcast_ref::<Error>() {
+                    Some(Error::Rc(ResponseCode::KEY_NOT_FOUND)) => Ok(None),
+                    _ => Err(e),
+                },
+                Ok(v) => Ok(Some(v)),
+            }
+            .context("Failed to load key entry.")?;
+
+            let mut db = db.borrow_mut();
+            if let Some((key_id_guard, _key_entry)) = entry {
+                db.set_blob(&key_id_guard, SubComponentType::CERT, public_cert, None)
+                    .context("Failed to update cert subcomponent.")?;
+
+                db.set_blob(&key_id_guard, SubComponentType::CERT_CHAIN, certificate_chain, None)
+                    .context("Failed to update cert chain subcomponent.")?;
+                return Ok(());
+            }
+
+            // If we reach this point we have to check the special condition where a certificate
+            // entry may be made.
+            if !(public_cert.is_none() && certificate_chain.is_some()) {
+                return Err(Error::Rc(ResponseCode::KEY_NOT_FOUND)).context("No key to update.");
+            }
+
+            // So we know that we have a certificate chain and no public cert.
+            // Now check that we have everything we need to make a new certificate entry.
+            let key = match (key.domain, &key.alias) {
+                (Domain::APP, Some(ref alias)) => KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: ThreadState::get_calling_uid() as i64,
+                    alias: Some(alias.clone()),
+                    blob: None,
+                },
+                (Domain::SELINUX, Some(_)) => key.clone(),
+                _ => {
+                    return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT))
+                        .context("Domain must be APP or SELINUX to insert a certificate.")
+                }
+            };
+
+            // Security critical: This must return on failure. Do not remove the `?`;
+            check_key_permission(KeyPerm::rebind(), &key, &None)
+                .context("Caller does not have permission to insert this certificate.")?;
+
+            db.store_new_certificate(&key, certificate_chain.unwrap(), &KEYSTORE_UUID)
+                .context("Failed to insert new certificate.")?;
+            Ok(())
+        })
+        .context("In update_subcomponent.")
+    }
+
+    fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
+        let mut k = match domain {
+            Domain::APP => KeyDescriptor {
+                domain,
+                nspace: ThreadState::get_calling_uid() as u64 as i64,
+                ..Default::default()
+            },
+            Domain::SELINUX => KeyDescriptor{domain, nspace: namespace, ..Default::default()},
+            _ => return Err(Error::perm()).context(
+                "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX."
+            ),
+        };
+
+        // First we check if the caller has the info permission for the selected domain/namespace.
+        // By default we use the calling uid as namespace if domain is Domain::APP.
+        // If the first check fails we check if the caller has the list permission allowing to list
+        // any namespace. In that case we also adjust the queried namespace if a specific uid was
+        // selected.
+        match check_key_permission(KeyPerm::get_info(), &k, &None) {
+            Err(e) => {
+                if let Some(selinux::Error::PermissionDenied) =
+                    e.root_cause().downcast_ref::<selinux::Error>()
+                {
+                    check_keystore_permission(KeystorePerm::list())
+                        .context("In list_entries: While checking keystore permission.")?;
+                    if namespace != -1 {
+                        k.nspace = namespace;
+                    }
+                } else {
+                    return Err(e).context("In list_entries: While checking key permission.")?;
+                }
+            }
+            Ok(()) => {}
+        };
+
+        let mut result = LEGACY_MIGRATOR
+            .list_uid(k.domain, k.nspace)
+            .context("In list_entries: Trying to list legacy keys.")?;
+
+        result.append(
+            &mut DB
+                .with(|db| {
+                    let mut db = db.borrow_mut();
+                    db.list(k.domain, k.nspace)
+                })
+                .context("In list_entries: Trying to list keystore database.")?,
+        );
+
+        result.sort_unstable();
+        result.dedup();
+        Ok(result)
+    }
+
+    fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
+        let caller_uid = ThreadState::get_calling_uid();
+        DB.with(|db| {
+            LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+                db.borrow_mut().unbind_key(&key, KeyType::Client, caller_uid, |k, av| {
+                    check_key_permission(KeyPerm::delete(), k, &av).context("During delete_key.")
+                })
+            })
+        })
+        .context("In delete_key: Trying to unbind the key.")?;
+        Ok(())
+    }
+
+    fn grant(
+        &self,
+        key: &KeyDescriptor,
+        grantee_uid: i32,
+        access_vector: permission::KeyPermSet,
+    ) -> Result<KeyDescriptor> {
+        let caller_uid = ThreadState::get_calling_uid();
+        DB.with(|db| {
+            LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+                db.borrow_mut().grant(
+                    &key,
+                    caller_uid,
+                    grantee_uid as u32,
+                    access_vector,
+                    |k, av| check_grant_permission(*av, k).context("During grant."),
+                )
+            })
+        })
+        .context("In KeystoreService::grant.")
+    }
+
+    fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
+        DB.with(|db| {
+            db.borrow_mut().ungrant(&key, ThreadState::get_calling_uid(), grantee_uid as u32, |k| {
+                check_key_permission(KeyPerm::grant(), k, &None)
+            })
+        })
+        .context("In KeystoreService::ungrant.")
+    }
+}
+
+impl binder::Interface for KeystoreService {}
+
+// Implementation of IKeystoreService. See AIDL spec at
+// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
+impl IKeystoreService for KeystoreService {
+    fn getSecurityLevel(
+        &self,
+        security_level: SecurityLevel,
+    ) -> binder::public_api::Result<Strong<dyn IKeystoreSecurityLevel>> {
+        let _wp = wd::watch_millis_with("IKeystoreService::getSecurityLevel", 500, move || {
+            format!("security_level: {}", security_level.0)
+        });
+        map_or_log_err(self.get_security_level(security_level), Ok)
+    }
+    fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {
+        let _wp = wd::watch_millis("IKeystoreService::get_key_entry", 500);
+        map_or_log_err(self.get_key_entry(key), Ok)
+    }
+    fn updateSubcomponent(
+        &self,
+        key: &KeyDescriptor,
+        public_cert: Option<&[u8]>,
+        certificate_chain: Option<&[u8]>,
+    ) -> binder::public_api::Result<()> {
+        let _wp = wd::watch_millis("IKeystoreService::updateSubcomponent", 500);
+        map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
+    }
+    fn listEntries(
+        &self,
+        domain: Domain,
+        namespace: i64,
+    ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
+        let _wp = wd::watch_millis("IKeystoreService::listEntries", 500);
+        map_or_log_err(self.list_entries(domain, namespace), Ok)
+    }
+    fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
+        let _wp = wd::watch_millis("IKeystoreService::deleteKey", 500);
+        let result = self.delete_key(key);
+        log_key_deleted(key, ThreadState::get_calling_uid(), result.is_ok());
+        map_or_log_err(result, Ok)
+    }
+    fn grant(
+        &self,
+        key: &KeyDescriptor,
+        grantee_uid: i32,
+        access_vector: i32,
+    ) -> binder::public_api::Result<KeyDescriptor> {
+        let _wp = wd::watch_millis("IKeystoreService::grant", 500);
+        map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
+    }
+    fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
+        let _wp = wd::watch_millis("IKeystoreService::ungrant", 500);
+        map_or_log_err(self.ungrant(key, grantee_uid), Ok)
+    }
+}
diff --git a/keystore2/src/shared_secret_negotiation.rs b/keystore2/src/shared_secret_negotiation.rs
new file mode 100644
index 0000000..fb55f33
--- /dev/null
+++ b/keystore2/src/shared_secret_negotiation.rs
@@ -0,0 +1,265 @@
+// Copyright 2021, 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.
+
+//! This module implements the shared secret negotiation.
+
+use crate::error::{map_binder_status, map_binder_status_code, Error};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
+use android_hardware_security_keymint::binder::Strong;
+use android_hardware_security_sharedsecret::aidl::android::hardware::security::sharedsecret::{
+    ISharedSecret::ISharedSecret, SharedSecretParameters::SharedSecretParameters,
+};
+use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
+use anyhow::{Context, Result};
+use keystore2_vintf::{get_aidl_instances, get_hidl_instances};
+use std::fmt::{self, Display, Formatter};
+
+/// This function initiates the shared secret negotiation. It starts a thread and then returns
+/// immediately. The thread consults the vintf manifest to enumerate expected negotiation
+/// participants. It then attempts to connect to all of these participants. If any connection
+/// fails the thread will retry once per second to connect to the failed instance(s) until all of
+/// the instances are connected. It then performs the negotiation.
+///
+/// During the first phase of the negotiation it will again try every second until
+/// all instances have responded successfully to account for instances that register early but
+/// are not fully functioning at this time due to hardware delays or boot order dependency issues.
+/// An error during the second phase or a checksum mismatch leads to a panic.
+pub fn perform_shared_secret_negotiation() {
+    std::thread::spawn(|| {
+        let participants = list_participants()
+            .expect("In perform_shared_secret_negotiation: Trying to list participants.");
+        let connected = connect_participants(participants);
+        negotiate_shared_secret(connected);
+        log::info!("Shared secret negotiation concluded successfully.");
+    });
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+enum SharedSecretParticipant {
+    /// Represents an instance of android.hardware.security.sharedsecret.ISharedSecret.
+    Aidl(String),
+    /// In the legacy case there can be at most one TEE and one Strongbox hal.
+    Hidl { is_strongbox: bool, version: (usize, usize) },
+}
+
+impl Display for SharedSecretParticipant {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        match self {
+            Self::Aidl(instance) => write!(
+                f,
+                "{}.{}/{}",
+                SHARED_SECRET_PACKAGE_NAME, SHARED_SECRET_INTERFACE_NAME, instance
+            ),
+            Self::Hidl { is_strongbox, version: (ma, mi) } => write!(
+                f,
+                "{}@V{}.{}::{}/{}",
+                KEYMASTER_PACKAGE_NAME,
+                ma,
+                mi,
+                KEYMASTER_INTERFACE_NAME,
+                if *is_strongbox { "strongbox" } else { "default" }
+            ),
+        }
+    }
+}
+
+#[derive(thiserror::Error, Debug)]
+enum SharedSecretError {
+    #[error("Shared parameter retrieval failed on instance {p} with error {e:?}.")]
+    ParameterRetrieval { e: Error, p: SharedSecretParticipant },
+    #[error("Shared secret computation failed on instance {p} with error {e:?}.")]
+    Computation { e: Error, p: SharedSecretParticipant },
+    #[error("Checksum comparison failed on instance {0}.")]
+    Checksum(SharedSecretParticipant),
+}
+
+fn filter_map_legacy_km_instances(
+    name: String,
+    version: (usize, usize),
+) -> Option<SharedSecretParticipant> {
+    match name.as_str() {
+        "default" => Some(SharedSecretParticipant::Hidl { is_strongbox: false, version }),
+        "strongbox" => Some(SharedSecretParticipant::Hidl { is_strongbox: true, version }),
+        _ => {
+            log::warn!("Found unexpected keymaster instance: \"{}\"", name);
+            log::warn!("Device is misconfigured. Allowed instances are:");
+            log::warn!("   * default");
+            log::warn!("   * strongbox");
+            None
+        }
+    }
+}
+
+static KEYMASTER_PACKAGE_NAME: &str = "android.hardware.keymaster";
+static KEYMASTER_INTERFACE_NAME: &str = "IKeymasterDevice";
+static SHARED_SECRET_PACKAGE_NAME: &str = "android.hardware.security.sharedsecret";
+static SHARED_SECRET_INTERFACE_NAME: &str = "ISharedSecret";
+static COMPAT_PACKAGE_NAME: &str = "android.security.compat";
+
+/// Lists participants.
+fn list_participants() -> Result<Vec<SharedSecretParticipant>> {
+    Ok([(4, 0), (4, 1)]
+        .iter()
+        .map(|(ma, mi)| {
+            get_hidl_instances(KEYMASTER_PACKAGE_NAME, *ma, *mi, KEYMASTER_INTERFACE_NAME)
+                .as_vec()
+                .with_context(|| format!("Trying to convert KM{}.{} names to vector.", *ma, *mi))
+                .map(|instances| {
+                    instances
+                        .into_iter()
+                        .filter_map(|name| {
+                            filter_map_legacy_km_instances(name.to_string(), (*ma, *mi))
+                        })
+                        .collect::<Vec<SharedSecretParticipant>>()
+                })
+        })
+        .collect::<Result<Vec<_>>>()
+        .map(|v| v.into_iter().flatten())
+        .and_then(|i| {
+            let participants_aidl: Vec<SharedSecretParticipant> =
+                get_aidl_instances(SHARED_SECRET_PACKAGE_NAME, 1, SHARED_SECRET_INTERFACE_NAME)
+                    .as_vec()
+                    .context("In list_participants: Trying to convert KM1.0 names to vector.")?
+                    .into_iter()
+                    .map(|name| SharedSecretParticipant::Aidl(name.to_string()))
+                    .collect();
+            Ok(i.chain(participants_aidl.into_iter()))
+        })
+        .context("In list_participants.")?
+        .collect())
+}
+
+fn connect_participants(
+    mut participants: Vec<SharedSecretParticipant>,
+) -> Vec<(Strong<dyn ISharedSecret>, SharedSecretParticipant)> {
+    let mut connected_participants: Vec<(Strong<dyn ISharedSecret>, SharedSecretParticipant)> =
+        vec![];
+    loop {
+        let (connected, not_connected) = participants.into_iter().fold(
+            (connected_participants, vec![]),
+            |(mut connected, mut failed), e| {
+                match e {
+                    SharedSecretParticipant::Aidl(instance_name) => {
+                        let service_name = format!(
+                            "{}.{}/{}",
+                            SHARED_SECRET_PACKAGE_NAME, SHARED_SECRET_INTERFACE_NAME, instance_name
+                        );
+                        match map_binder_status_code(binder::get_interface(&service_name)) {
+                            Err(e) => {
+                                log::warn!(
+                                    "Unable to connect \"{}\" with error:\n{:?}\nRetrying later.",
+                                    service_name,
+                                    e
+                                );
+                                failed.push(SharedSecretParticipant::Aidl(instance_name));
+                            }
+                            Ok(service) => connected
+                                .push((service, SharedSecretParticipant::Aidl(instance_name))),
+                        }
+                    }
+                    SharedSecretParticipant::Hidl { is_strongbox, version } => {
+                        // This is a no-op if it was called before.
+                        keystore2_km_compat::add_keymint_device_service();
+
+                        // If we cannot connect to the compatibility service there is no way to
+                        // recover.
+                        // PANIC! - Unless you brought your towel.
+                        let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
+                            map_binder_status_code(binder::get_interface(COMPAT_PACKAGE_NAME))
+                                .expect(
+                                    "In connect_participants: Trying to connect to compat service.",
+                                );
+
+                        match map_binder_status(keystore_compat_service.getSharedSecret(
+                            if is_strongbox {
+                                SecurityLevel::STRONGBOX
+                            } else {
+                                SecurityLevel::TRUSTED_ENVIRONMENT
+                            },
+                        )) {
+                            Err(e) => {
+                                log::warn!(
+                                    concat!(
+                                        "Unable to connect keymaster device \"{}\" ",
+                                        "with error:\n{:?}\nRetrying later."
+                                    ),
+                                    if is_strongbox { "strongbox" } else { "TEE" },
+                                    e
+                                );
+                                failed
+                                    .push(SharedSecretParticipant::Hidl { is_strongbox, version });
+                            }
+                            Ok(service) => connected.push((
+                                service,
+                                SharedSecretParticipant::Hidl { is_strongbox, version },
+                            )),
+                        }
+                    }
+                }
+                (connected, failed)
+            },
+        );
+        participants = not_connected;
+        connected_participants = connected;
+        if participants.is_empty() {
+            break;
+        }
+        std::thread::sleep(std::time::Duration::from_millis(1000));
+    }
+    connected_participants
+}
+
+fn negotiate_shared_secret(
+    participants: Vec<(Strong<dyn ISharedSecret>, SharedSecretParticipant)>,
+) {
+    // Phase 1: Get the sharing parameters from all participants.
+    let mut params = loop {
+        let result: Result<Vec<SharedSecretParameters>, SharedSecretError> = participants
+            .iter()
+            .map(|(s, p)| {
+                map_binder_status(s.getSharedSecretParameters())
+                    .map_err(|e| SharedSecretError::ParameterRetrieval { e, p: (*p).clone() })
+            })
+            .collect();
+
+        match result {
+            Err(e) => {
+                log::warn!("{:?}", e);
+                log::warn!("Retrying in one second.");
+                std::thread::sleep(std::time::Duration::from_millis(1000));
+            }
+            Ok(params) => break params,
+        }
+    };
+
+    params.sort_unstable();
+
+    // Phase 2: Send the sorted sharing parameters to all participants.
+    participants
+        .into_iter()
+        .try_fold(None, |acc, (s, p)| {
+            match (acc, map_binder_status(s.computeSharedSecret(&params))) {
+                (None, Ok(new_sum)) => Ok(Some(new_sum)),
+                (Some(old_sum), Ok(new_sum)) => {
+                    if old_sum == new_sum {
+                        Ok(Some(old_sum))
+                    } else {
+                        Err(SharedSecretError::Checksum(p))
+                    }
+                }
+                (_, Err(e)) => Err(SharedSecretError::Computation { e, p }),
+            }
+        })
+        .expect("Fatal: Shared secret computation failed.");
+}
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
new file mode 100644
index 0000000..848707c
--- /dev/null
+++ b/keystore2/src/super_key.rs
@@ -0,0 +1,1199 @@
+// Copyright 2020, 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.
+
+use crate::{
+    boot_level_keys::{get_level_zero_key, BootLevelKeyCache},
+    database::BlobMetaData,
+    database::BlobMetaEntry,
+    database::EncryptedBy,
+    database::KeyEntry,
+    database::KeyType,
+    database::{KeyIdGuard, KeyMetaData, KeyMetaEntry, KeystoreDB},
+    ec_crypto::ECDHPrivateKey,
+    enforcements::Enforcements,
+    error::Error,
+    error::ResponseCode,
+    key_parameter::{KeyParameter, KeyParameterValue},
+    legacy_blob::LegacyBlobLoader,
+    legacy_migrator::LegacyMigrator,
+    raw_device::KeyMintDevice,
+    try_insert::TryInsert,
+    utils::watchdog as wd,
+};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, BlockMode::BlockMode, HardwareAuthToken::HardwareAuthToken,
+    HardwareAuthenticatorType::HardwareAuthenticatorType, KeyFormat::KeyFormat,
+    KeyParameter::KeyParameter as KmKeyParameter, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
+    SecurityLevel::SecurityLevel,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Domain::Domain, KeyDescriptor::KeyDescriptor,
+};
+use anyhow::{Context, Result};
+use keystore2_crypto::{
+    aes_gcm_decrypt, aes_gcm_encrypt, generate_aes256_key, generate_salt, Password, ZVec,
+    AES_256_KEY_LENGTH,
+};
+use keystore2_system_property::PropertyWatcher;
+use std::{
+    collections::HashMap,
+    sync::Arc,
+    sync::{Mutex, Weak},
+};
+use std::{convert::TryFrom, ops::Deref};
+
+const MAX_MAX_BOOT_LEVEL: usize = 1_000_000_000;
+/// Allow up to 15 seconds between the user unlocking using a biometric, and the auth
+/// token being used to unlock in [`SuperKeyManager::try_unlock_user_with_biometric`].
+/// This seems short enough for security purposes, while long enough that even the
+/// very slowest device will present the auth token in time.
+const BIOMETRIC_AUTH_TIMEOUT_S: i32 = 15; // seconds
+
+type UserId = u32;
+
+/// Encryption algorithm used by a particular type of superencryption key
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum SuperEncryptionAlgorithm {
+    /// Symmetric encryption with AES-256-GCM
+    Aes256Gcm,
+    /// Public-key encryption with ECDH P-256
+    EcdhP256,
+}
+
+/// A particular user may have several superencryption keys in the database, each for a
+/// different purpose, distinguished by alias. Each is associated with a static
+/// constant of this type.
+pub struct SuperKeyType {
+    /// Alias used to look the key up in the `persistent.keyentry` table.
+    pub alias: &'static str,
+    /// Encryption algorithm
+    pub algorithm: SuperEncryptionAlgorithm,
+}
+
+/// Key used for LskfLocked keys; the corresponding superencryption key is loaded in memory
+/// when the user first unlocks, and remains in memory until the device reboots.
+pub const USER_SUPER_KEY: SuperKeyType =
+    SuperKeyType { alias: "USER_SUPER_KEY", algorithm: SuperEncryptionAlgorithm::Aes256Gcm };
+/// Key used for ScreenLockBound keys; the corresponding superencryption key is loaded in memory
+/// each time the user enters their LSKF, and cleared from memory each time the device is locked.
+/// Symmetric.
+pub const USER_SCREEN_LOCK_BOUND_KEY: SuperKeyType = SuperKeyType {
+    alias: "USER_SCREEN_LOCK_BOUND_KEY",
+    algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
+};
+/// Key used for ScreenLockBound keys; the corresponding superencryption key is loaded in memory
+/// each time the user enters their LSKF, and cleared from memory each time the device is locked.
+/// Asymmetric, so keys can be encrypted when the device is locked.
+pub const USER_SCREEN_LOCK_BOUND_ECDH_KEY: SuperKeyType = SuperKeyType {
+    alias: "USER_SCREEN_LOCK_BOUND_ECDH_KEY",
+    algorithm: SuperEncryptionAlgorithm::EcdhP256,
+};
+
+/// Superencryption to apply to a new key.
+#[derive(Debug, Clone, Copy)]
+pub enum SuperEncryptionType {
+    /// Do not superencrypt this key.
+    None,
+    /// Superencrypt with a key that remains in memory from first unlock to reboot.
+    LskfBound,
+    /// Superencrypt with a key cleared from memory when the device is locked.
+    ScreenLockBound,
+    /// Superencrypt with a key based on the desired boot level
+    BootLevel(i32),
+}
+
+#[derive(Debug, Clone, Copy)]
+pub enum SuperKeyIdentifier {
+    /// id of the super key in the database.
+    DatabaseId(i64),
+    /// Boot level of the encrypting boot level key
+    BootLevel(i32),
+}
+
+impl SuperKeyIdentifier {
+    fn from_metadata(metadata: &BlobMetaData) -> Option<Self> {
+        if let Some(EncryptedBy::KeyId(key_id)) = metadata.encrypted_by() {
+            Some(SuperKeyIdentifier::DatabaseId(*key_id))
+        } else if let Some(boot_level) = metadata.max_boot_level() {
+            Some(SuperKeyIdentifier::BootLevel(*boot_level))
+        } else {
+            None
+        }
+    }
+
+    fn add_to_metadata(&self, metadata: &mut BlobMetaData) {
+        match self {
+            SuperKeyIdentifier::DatabaseId(id) => {
+                metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(*id)));
+            }
+            SuperKeyIdentifier::BootLevel(level) => {
+                metadata.add(BlobMetaEntry::MaxBootLevel(*level));
+            }
+        }
+    }
+}
+
+pub struct SuperKey {
+    algorithm: SuperEncryptionAlgorithm,
+    key: ZVec,
+    /// Identifier of the encrypting key, used to write an encrypted blob
+    /// back to the database after re-encryption eg on a key update.
+    id: SuperKeyIdentifier,
+    /// ECDH is more expensive than AES. So on ECDH private keys we set the
+    /// reencrypt_with field to point at the corresponding AES key, and the
+    /// keys will be re-encrypted with AES on first use.
+    reencrypt_with: Option<Arc<SuperKey>>,
+}
+
+impl SuperKey {
+    /// For most purposes `unwrap_key` handles decryption,
+    /// but legacy handling and some tests need to assume AES and decrypt directly.
+    pub fn aes_gcm_decrypt(&self, data: &[u8], iv: &[u8], tag: &[u8]) -> Result<ZVec> {
+        if self.algorithm == SuperEncryptionAlgorithm::Aes256Gcm {
+            aes_gcm_decrypt(data, iv, tag, &self.key)
+                .context("In aes_gcm_decrypt: decryption failed")
+        } else {
+            Err(Error::sys()).context("In aes_gcm_decrypt: Key is not an AES key")
+        }
+    }
+}
+
+/// A SuperKey that has been encrypted with an AES-GCM key. For
+/// encryption the key is in memory, and for decryption it is in KM.
+struct LockedKey {
+    algorithm: SuperEncryptionAlgorithm,
+    id: SuperKeyIdentifier,
+    nonce: Vec<u8>,
+    ciphertext: Vec<u8>, // with tag appended
+}
+
+impl LockedKey {
+    fn new(key: &[u8], to_encrypt: &Arc<SuperKey>) -> Result<Self> {
+        let (mut ciphertext, nonce, mut tag) = aes_gcm_encrypt(&to_encrypt.key, key)?;
+        ciphertext.append(&mut tag);
+        Ok(LockedKey { algorithm: to_encrypt.algorithm, id: to_encrypt.id, nonce, ciphertext })
+    }
+
+    fn decrypt(
+        &self,
+        db: &mut KeystoreDB,
+        km_dev: &KeyMintDevice,
+        key_id_guard: &KeyIdGuard,
+        key_entry: &KeyEntry,
+        auth_token: &HardwareAuthToken,
+        reencrypt_with: Option<Arc<SuperKey>>,
+    ) -> Result<Arc<SuperKey>> {
+        let key_params = vec![
+            KeyParameterValue::Algorithm(Algorithm::AES),
+            KeyParameterValue::KeySize(256),
+            KeyParameterValue::BlockMode(BlockMode::GCM),
+            KeyParameterValue::PaddingMode(PaddingMode::NONE),
+            KeyParameterValue::Nonce(self.nonce.clone()),
+            KeyParameterValue::MacLength(128),
+        ];
+        let key_params: Vec<KmKeyParameter> = key_params.into_iter().map(|x| x.into()).collect();
+        let key = ZVec::try_from(km_dev.use_key_in_one_step(
+            db,
+            key_id_guard,
+            key_entry,
+            KeyPurpose::DECRYPT,
+            &key_params,
+            Some(auth_token),
+            &self.ciphertext,
+        )?)?;
+        Ok(Arc::new(SuperKey { algorithm: self.algorithm, key, id: self.id, reencrypt_with }))
+    }
+}
+
+/// Keys for unlocking UNLOCKED_DEVICE_REQUIRED keys, as LockedKeys, complete with
+/// a database descriptor for the encrypting key and the sids for the auth tokens
+/// that can be used to decrypt it.
+struct BiometricUnlock {
+    /// List of auth token SIDs that can be used to unlock these keys.
+    sids: Vec<i64>,
+    /// Database descriptor of key to use to unlock.
+    key_desc: KeyDescriptor,
+    /// Locked versions of the matching UserSuperKeys fields
+    screen_lock_bound: LockedKey,
+    screen_lock_bound_private: LockedKey,
+}
+
+#[derive(Default)]
+struct UserSuperKeys {
+    /// The per boot key is used for LSKF binding of authentication bound keys. There is one
+    /// key per android user. The key is stored on flash encrypted with a key derived from a
+    /// secret, that is itself derived from the user's lock screen knowledge factor (LSKF).
+    /// When the user unlocks the device for the first time, this key is unlocked, i.e., decrypted,
+    /// and stays memory resident until the device reboots.
+    per_boot: Option<Arc<SuperKey>>,
+    /// The screen lock key works like the per boot key with the distinction that it is cleared
+    /// from memory when the screen lock is engaged.
+    screen_lock_bound: Option<Arc<SuperKey>>,
+    /// When the device is locked, screen-lock-bound keys can still be encrypted, using
+    /// ECDH public-key encryption. This field holds the decryption private key.
+    screen_lock_bound_private: Option<Arc<SuperKey>>,
+    /// Versions of the above two keys, locked behind a biometric.
+    biometric_unlock: Option<BiometricUnlock>,
+}
+
+#[derive(Default)]
+struct SkmState {
+    user_keys: HashMap<UserId, UserSuperKeys>,
+    key_index: HashMap<i64, Weak<SuperKey>>,
+    boot_level_key_cache: Option<BootLevelKeyCache>,
+}
+
+impl SkmState {
+    fn add_key_to_key_index(&mut self, super_key: &Arc<SuperKey>) -> Result<()> {
+        if let SuperKeyIdentifier::DatabaseId(id) = super_key.id {
+            self.key_index.insert(id, Arc::downgrade(super_key));
+            Ok(())
+        } else {
+            Err(Error::sys()).context(format!(
+                "In add_key_to_key_index: cannot add key with ID {:?}",
+                super_key.id
+            ))
+        }
+    }
+}
+
+#[derive(Default)]
+pub struct SuperKeyManager {
+    data: Mutex<SkmState>,
+}
+
+impl SuperKeyManager {
+    pub fn set_up_boot_level_cache(self: &Arc<Self>, db: &mut KeystoreDB) -> Result<()> {
+        let mut data = self.data.lock().unwrap();
+        if data.boot_level_key_cache.is_some() {
+            log::info!("In set_up_boot_level_cache: called for a second time");
+            return Ok(());
+        }
+        let level_zero_key = get_level_zero_key(db)
+            .context("In set_up_boot_level_cache: get_level_zero_key failed")?;
+        data.boot_level_key_cache = Some(BootLevelKeyCache::new(level_zero_key));
+        log::info!("Starting boot level watcher.");
+        let clone = self.clone();
+        std::thread::spawn(move || {
+            clone
+                .watch_boot_level()
+                .unwrap_or_else(|e| log::error!("watch_boot_level failed:\n{:?}", e));
+        });
+        Ok(())
+    }
+
+    /// Watch the `keystore.boot_level` system property, and keep boot level up to date.
+    /// Blocks waiting for system property changes, so must be run in its own thread.
+    fn watch_boot_level(&self) -> Result<()> {
+        let mut w = PropertyWatcher::new("keystore.boot_level")
+            .context("In watch_boot_level: PropertyWatcher::new failed")?;
+        loop {
+            let level = w
+                .read(|_n, v| v.parse::<usize>().map_err(std::convert::Into::into))
+                .context("In watch_boot_level: read of property failed")?;
+            // watch_boot_level should only be called once data.boot_level_key_cache is Some,
+            // so it's safe to unwrap in the branches below.
+            if level < MAX_MAX_BOOT_LEVEL {
+                log::info!("Read keystore.boot_level value {}", level);
+                let mut data = self.data.lock().unwrap();
+                data.boot_level_key_cache
+                    .as_mut()
+                    .unwrap()
+                    .advance_boot_level(level)
+                    .context("In watch_boot_level: advance_boot_level failed")?;
+            } else {
+                log::info!(
+                    "keystore.boot_level {} hits maximum {}, finishing.",
+                    level,
+                    MAX_MAX_BOOT_LEVEL
+                );
+                let mut data = self.data.lock().unwrap();
+                data.boot_level_key_cache.as_mut().unwrap().finish();
+                break;
+            }
+            w.wait().context("In watch_boot_level: property wait failed")?;
+        }
+        Ok(())
+    }
+
+    pub fn level_accessible(&self, boot_level: i32) -> bool {
+        self.data
+            .lock()
+            .unwrap()
+            .boot_level_key_cache
+            .as_ref()
+            .map_or(false, |c| c.level_accessible(boot_level as usize))
+    }
+
+    pub fn forget_all_keys_for_user(&self, user: UserId) {
+        let mut data = self.data.lock().unwrap();
+        data.user_keys.remove(&user);
+    }
+
+    fn install_per_boot_key_for_user(&self, user: UserId, super_key: Arc<SuperKey>) -> Result<()> {
+        let mut data = self.data.lock().unwrap();
+        data.add_key_to_key_index(&super_key)
+            .context("In install_per_boot_key_for_user: add_key_to_key_index failed")?;
+        data.user_keys.entry(user).or_default().per_boot = Some(super_key);
+        Ok(())
+    }
+
+    fn lookup_key(&self, key_id: &SuperKeyIdentifier) -> Result<Option<Arc<SuperKey>>> {
+        let mut data = self.data.lock().unwrap();
+        Ok(match key_id {
+            SuperKeyIdentifier::DatabaseId(id) => data.key_index.get(id).and_then(|k| k.upgrade()),
+            SuperKeyIdentifier::BootLevel(level) => data
+                .boot_level_key_cache
+                .as_mut()
+                .map(|b| b.aes_key(*level as usize))
+                .transpose()
+                .context("In lookup_key: aes_key failed")?
+                .flatten()
+                .map(|key| {
+                    Arc::new(SuperKey {
+                        algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
+                        key,
+                        id: *key_id,
+                        reencrypt_with: None,
+                    })
+                }),
+        })
+    }
+
+    pub fn get_per_boot_key_by_user_id(&self, user_id: UserId) -> Option<Arc<SuperKey>> {
+        let data = self.data.lock().unwrap();
+        data.user_keys.get(&user_id).and_then(|e| e.per_boot.as_ref().cloned())
+    }
+
+    /// This function unlocks the super keys for a given user.
+    /// This means the key is loaded from the database, decrypted and placed in the
+    /// super key cache. If there is no such key a new key is created, encrypted with
+    /// a key derived from the given password and stored in the database.
+    pub fn unlock_user_key(
+        &self,
+        db: &mut KeystoreDB,
+        user: UserId,
+        pw: &Password,
+        legacy_blob_loader: &LegacyBlobLoader,
+    ) -> Result<()> {
+        let (_, entry) = db
+            .get_or_create_key_with(
+                Domain::APP,
+                user as u64 as i64,
+                &USER_SUPER_KEY.alias,
+                crate::database::KEYSTORE_UUID,
+                || {
+                    // For backward compatibility we need to check if there is a super key present.
+                    let super_key = legacy_blob_loader
+                        .load_super_key(user, pw)
+                        .context("In create_new_key: Failed to load legacy key blob.")?;
+                    let super_key = match super_key {
+                        None => {
+                            // No legacy file was found. So we generate a new key.
+                            generate_aes256_key()
+                                .context("In create_new_key: Failed to generate AES 256 key.")?
+                        }
+                        Some(key) => key,
+                    };
+                    // Regardless of whether we loaded an old AES128 key or generated a new AES256
+                    // key as the super key, we derive a AES256 key from the password and re-encrypt
+                    // the super key before we insert it in the database. The length of the key is
+                    // preserved by the encryption so we don't need any extra flags to inform us
+                    // which algorithm to use it with.
+                    Self::encrypt_with_password(&super_key, pw).context("In create_new_key.")
+                },
+            )
+            .context("In unlock_user_key: Failed to get key id.")?;
+
+        self.populate_cache_from_super_key_blob(user, USER_SUPER_KEY.algorithm, entry, pw)
+            .context("In unlock_user_key.")?;
+        Ok(())
+    }
+
+    /// Check if a given key is super-encrypted, from its metadata. If so, unwrap the key using
+    /// the relevant super key.
+    pub fn unwrap_key_if_required<'a>(
+        &self,
+        metadata: &BlobMetaData,
+        blob: &'a [u8],
+    ) -> Result<KeyBlob<'a>> {
+        Ok(if let Some(key_id) = SuperKeyIdentifier::from_metadata(metadata) {
+            let super_key = self
+                .lookup_key(&key_id)
+                .context("In unwrap_key: lookup_key failed")?
+                .ok_or(Error::Rc(ResponseCode::LOCKED))
+                .context("In unwrap_key: Required super decryption key is not in memory.")?;
+            KeyBlob::Sensitive {
+                key: Self::unwrap_key_with_key(blob, metadata, &super_key)
+                    .context("In unwrap_key: unwrap_key_with_key failed")?,
+                reencrypt_with: super_key.reencrypt_with.as_ref().unwrap_or(&super_key).clone(),
+                force_reencrypt: super_key.reencrypt_with.is_some(),
+            }
+        } else {
+            KeyBlob::Ref(blob)
+        })
+    }
+
+    /// Unwraps an encrypted key blob given an encryption key.
+    fn unwrap_key_with_key(blob: &[u8], metadata: &BlobMetaData, key: &SuperKey) -> Result<ZVec> {
+        match key.algorithm {
+            SuperEncryptionAlgorithm::Aes256Gcm => match (metadata.iv(), metadata.aead_tag()) {
+                (Some(iv), Some(tag)) => key
+                    .aes_gcm_decrypt(blob, iv, tag)
+                    .context("In unwrap_key_with_key: Failed to decrypt the key blob."),
+                (iv, tag) => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
+                    concat!(
+                        "In unwrap_key_with_key: Key has incomplete metadata.",
+                        "Present: iv: {}, aead_tag: {}."
+                    ),
+                    iv.is_some(),
+                    tag.is_some(),
+                )),
+            },
+            SuperEncryptionAlgorithm::EcdhP256 => {
+                match (metadata.public_key(), metadata.salt(), metadata.iv(), metadata.aead_tag()) {
+                    (Some(public_key), Some(salt), Some(iv), Some(aead_tag)) => {
+                        ECDHPrivateKey::from_private_key(&key.key)
+                            .and_then(|k| k.decrypt_message(public_key, salt, iv, blob, aead_tag))
+                            .context(
+                                "In unwrap_key_with_key: Failed to decrypt the key blob with ECDH.",
+                            )
+                    }
+                    (public_key, salt, iv, aead_tag) => {
+                        Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
+                            concat!(
+                                "In unwrap_key_with_key: Key has incomplete metadata.",
+                                "Present: public_key: {}, salt: {}, iv: {}, aead_tag: {}."
+                            ),
+                            public_key.is_some(),
+                            salt.is_some(),
+                            iv.is_some(),
+                            aead_tag.is_some(),
+                        ))
+                    }
+                }
+            }
+        }
+    }
+
+    /// Checks if user has setup LSKF, even when super key cache is empty for the user.
+    pub fn super_key_exists_in_db_for_user(
+        db: &mut KeystoreDB,
+        legacy_migrator: &LegacyMigrator,
+        user_id: UserId,
+    ) -> Result<bool> {
+        let key_in_db = db
+            .key_exists(Domain::APP, user_id as u64 as i64, &USER_SUPER_KEY.alias, KeyType::Super)
+            .context("In super_key_exists_in_db_for_user.")?;
+
+        if key_in_db {
+            Ok(key_in_db)
+        } else {
+            legacy_migrator
+                .has_super_key(user_id)
+                .context("In super_key_exists_in_db_for_user: Trying to query legacy db.")
+        }
+    }
+
+    /// Checks if user has already setup LSKF (i.e. a super key is persisted in the database or the
+    /// legacy database). If not, return Uninitialized state.
+    /// Otherwise, decrypt the super key from the password and return LskfUnlocked state.
+    pub fn check_and_unlock_super_key(
+        &self,
+        db: &mut KeystoreDB,
+        legacy_migrator: &LegacyMigrator,
+        user_id: UserId,
+        pw: &Password,
+    ) -> Result<UserState> {
+        let alias = &USER_SUPER_KEY;
+        let result = legacy_migrator
+            .with_try_migrate_super_key(user_id, pw, || db.load_super_key(alias, user_id))
+            .context("In check_and_unlock_super_key. Failed to load super key")?;
+
+        match result {
+            Some((_, entry)) => {
+                let super_key = self
+                    .populate_cache_from_super_key_blob(user_id, alias.algorithm, entry, pw)
+                    .context("In check_and_unlock_super_key.")?;
+                Ok(UserState::LskfUnlocked(super_key))
+            }
+            None => Ok(UserState::Uninitialized),
+        }
+    }
+
+    /// Checks if user has already setup LSKF (i.e. a super key is persisted in the database or the
+    /// legacy database). If so, return LskfLocked state.
+    /// If the password is provided, generate a new super key, encrypt with the password,
+    /// store in the database and populate the super key cache for the new user
+    /// and return LskfUnlocked state.
+    /// If the password is not provided, return Uninitialized state.
+    pub fn check_and_initialize_super_key(
+        &self,
+        db: &mut KeystoreDB,
+        legacy_migrator: &LegacyMigrator,
+        user_id: UserId,
+        pw: Option<&Password>,
+    ) -> Result<UserState> {
+        let super_key_exists_in_db =
+            Self::super_key_exists_in_db_for_user(db, legacy_migrator, user_id).context(
+                "In check_and_initialize_super_key. Failed to check if super key exists.",
+            )?;
+        if super_key_exists_in_db {
+            Ok(UserState::LskfLocked)
+        } else if let Some(pw) = pw {
+            //generate a new super key.
+            let super_key = generate_aes256_key()
+                .context("In check_and_initialize_super_key: Failed to generate AES 256 key.")?;
+            //derive an AES256 key from the password and re-encrypt the super key
+            //before we insert it in the database.
+            let (encrypted_super_key, blob_metadata) = Self::encrypt_with_password(&super_key, pw)
+                .context("In check_and_initialize_super_key.")?;
+
+            let key_entry = db
+                .store_super_key(
+                    user_id,
+                    &USER_SUPER_KEY,
+                    &encrypted_super_key,
+                    &blob_metadata,
+                    &KeyMetaData::new(),
+                )
+                .context("In check_and_initialize_super_key. Failed to store super key.")?;
+
+            let super_key = self
+                .populate_cache_from_super_key_blob(
+                    user_id,
+                    USER_SUPER_KEY.algorithm,
+                    key_entry,
+                    pw,
+                )
+                .context("In check_and_initialize_super_key.")?;
+            Ok(UserState::LskfUnlocked(super_key))
+        } else {
+            Ok(UserState::Uninitialized)
+        }
+    }
+
+    //helper function to populate super key cache from the super key blob loaded from the database
+    fn populate_cache_from_super_key_blob(
+        &self,
+        user_id: UserId,
+        algorithm: SuperEncryptionAlgorithm,
+        entry: KeyEntry,
+        pw: &Password,
+    ) -> Result<Arc<SuperKey>> {
+        let super_key = Self::extract_super_key_from_key_entry(algorithm, entry, pw, None)
+            .context(
+                "In populate_cache_from_super_key_blob. Failed to extract super key from key entry",
+            )?;
+        self.install_per_boot_key_for_user(user_id, super_key.clone())?;
+        Ok(super_key)
+    }
+
+    /// Extracts super key from the entry loaded from the database
+    pub fn extract_super_key_from_key_entry(
+        algorithm: SuperEncryptionAlgorithm,
+        entry: KeyEntry,
+        pw: &Password,
+        reencrypt_with: Option<Arc<SuperKey>>,
+    ) -> Result<Arc<SuperKey>> {
+        if let Some((blob, metadata)) = entry.key_blob_info() {
+            let key = match (
+                metadata.encrypted_by(),
+                metadata.salt(),
+                metadata.iv(),
+                metadata.aead_tag(),
+            ) {
+                (Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag)) => {
+                    // Note that password encryption is AES no matter the value of algorithm
+                    let key = pw.derive_key(Some(salt), AES_256_KEY_LENGTH).context(
+                        "In extract_super_key_from_key_entry: Failed to generate key from password.",
+                    )?;
+
+                    aes_gcm_decrypt(blob, iv, tag, &key).context(
+                        "In extract_super_key_from_key_entry: Failed to decrypt key blob.",
+                    )?
+                }
+                (enc_by, salt, iv, tag) => {
+                    return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
+                        concat!(
+                        "In extract_super_key_from_key_entry: Super key has incomplete metadata.",
+                        "encrypted_by: {:?}; Present: salt: {}, iv: {}, aead_tag: {}."
+                    ),
+                        enc_by,
+                        salt.is_some(),
+                        iv.is_some(),
+                        tag.is_some()
+                    ));
+                }
+            };
+            Ok(Arc::new(SuperKey {
+                algorithm,
+                key,
+                id: SuperKeyIdentifier::DatabaseId(entry.id()),
+                reencrypt_with,
+            }))
+        } else {
+            Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
+                .context("In extract_super_key_from_key_entry: No key blob info.")
+        }
+    }
+
+    /// Encrypts the super key from a key derived from the password, before storing in the database.
+    pub fn encrypt_with_password(
+        super_key: &[u8],
+        pw: &Password,
+    ) -> Result<(Vec<u8>, BlobMetaData)> {
+        let salt = generate_salt().context("In encrypt_with_password: Failed to generate salt.")?;
+        let derived_key = pw
+            .derive_key(Some(&salt), AES_256_KEY_LENGTH)
+            .context("In encrypt_with_password: Failed to derive password.")?;
+        let mut metadata = BlobMetaData::new();
+        metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
+        metadata.add(BlobMetaEntry::Salt(salt));
+        let (encrypted_key, iv, tag) = aes_gcm_encrypt(super_key, &derived_key)
+            .context("In encrypt_with_password: Failed to encrypt new super key.")?;
+        metadata.add(BlobMetaEntry::Iv(iv));
+        metadata.add(BlobMetaEntry::AeadTag(tag));
+        Ok((encrypted_key, metadata))
+    }
+
+    // Encrypt the given key blob with the user's super key, if the super key exists and the device
+    // is unlocked. If the super key exists and the device is locked, or LSKF is not setup,
+    // return error. Note that it is out of the scope of this function to check if super encryption
+    // is required. Such check should be performed before calling this function.
+    fn super_encrypt_on_key_init(
+        &self,
+        db: &mut KeystoreDB,
+        legacy_migrator: &LegacyMigrator,
+        user_id: UserId,
+        key_blob: &[u8],
+    ) -> Result<(Vec<u8>, BlobMetaData)> {
+        match UserState::get(db, legacy_migrator, self, user_id)
+            .context("In super_encrypt. Failed to get user state.")?
+        {
+            UserState::LskfUnlocked(super_key) => {
+                Self::encrypt_with_aes_super_key(key_blob, &super_key)
+                    .context("In super_encrypt_on_key_init. Failed to encrypt the key.")
+            }
+            UserState::LskfLocked => {
+                Err(Error::Rc(ResponseCode::LOCKED)).context("In super_encrypt. Device is locked.")
+            }
+            UserState::Uninitialized => Err(Error::Rc(ResponseCode::UNINITIALIZED))
+                .context("In super_encrypt. LSKF is not setup for the user."),
+        }
+    }
+
+    //Helper function to encrypt a key with the given super key. Callers should select which super
+    //key to be used. This is called when a key is super encrypted at its creation as well as at its
+    //upgrade.
+    fn encrypt_with_aes_super_key(
+        key_blob: &[u8],
+        super_key: &SuperKey,
+    ) -> Result<(Vec<u8>, BlobMetaData)> {
+        if super_key.algorithm != SuperEncryptionAlgorithm::Aes256Gcm {
+            return Err(Error::sys())
+                .context("In encrypt_with_aes_super_key: unexpected algorithm");
+        }
+        let mut metadata = BlobMetaData::new();
+        let (encrypted_key, iv, tag) = aes_gcm_encrypt(key_blob, &(super_key.key))
+            .context("In encrypt_with_aes_super_key: Failed to encrypt new super key.")?;
+        metadata.add(BlobMetaEntry::Iv(iv));
+        metadata.add(BlobMetaEntry::AeadTag(tag));
+        super_key.id.add_to_metadata(&mut metadata);
+        Ok((encrypted_key, metadata))
+    }
+
+    /// Check if super encryption is required and if so, super-encrypt the key to be stored in
+    /// the database.
+    #[allow(clippy::too_many_arguments)]
+    pub fn handle_super_encryption_on_key_init(
+        &self,
+        db: &mut KeystoreDB,
+        legacy_migrator: &LegacyMigrator,
+        domain: &Domain,
+        key_parameters: &[KeyParameter],
+        flags: Option<i32>,
+        user_id: UserId,
+        key_blob: &[u8],
+    ) -> Result<(Vec<u8>, BlobMetaData)> {
+        match Enforcements::super_encryption_required(domain, key_parameters, flags) {
+            SuperEncryptionType::None => Ok((key_blob.to_vec(), BlobMetaData::new())),
+            SuperEncryptionType::LskfBound => self
+                .super_encrypt_on_key_init(db, legacy_migrator, user_id, &key_blob)
+                .context(concat!(
+                    "In handle_super_encryption_on_key_init. ",
+                    "Failed to super encrypt with LskfBound key."
+                )),
+            SuperEncryptionType::ScreenLockBound => {
+                let mut data = self.data.lock().unwrap();
+                let entry = data.user_keys.entry(user_id).or_default();
+                if let Some(super_key) = entry.screen_lock_bound.as_ref() {
+                    Self::encrypt_with_aes_super_key(key_blob, &super_key).context(concat!(
+                        "In handle_super_encryption_on_key_init. ",
+                        "Failed to encrypt with ScreenLockBound key."
+                    ))
+                } else {
+                    // Symmetric key is not available, use public key encryption
+                    let loaded =
+                        db.load_super_key(&USER_SCREEN_LOCK_BOUND_ECDH_KEY, user_id).context(
+                            "In handle_super_encryption_on_key_init: load_super_key failed.",
+                        )?;
+                    let (key_id_guard, key_entry) = loaded.ok_or_else(Error::sys).context(
+                        "In handle_super_encryption_on_key_init: User ECDH key missing.",
+                    )?;
+                    let public_key =
+                        key_entry.metadata().sec1_public_key().ok_or_else(Error::sys).context(
+                            "In handle_super_encryption_on_key_init: sec1_public_key missing.",
+                        )?;
+                    let mut metadata = BlobMetaData::new();
+                    let (ephem_key, salt, iv, encrypted_key, aead_tag) =
+                        ECDHPrivateKey::encrypt_message(public_key, key_blob).context(concat!(
+                            "In handle_super_encryption_on_key_init: ",
+                            "ECDHPrivateKey::encrypt_message failed."
+                        ))?;
+                    metadata.add(BlobMetaEntry::PublicKey(ephem_key));
+                    metadata.add(BlobMetaEntry::Salt(salt));
+                    metadata.add(BlobMetaEntry::Iv(iv));
+                    metadata.add(BlobMetaEntry::AeadTag(aead_tag));
+                    SuperKeyIdentifier::DatabaseId(key_id_guard.id())
+                        .add_to_metadata(&mut metadata);
+                    Ok((encrypted_key, metadata))
+                }
+            }
+            SuperEncryptionType::BootLevel(level) => {
+                let key_id = SuperKeyIdentifier::BootLevel(level);
+                let super_key = self
+                    .lookup_key(&key_id)
+                    .context("In handle_super_encryption_on_key_init: lookup_key failed")?
+                    .ok_or(Error::Rc(ResponseCode::LOCKED))
+                    .context("In handle_super_encryption_on_key_init: Boot stage key absent")?;
+                Self::encrypt_with_aes_super_key(key_blob, &super_key).context(concat!(
+                    "In handle_super_encryption_on_key_init: ",
+                    "Failed to encrypt with BootLevel key."
+                ))
+            }
+        }
+    }
+
+    /// Check if a given key needs re-super-encryption, from its KeyBlob type.
+    /// If so, re-super-encrypt the key and return a new set of metadata,
+    /// containing the new super encryption information.
+    pub fn reencrypt_if_required<'a>(
+        key_blob_before_upgrade: &KeyBlob,
+        key_after_upgrade: &'a [u8],
+    ) -> Result<(KeyBlob<'a>, Option<BlobMetaData>)> {
+        match key_blob_before_upgrade {
+            KeyBlob::Sensitive { reencrypt_with: super_key, .. } => {
+                let (key, metadata) =
+                    Self::encrypt_with_aes_super_key(key_after_upgrade, super_key)
+                        .context("In reencrypt_if_required: Failed to re-super-encrypt key.")?;
+                Ok((KeyBlob::NonSensitive(key), Some(metadata)))
+            }
+            _ => Ok((KeyBlob::Ref(key_after_upgrade), None)),
+        }
+    }
+
+    /// Fetch a superencryption key from the database, or create it if it doesn't already exist.
+    /// When this is called, the caller must hold the lock on the SuperKeyManager.
+    /// So it's OK that the check and creation are different DB transactions.
+    fn get_or_create_super_key(
+        db: &mut KeystoreDB,
+        user_id: UserId,
+        key_type: &SuperKeyType,
+        password: &Password,
+        reencrypt_with: Option<Arc<SuperKey>>,
+    ) -> Result<Arc<SuperKey>> {
+        let loaded_key = db.load_super_key(key_type, user_id)?;
+        if let Some((_, key_entry)) = loaded_key {
+            Ok(Self::extract_super_key_from_key_entry(
+                key_type.algorithm,
+                key_entry,
+                password,
+                reencrypt_with,
+            )?)
+        } else {
+            let (super_key, public_key) = match key_type.algorithm {
+                SuperEncryptionAlgorithm::Aes256Gcm => (
+                    generate_aes256_key()
+                        .context("In get_or_create_super_key: Failed to generate AES 256 key.")?,
+                    None,
+                ),
+                SuperEncryptionAlgorithm::EcdhP256 => {
+                    let key = ECDHPrivateKey::generate()
+                        .context("In get_or_create_super_key: Failed to generate ECDH key")?;
+                    (
+                        key.private_key()
+                            .context("In get_or_create_super_key: private_key failed")?,
+                        Some(
+                            key.public_key()
+                                .context("In get_or_create_super_key: public_key failed")?,
+                        ),
+                    )
+                }
+            };
+            //derive an AES256 key from the password and re-encrypt the super key
+            //before we insert it in the database.
+            let (encrypted_super_key, blob_metadata) =
+                Self::encrypt_with_password(&super_key, password)
+                    .context("In get_or_create_super_key.")?;
+            let mut key_metadata = KeyMetaData::new();
+            if let Some(pk) = public_key {
+                key_metadata.add(KeyMetaEntry::Sec1PublicKey(pk));
+            }
+            let key_entry = db
+                .store_super_key(
+                    user_id,
+                    key_type,
+                    &encrypted_super_key,
+                    &blob_metadata,
+                    &key_metadata,
+                )
+                .context("In get_or_create_super_key. Failed to store super key.")?;
+            Ok(Arc::new(SuperKey {
+                algorithm: key_type.algorithm,
+                key: super_key,
+                id: SuperKeyIdentifier::DatabaseId(key_entry.id()),
+                reencrypt_with,
+            }))
+        }
+    }
+
+    /// Decrypt the screen-lock bound keys for this user using the password and store in memory.
+    pub fn unlock_screen_lock_bound_key(
+        &self,
+        db: &mut KeystoreDB,
+        user_id: UserId,
+        password: &Password,
+    ) -> Result<()> {
+        let mut data = self.data.lock().unwrap();
+        let entry = data.user_keys.entry(user_id).or_default();
+        let aes = entry
+            .screen_lock_bound
+            .get_or_try_to_insert_with(|| {
+                Self::get_or_create_super_key(
+                    db,
+                    user_id,
+                    &USER_SCREEN_LOCK_BOUND_KEY,
+                    password,
+                    None,
+                )
+            })?
+            .clone();
+        let ecdh = entry
+            .screen_lock_bound_private
+            .get_or_try_to_insert_with(|| {
+                Self::get_or_create_super_key(
+                    db,
+                    user_id,
+                    &USER_SCREEN_LOCK_BOUND_ECDH_KEY,
+                    password,
+                    Some(aes.clone()),
+                )
+            })?
+            .clone();
+        data.add_key_to_key_index(&aes)?;
+        data.add_key_to_key_index(&ecdh)?;
+        Ok(())
+    }
+
+    /// Wipe the screen-lock bound keys for this user from memory.
+    pub fn lock_screen_lock_bound_key(
+        &self,
+        db: &mut KeystoreDB,
+        user_id: UserId,
+        unlocking_sids: &[i64],
+    ) {
+        log::info!("Locking screen bound for user {} sids {:?}", user_id, unlocking_sids);
+        let mut data = self.data.lock().unwrap();
+        let mut entry = data.user_keys.entry(user_id).or_default();
+        if !unlocking_sids.is_empty() {
+            if let (Some(aes), Some(ecdh)) = (
+                entry.screen_lock_bound.as_ref().cloned(),
+                entry.screen_lock_bound_private.as_ref().cloned(),
+            ) {
+                let res = (|| -> Result<()> {
+                    let key_desc = KeyMintDevice::internal_descriptor(format!(
+                        "biometric_unlock_key_{}",
+                        user_id
+                    ));
+                    let encrypting_key = generate_aes256_key()?;
+                    let km_dev: KeyMintDevice =
+                        KeyMintDevice::get(SecurityLevel::TRUSTED_ENVIRONMENT)
+                            .context("In lock_screen_lock_bound_key: KeyMintDevice::get failed")?;
+                    let mut key_params = vec![
+                        KeyParameterValue::Algorithm(Algorithm::AES),
+                        KeyParameterValue::KeySize(256),
+                        KeyParameterValue::BlockMode(BlockMode::GCM),
+                        KeyParameterValue::PaddingMode(PaddingMode::NONE),
+                        KeyParameterValue::CallerNonce,
+                        KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
+                        KeyParameterValue::MinMacLength(128),
+                        KeyParameterValue::AuthTimeout(BIOMETRIC_AUTH_TIMEOUT_S),
+                        KeyParameterValue::HardwareAuthenticatorType(
+                            HardwareAuthenticatorType::FINGERPRINT,
+                        ),
+                    ];
+                    for sid in unlocking_sids {
+                        key_params.push(KeyParameterValue::UserSecureID(*sid));
+                    }
+                    let key_params: Vec<KmKeyParameter> =
+                        key_params.into_iter().map(|x| x.into()).collect();
+                    km_dev.create_and_store_key(db, &key_desc, |dev| {
+                        let _wp = wd::watch_millis(
+                            "In lock_screen_lock_bound_key: calling importKey.",
+                            500,
+                        );
+                        dev.importKey(key_params.as_slice(), KeyFormat::RAW, &encrypting_key, None)
+                    })?;
+                    entry.biometric_unlock = Some(BiometricUnlock {
+                        sids: unlocking_sids.into(),
+                        key_desc,
+                        screen_lock_bound: LockedKey::new(&encrypting_key, &aes)?,
+                        screen_lock_bound_private: LockedKey::new(&encrypting_key, &ecdh)?,
+                    });
+                    Ok(())
+                })();
+                // There is no reason to propagate an error here upwards. We must discard
+                // entry.screen_lock_bound* in any case.
+                if let Err(e) = res {
+                    log::error!("Error setting up biometric unlock: {:#?}", e);
+                }
+            }
+        }
+        entry.screen_lock_bound = None;
+        entry.screen_lock_bound_private = None;
+    }
+
+    /// User has unlocked, not using a password. See if any of our stored auth tokens can be used
+    /// to unlock the keys protecting UNLOCKED_DEVICE_REQUIRED keys.
+    pub fn try_unlock_user_with_biometric(
+        &self,
+        db: &mut KeystoreDB,
+        user_id: UserId,
+    ) -> Result<()> {
+        let mut data = self.data.lock().unwrap();
+        let mut entry = data.user_keys.entry(user_id).or_default();
+        if let Some(biometric) = entry.biometric_unlock.as_ref() {
+            let (key_id_guard, key_entry) =
+                KeyMintDevice::lookup_from_desc(db, &biometric.key_desc)?;
+            let km_dev: KeyMintDevice = KeyMintDevice::get(SecurityLevel::TRUSTED_ENVIRONMENT)
+                .context("In try_unlock_user_with_biometric: KeyMintDevice::get failed")?;
+            for sid in &biometric.sids {
+                if let Some((auth_token_entry, _)) = db.find_auth_token_entry(|entry| {
+                    entry.auth_token().userId == *sid || entry.auth_token().authenticatorId == *sid
+                })? {
+                    let res: Result<(Arc<SuperKey>, Arc<SuperKey>)> = (|| {
+                        let slb = biometric.screen_lock_bound.decrypt(
+                            db,
+                            &km_dev,
+                            &key_id_guard,
+                            &key_entry,
+                            auth_token_entry.auth_token(),
+                            None,
+                        )?;
+                        let slbp = biometric.screen_lock_bound_private.decrypt(
+                            db,
+                            &km_dev,
+                            &key_id_guard,
+                            &key_entry,
+                            auth_token_entry.auth_token(),
+                            Some(slb.clone()),
+                        )?;
+                        Ok((slb, slbp))
+                    })();
+                    match res {
+                        Ok((slb, slbp)) => {
+                            entry.screen_lock_bound = Some(slb.clone());
+                            entry.screen_lock_bound_private = Some(slbp.clone());
+                            data.add_key_to_key_index(&slb)?;
+                            data.add_key_to_key_index(&slbp)?;
+                            log::info!(concat!(
+                                "In try_unlock_user_with_biometric: ",
+                                "Successfully unlocked with biometric"
+                            ));
+                            return Ok(());
+                        }
+                        Err(e) => {
+                            log::warn!("In try_unlock_user_with_biometric: attempt failed: {:?}", e)
+                        }
+                    }
+                }
+            }
+        }
+        Ok(())
+    }
+}
+
+/// This enum represents different states of the user's life cycle in the device.
+/// For now, only three states are defined. More states may be added later.
+pub enum UserState {
+    // The user has registered LSKF and has unlocked the device by entering PIN/Password,
+    // and hence the per-boot super key is available in the cache.
+    LskfUnlocked(Arc<SuperKey>),
+    // The user has registered LSKF, but has not unlocked the device using password, after reboot.
+    // Hence the per-boot super-key(s) is not available in the cache.
+    // However, the encrypted super key is available in the database.
+    LskfLocked,
+    // There's no user in the device for the given user id, or the user with the user id has not
+    // setup LSKF.
+    Uninitialized,
+}
+
+impl UserState {
+    pub fn get(
+        db: &mut KeystoreDB,
+        legacy_migrator: &LegacyMigrator,
+        skm: &SuperKeyManager,
+        user_id: UserId,
+    ) -> Result<UserState> {
+        match skm.get_per_boot_key_by_user_id(user_id) {
+            Some(super_key) => Ok(UserState::LskfUnlocked(super_key)),
+            None => {
+                //Check if a super key exists in the database or legacy database.
+                //If so, return locked user state.
+                if SuperKeyManager::super_key_exists_in_db_for_user(db, legacy_migrator, user_id)
+                    .context("In get.")?
+                {
+                    Ok(UserState::LskfLocked)
+                } else {
+                    Ok(UserState::Uninitialized)
+                }
+            }
+        }
+    }
+
+    /// Queries user state when serving password change requests.
+    pub fn get_with_password_changed(
+        db: &mut KeystoreDB,
+        legacy_migrator: &LegacyMigrator,
+        skm: &SuperKeyManager,
+        user_id: UserId,
+        password: Option<&Password>,
+    ) -> Result<UserState> {
+        match skm.get_per_boot_key_by_user_id(user_id) {
+            Some(super_key) => {
+                if password.is_none() {
+                    //transitioning to swiping, delete only the super key in database and cache, and
+                    //super-encrypted keys in database (and in KM)
+                    Self::reset_user(db, skm, legacy_migrator, user_id, true).context(
+                        "In get_with_password_changed: Trying to delete keys from the db.",
+                    )?;
+                    //Lskf is now removed in Keystore
+                    Ok(UserState::Uninitialized)
+                } else {
+                    //Keystore won't be notified when changing to a new password when LSKF is
+                    //already setup. Therefore, ideally this path wouldn't be reached.
+                    Ok(UserState::LskfUnlocked(super_key))
+                }
+            }
+            None => {
+                //Check if a super key exists in the database or legacy database.
+                //If so, return LskfLocked state.
+                //Otherwise, i) if the password is provided, initialize the super key and return
+                //LskfUnlocked state ii) if password is not provided, return Uninitialized state.
+                skm.check_and_initialize_super_key(db, legacy_migrator, user_id, password)
+            }
+        }
+    }
+
+    /// Queries user state when serving password unlock requests.
+    pub fn get_with_password_unlock(
+        db: &mut KeystoreDB,
+        legacy_migrator: &LegacyMigrator,
+        skm: &SuperKeyManager,
+        user_id: UserId,
+        password: &Password,
+    ) -> Result<UserState> {
+        match skm.get_per_boot_key_by_user_id(user_id) {
+            Some(super_key) => {
+                log::info!("In get_with_password_unlock. Trying to unlock when already unlocked.");
+                Ok(UserState::LskfUnlocked(super_key))
+            }
+            None => {
+                //Check if a super key exists in the database or legacy database.
+                //If not, return Uninitialized state.
+                //Otherwise, try to unlock the super key and if successful,
+                //return LskfUnlocked state
+                skm.check_and_unlock_super_key(db, legacy_migrator, user_id, password)
+                    .context("In get_with_password_unlock. Failed to unlock super key.")
+            }
+        }
+    }
+
+    /// Delete all the keys created on behalf of the user.
+    /// If 'keep_non_super_encrypted_keys' is set to true, delete only the super key and super
+    /// encrypted keys.
+    pub fn reset_user(
+        db: &mut KeystoreDB,
+        skm: &SuperKeyManager,
+        legacy_migrator: &LegacyMigrator,
+        user_id: UserId,
+        keep_non_super_encrypted_keys: bool,
+    ) -> Result<()> {
+        // mark keys created on behalf of the user as unreferenced.
+        legacy_migrator
+            .bulk_delete_user(user_id, keep_non_super_encrypted_keys)
+            .context("In reset_user: Trying to delete legacy keys.")?;
+        db.unbind_keys_for_user(user_id, keep_non_super_encrypted_keys)
+            .context("In reset user. Error in unbinding keys.")?;
+
+        //delete super key in cache, if exists
+        skm.forget_all_keys_for_user(user_id);
+        Ok(())
+    }
+}
+
+/// This enum represents three states a KeyMint Blob can be in, w.r.t super encryption.
+/// `Sensitive` holds the non encrypted key and a reference to its super key.
+/// `NonSensitive` holds a non encrypted key that is never supposed to be encrypted.
+/// `Ref` holds a reference to a key blob when it does not need to be modified if its
+/// life time allows it.
+pub enum KeyBlob<'a> {
+    Sensitive {
+        key: ZVec,
+        /// If KeyMint reports that the key must be upgraded, we must
+        /// re-encrypt the key before writing to the database; we use
+        /// this key.
+        reencrypt_with: Arc<SuperKey>,
+        /// If this key was decrypted with an ECDH key, we want to
+        /// re-encrypt it on first use whether it was upgraded or not;
+        /// this field indicates that that's necessary.
+        force_reencrypt: bool,
+    },
+    NonSensitive(Vec<u8>),
+    Ref(&'a [u8]),
+}
+
+impl<'a> KeyBlob<'a> {
+    pub fn force_reencrypt(&self) -> bool {
+        if let KeyBlob::Sensitive { force_reencrypt, .. } = self {
+            *force_reencrypt
+        } else {
+            false
+        }
+    }
+}
+
+/// Deref returns a reference to the key material in any variant.
+impl<'a> Deref for KeyBlob<'a> {
+    type Target = [u8];
+
+    fn deref(&self) -> &Self::Target {
+        match self {
+            Self::Sensitive { key, .. } => &key,
+            Self::NonSensitive(key) => &key,
+            Self::Ref(key) => key,
+        }
+    }
+}
diff --git a/keystore2/src/try_insert.rs b/keystore2/src/try_insert.rs
new file mode 100644
index 0000000..6dd3962
--- /dev/null
+++ b/keystore2/src/try_insert.rs
@@ -0,0 +1,100 @@
+// Copyright 2021, 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.
+
+//! The TryInsert trait adds to Option<T> the method
+//! get_or_try_to_insert_with, which is analogous to
+//! get_or_insert_with, but allows the called function to fail and propagates the failure.
+
+/// The TryInsert trait adds to Option<T> the method
+/// get_or_try_to_insert_with, which is analogous to
+/// get_or_insert_with, but allows the called function to fail and propagates the failure.
+pub trait TryInsert {
+    /// Type of the Ok branch of the Result
+    type Item;
+    /// Inserts a value computed from `f` into the option if it is [`None`],
+    /// then returns a mutable reference to the contained value. If `f`
+    /// returns Err, the Option is unchanged.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut x = None;
+    /// assert_eq!(x.get_or_try_to_insert_with(Err("oops".to_string())), Err("oops".to_string()))
+    /// {
+    ///     let y: &mut u32 = x.get_or_try_to_insert_with(|| Ok(5))?;
+    ///     assert_eq!(y, &5);
+    ///
+    ///     *y = 7;
+    /// }
+    ///
+    /// assert_eq!(x, Some(7));
+    /// ```
+    fn get_or_try_to_insert_with<E, F: FnOnce() -> Result<Self::Item, E>>(
+        &mut self,
+        f: F,
+    ) -> Result<&mut Self::Item, E>;
+}
+
+impl<T> TryInsert for Option<T> {
+    type Item = T;
+    fn get_or_try_to_insert_with<E, F: FnOnce() -> Result<Self::Item, E>>(
+        &mut self,
+        f: F,
+    ) -> Result<&mut Self::Item, E> {
+        if self.is_none() {
+            *self = Some(f()?);
+        }
+
+        match self {
+            Some(v) => Ok(v),
+            // SAFETY: a `None` variant for `self` would have been replaced by a `Some`
+            // variant in the code above.
+            None => unsafe { std::hint::unreachable_unchecked() },
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    fn fails() -> Result<i32, String> {
+        Err("fail".to_string())
+    }
+
+    fn succeeds() -> Result<i32, String> {
+        Ok(99)
+    }
+
+    #[test]
+    fn test() {
+        let mut x = None;
+        assert_eq!(x.get_or_try_to_insert_with(fails), Err("fail".to_string()));
+        assert_eq!(x, None);
+        assert_eq!(*x.get_or_try_to_insert_with(succeeds).unwrap(), 99);
+        assert_eq!(x, Some(99));
+        x = Some(42);
+        assert_eq!(*x.get_or_try_to_insert_with(fails).unwrap(), 42);
+        assert_eq!(x, Some(42));
+        assert_eq!(*x.get_or_try_to_insert_with(succeeds).unwrap(), 42);
+        assert_eq!(x, Some(42));
+        *x.get_or_try_to_insert_with(fails).unwrap() = 2;
+        assert_eq!(x, Some(2));
+        *x.get_or_try_to_insert_with(succeeds).unwrap() = 3;
+        assert_eq!(x, Some(3));
+        x = None;
+        *x.get_or_try_to_insert_with(succeeds).unwrap() = 5;
+        assert_eq!(x, Some(5));
+    }
+}
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
new file mode 100644
index 0000000..9852aad
--- /dev/null
+++ b/keystore2/src/utils.rs
@@ -0,0 +1,307 @@
+// Copyright 2020, 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.
+
+//! This module implements utility functions used by the Keystore 2.0 service
+//! implementation.
+
+use crate::error::{map_binder_status, Error, ErrorCode};
+use crate::permission;
+use crate::permission::{KeyPerm, KeyPermSet, KeystorePerm};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    KeyCharacteristics::KeyCharacteristics, Tag::Tag,
+};
+use android_os_permissions_aidl::aidl::android::os::IPermissionController;
+use android_security_apc::aidl::android::security::apc::{
+    IProtectedConfirmation::{FLAG_UI_OPTION_INVERTED, FLAG_UI_OPTION_MAGNIFIED},
+    ResponseCode::ResponseCode as ApcResponseCode,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Authorization::Authorization, KeyDescriptor::KeyDescriptor,
+};
+use anyhow::{anyhow, Context};
+use binder::{FromIBinder, SpIBinder, ThreadState};
+use keystore2_apc_compat::{
+    ApcCompatUiOptions, APC_COMPAT_ERROR_ABORTED, APC_COMPAT_ERROR_CANCELLED,
+    APC_COMPAT_ERROR_IGNORED, APC_COMPAT_ERROR_OK, APC_COMPAT_ERROR_OPERATION_PENDING,
+    APC_COMPAT_ERROR_SYSTEM_ERROR,
+};
+use std::convert::TryFrom;
+use std::sync::Mutex;
+
+/// This function uses its namesake in the permission module and in
+/// combination with with_calling_sid from the binder crate to check
+/// if the caller has the given keystore permission.
+pub fn check_keystore_permission(perm: KeystorePerm) -> anyhow::Result<()> {
+    ThreadState::with_calling_sid(|calling_sid| {
+        permission::check_keystore_permission(
+            &calling_sid.ok_or_else(Error::sys).context(
+                "In check_keystore_permission: Cannot check permission without calling_sid.",
+            )?,
+            perm,
+        )
+    })
+}
+
+/// This function uses its namesake in the permission module and in
+/// combination with with_calling_sid from the binder crate to check
+/// if the caller has the given grant permission.
+pub fn check_grant_permission(access_vec: KeyPermSet, key: &KeyDescriptor) -> anyhow::Result<()> {
+    ThreadState::with_calling_sid(|calling_sid| {
+        permission::check_grant_permission(
+            &calling_sid.ok_or_else(Error::sys).context(
+                "In check_grant_permission: Cannot check permission without calling_sid.",
+            )?,
+            access_vec,
+            key,
+        )
+    })
+}
+
+/// This function uses its namesake in the permission module and in
+/// combination with with_calling_sid from the binder crate to check
+/// if the caller has the given key permission.
+pub fn check_key_permission(
+    perm: KeyPerm,
+    key: &KeyDescriptor,
+    access_vector: &Option<KeyPermSet>,
+) -> anyhow::Result<()> {
+    ThreadState::with_calling_sid(|calling_sid| {
+        permission::check_key_permission(
+            ThreadState::get_calling_uid(),
+            &calling_sid
+                .ok_or_else(Error::sys)
+                .context("In check_key_permission: Cannot check permission without calling_sid.")?,
+            perm,
+            key,
+            access_vector,
+        )
+    })
+}
+
+/// This function checks whether a given tag corresponds to the access of device identifiers.
+pub fn is_device_id_attestation_tag(tag: Tag) -> bool {
+    matches!(
+        tag,
+        Tag::ATTESTATION_ID_IMEI
+            | Tag::ATTESTATION_ID_MEID
+            | Tag::ATTESTATION_ID_SERIAL
+            | Tag::DEVICE_UNIQUE_ATTESTATION
+    )
+}
+
+/// This function checks whether the calling app has the Android permissions needed to attest device
+/// identifiers. It throws an error if the permissions cannot be verified, or if the caller doesn't
+/// have the right permissions, and returns silently otherwise.
+pub fn check_device_attestation_permissions() -> anyhow::Result<()> {
+    let permission_controller: binder::Strong<dyn IPermissionController::IPermissionController> =
+        binder::get_interface("permission")?;
+
+    let binder_result = {
+        let _wp = watchdog::watch_millis(
+            "In check_device_attestation_permissions: calling checkPermission.",
+            500,
+        );
+        permission_controller.checkPermission(
+            "android.permission.READ_PRIVILEGED_PHONE_STATE",
+            ThreadState::get_calling_pid(),
+            ThreadState::get_calling_uid() as i32,
+        )
+    };
+    let has_permissions = map_binder_status(binder_result)
+        .context("In check_device_attestation_permissions: checkPermission failed")?;
+    match has_permissions {
+        true => Ok(()),
+        false => Err(Error::Km(ErrorCode::CANNOT_ATTEST_IDS)).context(concat!(
+            "In check_device_attestation_permissions: ",
+            "caller does not have the permission to attest device IDs"
+        )),
+    }
+}
+
+/// Thread safe wrapper around SpIBinder. It is safe to have SpIBinder smart pointers to the
+/// same object in multiple threads, but cloning a SpIBinder is not thread safe.
+/// Keystore frequently hands out binder tokens to the security level interface. If this
+/// is to happen from a multi threaded thread pool, the SpIBinder needs to be protected by a
+/// Mutex.
+#[derive(Debug)]
+pub struct Asp(Mutex<SpIBinder>);
+
+impl Asp {
+    /// Creates a new instance owning a SpIBinder wrapped in a Mutex.
+    pub fn new(i: SpIBinder) -> Self {
+        Self(Mutex::new(i))
+    }
+
+    /// Clones the owned SpIBinder and attempts to convert it into the requested interface.
+    pub fn get_interface<T: FromIBinder + ?Sized>(&self) -> anyhow::Result<binder::Strong<T>> {
+        // We can use unwrap here because we never panic when locked, so the mutex
+        // can never be poisoned.
+        let lock = self.0.lock().unwrap();
+        (*lock)
+            .clone()
+            .into_interface()
+            .map_err(|e| anyhow!(format!("get_interface failed with error code {:?}", e)))
+    }
+}
+
+impl Clone for Asp {
+    fn clone(&self) -> Self {
+        let lock = self.0.lock().unwrap();
+        Self(Mutex::new((*lock).clone()))
+    }
+}
+
+/// Converts a set of key characteristics as returned from KeyMint into the internal
+/// representation of the keystore service.
+pub fn key_characteristics_to_internal(
+    key_characteristics: Vec<KeyCharacteristics>,
+) -> Vec<crate::key_parameter::KeyParameter> {
+    key_characteristics
+        .into_iter()
+        .flat_map(|aidl_key_char| {
+            let sec_level = aidl_key_char.securityLevel;
+            aidl_key_char.authorizations.into_iter().map(move |aidl_kp| {
+                crate::key_parameter::KeyParameter::new(aidl_kp.into(), sec_level)
+            })
+        })
+        .collect()
+}
+
+/// Converts a set of key characteristics from the internal representation into a set of
+/// Authorizations as they are used to convey key characteristics to the clients of keystore.
+pub fn key_parameters_to_authorizations(
+    parameters: Vec<crate::key_parameter::KeyParameter>,
+) -> Vec<Authorization> {
+    parameters.into_iter().map(|p| p.into_authorization()).collect()
+}
+
+/// This returns the current time (in seconds) as an instance of a monotonic clock, by invoking the
+/// system call since Rust does not support getting monotonic time instance as an integer.
+pub fn get_current_time_in_seconds() -> i64 {
+    let mut current_time = libc::timespec { tv_sec: 0, tv_nsec: 0 };
+    // Following unsafe block includes one system call to get monotonic time.
+    // Therefore, it is not considered harmful.
+    unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_RAW, &mut current_time) };
+    // It is safe to unwrap here because try_from() returns std::convert::Infallible, which is
+    // defined to be an error that can never happen (i.e. the result is always ok).
+    // This suppresses the compiler's complaint about converting tv_sec to i64 in method
+    // get_current_time_in_seconds.
+    #[allow(clippy::useless_conversion)]
+    i64::try_from(current_time.tv_sec).unwrap()
+}
+
+/// Converts a response code as returned by the Android Protected Confirmation HIDL compatibility
+/// module (keystore2_apc_compat) into a ResponseCode as defined by the APC AIDL
+/// (android.security.apc) spec.
+pub fn compat_2_response_code(rc: u32) -> ApcResponseCode {
+    match rc {
+        APC_COMPAT_ERROR_OK => ApcResponseCode::OK,
+        APC_COMPAT_ERROR_CANCELLED => ApcResponseCode::CANCELLED,
+        APC_COMPAT_ERROR_ABORTED => ApcResponseCode::ABORTED,
+        APC_COMPAT_ERROR_OPERATION_PENDING => ApcResponseCode::OPERATION_PENDING,
+        APC_COMPAT_ERROR_IGNORED => ApcResponseCode::IGNORED,
+        APC_COMPAT_ERROR_SYSTEM_ERROR => ApcResponseCode::SYSTEM_ERROR,
+        _ => ApcResponseCode::SYSTEM_ERROR,
+    }
+}
+
+/// Converts the UI Options flags as defined by the APC AIDL (android.security.apc) spec into
+/// UI Options flags as defined by the Android Protected Confirmation HIDL compatibility
+/// module (keystore2_apc_compat).
+pub fn ui_opts_2_compat(opt: i32) -> ApcCompatUiOptions {
+    ApcCompatUiOptions {
+        inverted: (opt & FLAG_UI_OPTION_INVERTED) != 0,
+        magnified: (opt & FLAG_UI_OPTION_MAGNIFIED) != 0,
+    }
+}
+
+/// AID offset for uid space partitioning.
+pub const AID_USER_OFFSET: u32 = cutils_bindgen::AID_USER_OFFSET;
+
+/// AID of the keystore process itself, used for keys that
+/// keystore generates for its own use.
+pub const AID_KEYSTORE: u32 = cutils_bindgen::AID_KEYSTORE;
+
+/// Extracts the android user from the given uid.
+pub fn uid_to_android_user(uid: u32) -> u32 {
+    // Safety: No memory access
+    unsafe { cutils_bindgen::multiuser_get_user_id(uid) }
+}
+
+/// This module provides helpers for simplified use of the watchdog module.
+#[cfg(feature = "watchdog")]
+pub mod watchdog {
+    pub use crate::watchdog::WatchPoint;
+    use crate::watchdog::Watchdog;
+    use lazy_static::lazy_static;
+    use std::sync::Arc;
+    use std::time::Duration;
+
+    lazy_static! {
+        /// A Watchdog thread, that can be used to create watch points.
+        static ref WD: Arc<Watchdog> = Watchdog::new(Duration::from_secs(10));
+    }
+
+    /// Sets a watch point with `id` and a timeout of `millis` milliseconds.
+    pub fn watch_millis(id: &'static str, millis: u64) -> Option<WatchPoint> {
+        Watchdog::watch(&WD, id, Duration::from_millis(millis))
+    }
+
+    /// Like `watch_millis` but with a callback that is called every time a report
+    /// is printed about this watch point.
+    pub fn watch_millis_with(
+        id: &'static str,
+        millis: u64,
+        callback: impl Fn() -> String + Send + 'static,
+    ) -> Option<WatchPoint> {
+        Watchdog::watch_with(&WD, id, Duration::from_millis(millis), callback)
+    }
+}
+
+/// This module provides empty/noop implementations of the watch dog utility functions.
+#[cfg(not(feature = "watchdog"))]
+pub mod watchdog {
+    /// Noop watch point.
+    pub struct WatchPoint();
+    /// Sets a Noop watch point.
+    fn watch_millis(_: &'static str, _: u64) -> Option<WatchPoint> {
+        None
+    }
+
+    pub fn watch_millis_with(
+        _: &'static str,
+        _: u64,
+        _: impl Fn() -> String + Send + 'static,
+    ) -> Option<WatchPoint> {
+        None
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use anyhow::Result;
+
+    #[test]
+    fn check_device_attestation_permissions_test() -> Result<()> {
+        check_device_attestation_permissions().or_else(|error| {
+            match error.root_cause().downcast_ref::<Error>() {
+                // Expected: the context for this test might not be allowed to attest device IDs.
+                Some(Error::Km(ErrorCode::CANNOT_ATTEST_IDS)) => Ok(()),
+                // Other errors are unexpected
+                _ => Err(error),
+            }
+        })
+    }
+}
diff --git a/keystore2/src/vintf/Android.bp b/keystore2/src/vintf/Android.bp
new file mode 100644
index 0000000..3ab0ec5
--- /dev/null
+++ b/keystore2/src/vintf/Android.bp
@@ -0,0 +1,80 @@
+// Copyright 2021, 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 {
+    // 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_vintf_rust",
+    crate_name: "keystore2_vintf",
+    srcs: ["lib.rs"],
+    rustlibs: [
+        "libkeystore2_vintf_bindgen",
+    ],
+    shared_libs: [
+        "libkeystore2_vintf_cpp",
+        "libvintf",
+    ],
+}
+
+cc_library {
+    name: "libkeystore2_vintf_cpp",
+    srcs: [
+        "vintf.cpp",
+    ],
+    shared_libs: [
+        "libvintf",
+    ],
+}
+
+rust_bindgen {
+    name: "libkeystore2_vintf_bindgen",
+    wrapper_src: "vintf.hpp",
+    crate_name: "keystore2_vintf_bindgen",
+    source_stem: "bindings",
+    host_supported: true,
+    shared_libs: ["libvintf"],
+    bindgen_flags: [
+        "--size_t-is-usize",
+        "--allowlist-function", "getHalNames",
+        "--allowlist-function", "getHalNamesAndVersions",
+        "--allowlist-function", "getHidlInstances",
+        "--allowlist-function", "getAidlInstances",
+        "--allowlist-function", "freeNames",
+    ],
+}
+
+rust_test {
+    name: "keystore2_vintf_test",
+    crate_name: "keystore2_vintf_test",
+    srcs: ["lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    rustlibs: [
+        "libkeystore2_vintf_bindgen",
+    ],
+    static_libs: [
+        "libkeystore2_vintf_cpp",
+    ],
+    shared_libs: [
+        "libc++",
+        "libvintf",
+    ],
+}
diff --git a/keystore2/src/vintf/lib.rs b/keystore2/src/vintf/lib.rs
new file mode 100644
index 0000000..8730a3e
--- /dev/null
+++ b/keystore2/src/vintf/lib.rs
@@ -0,0 +1,127 @@
+// Copyright 2021, 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.
+
+//! Bindings for getting the list of HALs.
+
+use keystore2_vintf_bindgen::{
+    freeNames, getAidlInstances, getHalNames, getHalNamesAndVersions, getHidlInstances,
+};
+use std::ffi::{CStr, CString};
+use std::os::raw::c_char;
+use std::str::Utf8Error;
+
+/// A struct that contains a list of HALs (optionally with version numbers).
+/// To use it, call as_vec to get a Vec view of the data it contains.
+pub struct HalNames {
+    data: *mut *mut c_char,
+    len: usize,
+}
+
+impl Drop for HalNames {
+    fn drop(&mut self) {
+        // Safety: The memory is allocated by our C shim so it must free it as well.
+        unsafe { freeNames(self.data, self.len) }
+    }
+}
+
+impl<'a> HalNames {
+    /// Get a Vec view of the list of HALs.
+    pub fn as_vec(&'a self) -> Result<Vec<&'a str>, Utf8Error> {
+        // Safety: self.data contains self.len C strings.
+        // The lifetimes ensure that the HalNames (and hence the strings) live
+        // at least as long as the returned vector.
+        unsafe { (0..self.len).map(|i| CStr::from_ptr(*self.data.add(i)).to_str()) }.collect()
+    }
+}
+
+/// Gets all HAL names.
+/// Note that this is not a zero-cost shim: it will make copies of the strings.
+pub fn get_hal_names() -> HalNames {
+    let mut len: usize = 0;
+    // Safety: We'll wrap this in HalNames to free the memory it allocates.
+    // It stores the size of the array it returns in len.
+    let raw_strs = unsafe { getHalNames(&mut len) };
+    HalNames { data: raw_strs, len }
+}
+
+/// Gets all HAL names and versions.
+/// Note that this is not a zero-cost shim: it will make copies of the strings.
+pub fn get_hal_names_and_versions() -> HalNames {
+    let mut len: usize = 0;
+    // Safety: We'll wrap this in HalNames to free the memory it allocates.
+    // It stores the size of the array it returns in len.
+    let raw_strs = unsafe { getHalNamesAndVersions(&mut len) };
+    HalNames { data: raw_strs, len }
+}
+
+/// Gets the instances of the given package, version, and interface tuple.
+/// Note that this is not a zero-cost shim: it will make copies of the strings.
+pub fn get_hidl_instances(
+    package: &str,
+    major_version: usize,
+    minor_version: usize,
+    interface_name: &str,
+) -> HalNames {
+    let mut len: usize = 0;
+    let packages = CString::new(package).expect("Failed to make CString from package.");
+    let interface_name =
+        CString::new(interface_name).expect("Failed to make CString from interface_name.");
+    // Safety: We'll wrap this in HalNames to free the memory it allocates.
+    // It stores the size of the array it returns in len.
+    let raw_strs = unsafe {
+        getHidlInstances(
+            &mut len,
+            packages.as_ptr(),
+            major_version,
+            minor_version,
+            interface_name.as_ptr(),
+        )
+    };
+    HalNames { data: raw_strs, len }
+}
+
+/// Gets the instances of the given package, version, and interface tuple.
+/// Note that this is not a zero-cost shim: it will make copies of the strings.
+pub fn get_aidl_instances(package: &str, version: usize, interface_name: &str) -> HalNames {
+    let mut len: usize = 0;
+    let packages = CString::new(package).expect("Failed to make CString from package.");
+    let interface_name =
+        CString::new(interface_name).expect("Failed to make CString from interface_name.");
+    // Safety: We'll wrap this in HalNames to free the memory it allocates.
+    // It stores the size of the array it returns in len.
+    let raw_strs =
+        unsafe { getAidlInstances(&mut len, packages.as_ptr(), version, interface_name.as_ptr()) };
+    HalNames { data: raw_strs, len }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+
+    #[test]
+    fn test() -> Result<(), Utf8Error> {
+        let result = get_hal_names();
+        let names = result.as_vec()?;
+        assert_ne!(names.len(), 0);
+
+        let result = get_hal_names_and_versions();
+        let names_and_versions = result.as_vec()?;
+        assert_ne!(names_and_versions.len(), 0);
+
+        assert!(names_and_versions.len() >= names.len());
+
+        Ok(())
+    }
+}
diff --git a/keystore2/src/vintf/vintf.cpp b/keystore2/src/vintf/vintf.cpp
new file mode 100644
index 0000000..e407efa
--- /dev/null
+++ b/keystore2/src/vintf/vintf.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 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 "vintf.hpp"
+
+#include <vintf/HalManifest.h>
+#include <vintf/VintfObject.h>
+
+// Converts a set<string> into a C-style array of C strings.
+static char** convert(const std::set<std::string>& names) {
+    char** ret = new char*[names.size()];
+    char** ptr = ret;
+    for (const auto& name : names) {
+        *(ptr++) = strdup(name.c_str());
+    }
+    return ret;
+}
+
+char** getHalNames(size_t* len) {
+    auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getHalNames();
+    *len = names.size();
+    return convert(names);
+}
+
+char** getHalNamesAndVersions(size_t* len) {
+    auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getHalNamesAndVersions();
+    *len = names.size();
+    return convert(names);
+}
+
+char** getHidlInstances(size_t* len, const char* package, size_t major_version,
+                        size_t minor_version, const char* interfaceName) {
+    android::vintf::Version version(major_version, minor_version);
+    auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getHidlInstances(package, version, interfaceName);
+    *len = names.size();
+    return convert(names);
+}
+
+char** getAidlInstances(size_t* len, const char* package, size_t version,
+                        const char* interfaceName) {
+    auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getAidlInstances(package, version, interfaceName);
+    *len = names.size();
+    return convert(names);
+}
+
+void freeNames(char** names, size_t len) {
+    for (int i = 0; i < len; i++) {
+        free(names[i]);
+    }
+    delete[] names;
+}
diff --git a/keystore2/src/vintf/vintf.hpp b/keystore2/src/vintf/vintf.hpp
new file mode 100644
index 0000000..091e8e8
--- /dev/null
+++ b/keystore2/src/vintf/vintf.hpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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 __VINTF_H__
+#define __VINTF_H__
+
+#include <stddef.h>
+
+extern "C" {
+
+char** getHalNames(size_t* len);
+char** getHalNamesAndVersions(size_t* len);
+char** getHidlInstances(size_t* len, const char* package, size_t major_version,
+                        size_t minor_version, const char* interfaceName);
+char** getAidlInstances(size_t* len, const char* package, size_t version,
+                        const char* interfaceName);
+void freeNames(char** names, size_t len);
+}
+
+#endif  //  __VINTF_H__
diff --git a/keystore2/src/watchdog.rs b/keystore2/src/watchdog.rs
new file mode 100644
index 0000000..9cca171
--- /dev/null
+++ b/keystore2/src/watchdog.rs
@@ -0,0 +1,326 @@
+// Copyright 2021, 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.
+
+// Can be removed when instrumentations are added to keystore.
+#![allow(dead_code)]
+
+//! This module implements a watchdog thread.
+
+use std::{
+    cmp::min,
+    collections::HashMap,
+    sync::Arc,
+    sync::{Condvar, Mutex, MutexGuard},
+    thread,
+};
+use std::{
+    marker::PhantomData,
+    time::{Duration, Instant},
+};
+
+/// Represents a Watchdog record. It can be created with `Watchdog::watch` or
+/// `Watchdog::watch_with`. It disarms the record when dropped.
+pub struct WatchPoint {
+    id: &'static str,
+    wd: Arc<Watchdog>,
+    not_send: PhantomData<*mut ()>, // WatchPoint must not be Send.
+}
+
+impl Drop for WatchPoint {
+    fn drop(&mut self) {
+        self.wd.disarm(self.id)
+    }
+}
+
+#[derive(Debug, PartialEq, Eq)]
+enum State {
+    NotRunning,
+    Running,
+}
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+struct Index {
+    tid: thread::ThreadId,
+    id: &'static str,
+}
+
+struct Record {
+    started: Instant,
+    deadline: Instant,
+    callback: Option<Box<dyn Fn() -> String + Send + 'static>>,
+}
+
+struct WatchdogState {
+    state: State,
+    thread: Option<thread::JoinHandle<()>>,
+    timeout: Duration,
+    records: HashMap<Index, Record>,
+    last_report: Instant,
+    has_overdue: bool,
+}
+
+impl WatchdogState {
+    fn update_overdue_and_find_next_timeout(&mut self) -> (bool, Option<Duration>) {
+        let now = Instant::now();
+        let mut next_timeout: Option<Duration> = None;
+        let mut has_overdue = false;
+        for (_, r) in self.records.iter() {
+            let timeout = r.deadline.saturating_duration_since(now);
+            if timeout == Duration::new(0, 0) {
+                has_overdue = true;
+                continue;
+            }
+            next_timeout = match next_timeout {
+                Some(nt) => {
+                    if timeout < nt {
+                        Some(timeout)
+                    } else {
+                        Some(nt)
+                    }
+                }
+                None => Some(timeout),
+            };
+        }
+        (has_overdue, next_timeout)
+    }
+
+    fn log_report(&mut self, has_overdue: bool) -> bool {
+        match (self.has_overdue, has_overdue) {
+            (true, true) => {
+                if self.last_report.elapsed() < Watchdog::NOISY_REPORT_TIMEOUT {
+                    self.has_overdue = false;
+                    return false;
+                }
+            }
+            (_, false) => {
+                self.has_overdue = false;
+                return false;
+            }
+            (false, true) => {}
+        }
+        self.last_report = Instant::now();
+        self.has_overdue = has_overdue;
+        log::warn!("Keystore Watchdog report:");
+        log::warn!("Overdue records:");
+        let now = Instant::now();
+        for (i, r) in self.records.iter() {
+            if r.deadline.saturating_duration_since(now) == Duration::new(0, 0) {
+                match &r.callback {
+                    Some(cb) => {
+                        log::warn!(
+                            "{:?} {} Pending: {:?} Overdue {:?}: {}",
+                            i.tid,
+                            i.id,
+                            r.started.elapsed(),
+                            r.deadline.elapsed(),
+                            (cb)()
+                        );
+                    }
+                    None => {
+                        log::warn!(
+                            "{:?} {} Pending: {:?} Overdue {:?}",
+                            i.tid,
+                            i.id,
+                            r.started.elapsed(),
+                            r.deadline.elapsed()
+                        );
+                    }
+                }
+            }
+        }
+        true
+    }
+
+    fn disarm(&mut self, index: Index) {
+        self.records.remove(&index);
+    }
+
+    fn arm(&mut self, index: Index, record: Record) {
+        if self.records.insert(index.clone(), record).is_some() {
+            log::warn!("Recursive watchdog record at \"{:?}\" replaces previous record.", index);
+        }
+    }
+}
+
+/// Watchdog spawns a thread that logs records of all overdue watch points when a deadline
+/// is missed and at least every second as long as overdue watch points exist.
+/// The thread terminates when idle for a given period of time.
+pub struct Watchdog {
+    state: Arc<(Condvar, Mutex<WatchdogState>)>,
+}
+
+impl Watchdog {
+    /// If we have overdue records, we want to be noisy about it and log a report
+    /// at least every `NOISY_REPORT_TIMEOUT` interval.
+    const NOISY_REPORT_TIMEOUT: Duration = Duration::from_secs(1);
+
+    /// Construct a [`Watchdog`]. When `timeout` has elapsed since the watchdog thread became
+    /// idle, i.e., there are no more active or overdue watch points, the watchdog thread
+    /// terminates.
+    pub fn new(timeout: Duration) -> Arc<Self> {
+        Arc::new(Self {
+            state: Arc::new((
+                Condvar::new(),
+                Mutex::new(WatchdogState {
+                    state: State::NotRunning,
+                    thread: None,
+                    timeout,
+                    records: HashMap::new(),
+                    last_report: Instant::now(),
+                    has_overdue: false,
+                }),
+            )),
+        })
+    }
+
+    fn watch_with_optional(
+        wd: &Arc<Self>,
+        callback: Option<Box<dyn Fn() -> String + Send + 'static>>,
+        id: &'static str,
+        timeout: Duration,
+    ) -> Option<WatchPoint> {
+        let deadline = Instant::now().checked_add(timeout);
+        if deadline.is_none() {
+            log::warn!("Deadline computation failed for WatchPoint \"{}\"", id);
+            log::warn!("WatchPoint not armed.");
+            return None;
+        }
+        wd.arm(callback, id, deadline.unwrap());
+        Some(WatchPoint { id, wd: wd.clone(), not_send: Default::default() })
+    }
+
+    /// Create a new watch point. If the WatchPoint is not dropped before the timeout
+    /// expires, a report is logged at least every second, which includes the id string
+    /// and whatever string the callback returns.
+    pub fn watch_with(
+        wd: &Arc<Self>,
+        id: &'static str,
+        timeout: Duration,
+        callback: impl Fn() -> String + Send + 'static,
+    ) -> Option<WatchPoint> {
+        Self::watch_with_optional(wd, Some(Box::new(callback)), id, timeout)
+    }
+
+    /// Like `watch_with`, but without a callback.
+    pub fn watch(wd: &Arc<Self>, id: &'static str, timeout: Duration) -> Option<WatchPoint> {
+        Self::watch_with_optional(wd, None, id, timeout)
+    }
+
+    fn arm(
+        &self,
+        callback: Option<Box<dyn Fn() -> String + Send + 'static>>,
+        id: &'static str,
+        deadline: Instant,
+    ) {
+        let tid = thread::current().id();
+        let index = Index { tid, id };
+        let record = Record { started: Instant::now(), deadline, callback };
+
+        let (ref condvar, ref state) = *self.state;
+
+        let mut state = state.lock().unwrap();
+        state.arm(index, record);
+
+        if state.state != State::Running {
+            self.spawn_thread(&mut state);
+        }
+        drop(state);
+        condvar.notify_all();
+    }
+
+    fn disarm(&self, id: &'static str) {
+        let tid = thread::current().id();
+        let index = Index { tid, id };
+        let (_, ref state) = *self.state;
+
+        let mut state = state.lock().unwrap();
+        state.disarm(index);
+        // There is no need to notify condvar. There is no action required for the
+        // watchdog thread before the next deadline.
+    }
+
+    fn spawn_thread(&self, state: &mut MutexGuard<WatchdogState>) {
+        if let Some(t) = state.thread.take() {
+            t.join().expect("Watchdog thread panicked.");
+        }
+
+        let cloned_state = self.state.clone();
+
+        state.thread = Some(thread::spawn(move || {
+            let (ref condvar, ref state) = *cloned_state;
+
+            let mut state = state.lock().unwrap();
+
+            loop {
+                let (has_overdue, next_timeout) = state.update_overdue_and_find_next_timeout();
+                state.log_report(has_overdue);
+                let (next_timeout, idle) = match (has_overdue, next_timeout) {
+                    (true, Some(next_timeout)) => {
+                        (min(next_timeout, Self::NOISY_REPORT_TIMEOUT), false)
+                    }
+                    (false, Some(next_timeout)) => (next_timeout, false),
+                    (true, None) => (Self::NOISY_REPORT_TIMEOUT, false),
+                    (false, None) => (state.timeout, true),
+                };
+
+                let (s, timeout) = condvar.wait_timeout(state, next_timeout).unwrap();
+                state = s;
+
+                if idle && timeout.timed_out() && state.records.is_empty() {
+                    state.state = State::NotRunning;
+                    break;
+                }
+            }
+            log::info!("Watchdog thread idle -> terminating. Have a great day.");
+        }));
+        state.state = State::Running;
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use std::sync::atomic;
+    use std::thread;
+    use std::time::Duration;
+
+    #[test]
+    fn test_watchdog() {
+        android_logger::init_once(
+            android_logger::Config::default()
+                .with_tag("keystore2_watchdog_tests")
+                .with_min_level(log::Level::Debug),
+        );
+
+        let wd = Watchdog::new(Watchdog::NOISY_REPORT_TIMEOUT.checked_mul(3).unwrap());
+        let hit_count = Arc::new(atomic::AtomicU8::new(0));
+        let hit_count_clone = hit_count.clone();
+        let wp =
+            Watchdog::watch_with(&wd, "test_watchdog", Duration::from_millis(100), move || {
+                format!("hit_count: {}", hit_count_clone.fetch_add(1, atomic::Ordering::Relaxed))
+            });
+        assert_eq!(0, hit_count.load(atomic::Ordering::Relaxed));
+        thread::sleep(Duration::from_millis(500));
+        assert_eq!(1, hit_count.load(atomic::Ordering::Relaxed));
+        thread::sleep(Watchdog::NOISY_REPORT_TIMEOUT);
+        assert_eq!(2, hit_count.load(atomic::Ordering::Relaxed));
+        drop(wp);
+        thread::sleep(Watchdog::NOISY_REPORT_TIMEOUT.checked_mul(4).unwrap());
+        assert_eq!(2, hit_count.load(atomic::Ordering::Relaxed));
+        let (_, ref state) = *wd.state;
+        let state = state.lock().unwrap();
+        assert_eq!(state.state, State::NotRunning);
+    }
+}
diff --git a/keystore2/system_property/Android.bp b/keystore2/system_property/Android.bp
new file mode 100644
index 0000000..9e7b056
--- /dev/null
+++ b/keystore2/system_property/Android.bp
@@ -0,0 +1,52 @@
+// Copyright 2021, 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 {
+    // 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_bindgen {
+    name: "libkeystore2_system_property_bindgen",
+    wrapper_src: "system_property_bindgen.hpp",
+    crate_name: "keystore2_system_property_bindgen",
+    source_stem: "bindings",
+
+    bindgen_flags: [
+        "--size_t-is-usize",
+        "--allowlist-function=__system_property_find",
+        "--allowlist-function=__system_property_read_callback",
+        "--allowlist-function=__system_property_wait",
+    ],
+}
+
+rust_library {
+    name: "libkeystore2_system_property-rust",
+    crate_name: "keystore2_system_property",
+    srcs: [
+        "lib.rs",
+    ],
+    rustlibs: [
+        "libanyhow",
+        "libkeystore2_system_property_bindgen",
+        "libthiserror",
+    ],
+    shared_libs: [
+        "libbase",
+    ],
+}
diff --git a/keystore2/system_property/lib.rs b/keystore2/system_property/lib.rs
new file mode 100644
index 0000000..be13c88
--- /dev/null
+++ b/keystore2/system_property/lib.rs
@@ -0,0 +1,191 @@
+// Copyright 2021, 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.
+
+//! This crate provides the PropertyWatcher type, which watches for changes
+//! in Android system properties.
+
+use keystore2_system_property_bindgen::prop_info as PropInfo;
+use std::os::raw::c_char;
+use std::ptr::null;
+use std::{
+    ffi::{c_void, CStr, CString},
+    str::Utf8Error,
+};
+use thiserror::Error;
+
+/// Errors this crate can generate
+#[derive(Error, Debug)]
+pub enum PropertyWatcherError {
+    /// We can't watch for a property whose name contains a NUL character.
+    #[error("Cannot convert name to C string")]
+    BadNameError(#[from] std::ffi::NulError),
+    /// We can only watch for properties that exist when the watcher is created.
+    #[error("System property is absent")]
+    SystemPropertyAbsent,
+    /// __system_property_wait timed out despite being given no timeout.
+    #[error("Wait failed")]
+    WaitFailed,
+    /// read callback was not called
+    #[error("__system_property_read_callback did not call callback")]
+    ReadCallbackNotCalled,
+    /// read callback gave us a NULL pointer
+    #[error("__system_property_read_callback gave us a NULL pointer instead of a string")]
+    MissingCString,
+    /// read callback gave us a bad C string
+    #[error("__system_property_read_callback gave us a non-UTF8 C string")]
+    BadCString(#[from] Utf8Error),
+    /// read callback returned an error
+    #[error("Callback failed")]
+    CallbackError(#[from] anyhow::Error),
+}
+
+/// Result type specific for this crate.
+pub type Result<T> = std::result::Result<T, PropertyWatcherError>;
+
+/// PropertyWatcher takes the name of an Android system property such
+/// as `keystore.boot_level`; it can report the current value of this
+/// property, or wait for it to change.
+pub struct PropertyWatcher {
+    prop_name: CString,
+    prop_info: *const PropInfo,
+    serial: keystore2_system_property_bindgen::__uint32_t,
+}
+
+impl PropertyWatcher {
+    /// Create a PropertyWatcher for the named system property.
+    pub fn new(name: &str) -> Result<Self> {
+        Ok(Self { prop_name: CString::new(name)?, prop_info: null(), serial: 0 })
+    }
+
+    // Lazy-initializing accessor for self.prop_info.
+    fn get_prop_info(&mut self) -> Option<*const PropInfo> {
+        if self.prop_info.is_null() {
+            // Unsafe required for FFI call. Input and output are both const.
+            // The returned pointer is valid for the lifetime of the program.
+            self.prop_info = unsafe {
+                keystore2_system_property_bindgen::__system_property_find(self.prop_name.as_ptr())
+            };
+        }
+        if self.prop_info.is_null() {
+            None
+        } else {
+            Some(self.prop_info)
+        }
+    }
+
+    fn read_raw(prop_info: *const PropInfo, mut f: impl FnOnce(Option<&CStr>, Option<&CStr>)) {
+        // Unsafe function converts values passed to us by
+        // __system_property_read_callback to Rust form
+        // and pass them to inner callback.
+        unsafe extern "C" fn callback(
+            res_p: *mut c_void,
+            name: *const c_char,
+            value: *const c_char,
+            _: keystore2_system_property_bindgen::__uint32_t,
+        ) {
+            let name = if name.is_null() { None } else { Some(CStr::from_ptr(name)) };
+            let value = if value.is_null() { None } else { Some(CStr::from_ptr(value)) };
+            let f = &mut *res_p.cast::<&mut dyn FnMut(Option<&CStr>, Option<&CStr>)>();
+            f(name, value);
+        }
+
+        let mut f: &mut dyn FnOnce(Option<&CStr>, Option<&CStr>) = &mut f;
+
+        // Unsafe block for FFI call. We convert the FnOnce
+        // to a void pointer, and unwrap it in our callback.
+        unsafe {
+            keystore2_system_property_bindgen::__system_property_read_callback(
+                prop_info,
+                Some(callback),
+                &mut f as *mut _ as *mut c_void,
+            )
+        }
+    }
+
+    /// Call the passed function, passing it the name and current value
+    /// of this system property. See documentation for
+    /// `__system_property_read_callback` for details.
+    /// Returns an error if the property is empty or doesn't exist.
+    pub fn read<T, F>(&mut self, f: F) -> Result<T>
+    where
+        F: FnOnce(&str, &str) -> anyhow::Result<T>,
+    {
+        let prop_info = self.get_prop_info().ok_or(PropertyWatcherError::SystemPropertyAbsent)?;
+        let mut result = Err(PropertyWatcherError::ReadCallbackNotCalled);
+        Self::read_raw(prop_info, |name, value| {
+            // use a wrapping closure as an erzatz try block.
+            result = (|| {
+                let name = name.ok_or(PropertyWatcherError::MissingCString)?.to_str()?;
+                let value = value.ok_or(PropertyWatcherError::MissingCString)?.to_str()?;
+                f(name, value).map_err(PropertyWatcherError::CallbackError)
+            })()
+        });
+        result
+    }
+
+    // Waits for the property that self is watching to be created. Returns immediately if the
+    // property already exists.
+    fn wait_for_property_creation(&mut self) -> Result<()> {
+        let mut global_serial = 0;
+        loop {
+            match self.get_prop_info() {
+                Some(_) => return Ok(()),
+                None => {
+                    // Unsafe call for FFI. The function modifies only global_serial, and has
+                    // no side-effects.
+                    if !unsafe {
+                        // Wait for a global serial number change, then try again. On success,
+                        // the function will update global_serial with the last version seen.
+                        keystore2_system_property_bindgen::__system_property_wait(
+                            null(),
+                            global_serial,
+                            &mut global_serial,
+                            null(),
+                        )
+                    } {
+                        return Err(PropertyWatcherError::WaitFailed);
+                    }
+                }
+            }
+        }
+    }
+
+    /// Wait for the system property to change. This
+    /// records the serial number of the last change, so
+    /// race conditions are avoided.
+    pub fn wait(&mut self) -> Result<()> {
+        // If the property is null, then wait for it to be created. Subsequent waits will
+        // skip this step and wait for our specific property to change.
+        if self.prop_info.is_null() {
+            return self.wait_for_property_creation();
+        }
+
+        let mut new_serial = self.serial;
+        // Unsafe block to call __system_property_wait.
+        // All arguments are private to PropertyWatcher so we
+        // can be confident they are valid.
+        if !unsafe {
+            keystore2_system_property_bindgen::__system_property_wait(
+                self.prop_info,
+                self.serial,
+                &mut new_serial,
+                null(),
+            )
+        } {
+            return Err(PropertyWatcherError::WaitFailed);
+        }
+        self.serial = new_serial;
+        Ok(())
+    }
+}
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/keystore2/system_property/system_property_bindgen.hpp
similarity index 76%
rename from keystore/binder/android/security/keymaster/OperationResult.aidl
rename to keystore2/system_property/system_property_bindgen.hpp
index db689d4..e3c1ade 100644
--- a/keystore/binder/android/security/keymaster/OperationResult.aidl
+++ b/keystore2/system_property/system_property_bindgen.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -13,8 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#pragma once
 
-package android.security.keymaster;
-
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
+#include "sys/system_properties.h"
diff --git a/keystore2/test_utils/lib.rs b/keystore2/test_utils/lib.rs
new file mode 100644
index 0000000..627af20
--- /dev/null
+++ b/keystore2/test_utils/lib.rs
@@ -0,0 +1,104 @@
+// Copyright 2020, 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.
+
+//! Implements TempDir which aids in creating an cleaning up temporary directories for testing.
+
+use std::fs::{create_dir, remove_dir_all};
+use std::io::ErrorKind;
+use std::path::{Path, PathBuf};
+use std::{env::temp_dir, ops::Deref};
+
+/// Represents the lifecycle of a temporary directory for testing.
+#[derive(Debug)]
+pub struct TempDir {
+    path: std::path::PathBuf,
+    do_drop: bool,
+}
+
+impl TempDir {
+    /// Creates a temporary directory with a name of the form <prefix>_NNNNN where NNNNN is a zero
+    /// padded random number with 5 figures. The prefix must not contain file system separators.
+    /// The location of the directory cannot be chosen.
+    /// The directory with all of its content is removed from the file system when the resulting
+    /// object gets dropped.
+    pub fn new(prefix: &str) -> std::io::Result<Self> {
+        let tmp = loop {
+            let mut tmp = temp_dir();
+            let number: u16 = rand::random();
+            tmp.push(format!("{}_{:05}", prefix, number));
+            match create_dir(&tmp) {
+                Err(e) => match e.kind() {
+                    ErrorKind::AlreadyExists => continue,
+                    _ => return Err(e),
+                },
+                Ok(()) => break tmp,
+            }
+        };
+        Ok(Self { path: tmp, do_drop: true })
+    }
+
+    /// Returns the absolute path of the temporary directory.
+    pub fn path(&self) -> &Path {
+        &self.path
+    }
+
+    /// Returns a path builder for convenient extension of the path.
+    ///
+    /// ## Example:
+    ///
+    /// ```
+    /// let tdir = TempDir::new("my_test")?;
+    /// let temp_foo_bar = tdir.build().push("foo").push("bar");
+    /// ```
+    /// `temp_foo_bar` derefs to a Path that represents "<tdir.path()>/foo/bar"
+    pub fn build(&self) -> PathBuilder {
+        PathBuilder(self.path.clone())
+    }
+
+    /// When a test is failing you can set this to false in order to inspect
+    /// the directory structure after the test failed.
+    #[allow(dead_code)]
+    pub fn do_not_drop(&mut self) {
+        println!("Disabled automatic cleanup for: {:?}", self.path);
+        log::info!("Disabled automatic cleanup for: {:?}", self.path);
+        self.do_drop = false;
+    }
+}
+
+impl Drop for TempDir {
+    fn drop(&mut self) {
+        if self.do_drop {
+            remove_dir_all(&self.path).expect("Cannot delete temporary dir.");
+        }
+    }
+}
+
+/// Allows for convenient building of paths from a TempDir. See TempDir.build() for more details.
+pub struct PathBuilder(PathBuf);
+
+impl PathBuilder {
+    /// Adds another segment to the end of the path. Consumes, modifies and returns self.
+    pub fn push(mut self, segment: &str) -> Self {
+        self.0.push(segment);
+        self
+    }
+}
+
+impl Deref for PathBuilder {
+    type Target = Path;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
diff --git a/keystore2/vpnprofilestore/Android.bp b/keystore2/vpnprofilestore/Android.bp
new file mode 100644
index 0000000..7ddf0d6
--- /dev/null
+++ b/keystore2/vpnprofilestore/Android.bp
@@ -0,0 +1,57 @@
+// Copyright 2021, 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 {
+    // 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: "libvpnprofilestore-rust",
+    crate_name: "vpnprofilestore",
+    srcs: [
+        "lib.rs",
+    ],
+    rustlibs: [
+        "android.security.vpnprofilestore-rust",
+        "libanyhow",
+        "libbinder_rs",
+        "libkeystore2",
+        "liblog_rust",
+        "librusqlite",
+        "libthiserror",
+    ],
+}
+
+rust_test {
+    name: "vpnprofilestore_test",
+    crate_name: "vpnprofilestore",
+    srcs: ["lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    rustlibs: [
+        "android.security.vpnprofilestore-rust",
+        "libanyhow",
+        "libbinder_rs",
+        "libkeystore2",
+        "libkeystore2_test_utils",
+        "liblog_rust",
+        "librusqlite",
+        "libthiserror",
+    ],
+}
diff --git a/keystore2/vpnprofilestore/lib.rs b/keystore2/vpnprofilestore/lib.rs
new file mode 100644
index 0000000..8b3bc2b
--- /dev/null
+++ b/keystore2/vpnprofilestore/lib.rs
@@ -0,0 +1,558 @@
+// Copyright 2020, 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.
+
+//! Implements the android.security.vpnprofilestore interface.
+
+use android_security_vpnprofilestore::aidl::android::security::vpnprofilestore::{
+    IVpnProfileStore::BnVpnProfileStore, IVpnProfileStore::IVpnProfileStore,
+    IVpnProfileStore::ERROR_PROFILE_NOT_FOUND, IVpnProfileStore::ERROR_SYSTEM_ERROR,
+};
+use android_security_vpnprofilestore::binder::{
+    BinderFeatures, ExceptionCode, Result as BinderResult, Status as BinderStatus, Strong,
+    ThreadState,
+};
+use anyhow::{Context, Result};
+use keystore2::{async_task::AsyncTask, legacy_blob::LegacyBlobLoader, utils::watchdog as wd};
+use rusqlite::{
+    params, Connection, OptionalExtension, Transaction, TransactionBehavior, NO_PARAMS,
+};
+use std::{
+    collections::HashSet,
+    path::{Path, PathBuf},
+};
+
+struct DB {
+    conn: Connection,
+}
+
+impl DB {
+    fn new(db_file: &Path) -> Result<Self> {
+        let mut db = Self {
+            conn: Connection::open(db_file).context("Failed to initialize SQLite connection.")?,
+        };
+
+        // On busy fail Immediately. It is unlikely to succeed given a bug in sqlite.
+        db.conn.busy_handler(None).context("Failed to set busy handler.")?;
+
+        db.init_tables().context("Trying to initialize vpnstore db.")?;
+        Ok(db)
+    }
+
+    fn with_transaction<T, F>(&mut self, behavior: TransactionBehavior, f: F) -> Result<T>
+    where
+        F: Fn(&Transaction) -> Result<T>,
+    {
+        loop {
+            match self
+                .conn
+                .transaction_with_behavior(behavior)
+                .context("In with_transaction.")
+                .and_then(|tx| f(&tx).map(|result| (result, tx)))
+                .and_then(|(result, tx)| {
+                    tx.commit().context("In with_transaction: Failed to commit transaction.")?;
+                    Ok(result)
+                }) {
+                Ok(result) => break Ok(result),
+                Err(e) => {
+                    if Self::is_locked_error(&e) {
+                        std::thread::sleep(std::time::Duration::from_micros(500));
+                        continue;
+                    } else {
+                        return Err(e).context("In with_transaction.");
+                    }
+                }
+            }
+        }
+    }
+
+    fn is_locked_error(e: &anyhow::Error) -> bool {
+        matches!(
+            e.root_cause().downcast_ref::<rusqlite::ffi::Error>(),
+            Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseBusy, .. })
+                | Some(rusqlite::ffi::Error { code: rusqlite::ErrorCode::DatabaseLocked, .. })
+        )
+    }
+
+    fn init_tables(&mut self) -> Result<()> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "CREATE TABLE IF NOT EXISTS profiles (
+                     owner INTEGER,
+                     alias BLOB,
+                     profile BLOB,
+                     UNIQUE(owner, alias));",
+                NO_PARAMS,
+            )
+            .context("Failed to initialize \"profiles\" table.")?;
+            Ok(())
+        })
+    }
+
+    fn list(&mut self, caller_uid: u32) -> Result<Vec<String>> {
+        self.with_transaction(TransactionBehavior::Deferred, |tx| {
+            let mut stmt = tx
+                .prepare("SELECT alias FROM profiles WHERE owner = ? ORDER BY alias ASC;")
+                .context("In list: Failed to prepare statement.")?;
+
+            let aliases = stmt
+                .query_map(params![caller_uid], |row| row.get(0))?
+                .collect::<rusqlite::Result<Vec<String>>>()
+                .context("In list: query_map failed.");
+            aliases
+        })
+    }
+
+    fn put(&mut self, caller_uid: u32, alias: &str, profile: &[u8]) -> Result<()> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "INSERT OR REPLACE INTO profiles (owner, alias, profile) values (?, ?, ?)",
+                params![caller_uid, alias, profile,],
+            )
+            .context("In put: Failed to insert or replace.")?;
+            Ok(())
+        })
+    }
+
+    fn get(&mut self, caller_uid: u32, alias: &str) -> Result<Option<Vec<u8>>> {
+        self.with_transaction(TransactionBehavior::Deferred, |tx| {
+            tx.query_row(
+                "SELECT profile FROM profiles WHERE owner = ? AND alias = ?;",
+                params![caller_uid, alias],
+                |row| row.get(0),
+            )
+            .optional()
+            .context("In get: failed loading profile.")
+        })
+    }
+
+    fn remove(&mut self, caller_uid: u32, alias: &str) -> Result<bool> {
+        let removed = self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "DELETE FROM profiles WHERE owner = ? AND alias = ?;",
+                params![caller_uid, alias],
+            )
+            .context("In remove: Failed to delete row.")
+        })?;
+        Ok(removed == 1)
+    }
+}
+
+/// This is the main VpnProfileStore error type, it wraps binder exceptions and the
+/// VnpStore errors.
+#[derive(Debug, thiserror::Error, PartialEq)]
+pub enum Error {
+    /// Wraps a VpnProfileStore error code.
+    #[error("Error::Error({0:?})")]
+    Error(i32),
+    /// Wraps a Binder exception code other than a service specific exception.
+    #[error("Binder exception code {0:?}, {1:?}")]
+    Binder(ExceptionCode, i32),
+}
+
+impl Error {
+    /// Short hand for `Error::Error(ERROR_SYSTEM_ERROR)`
+    pub fn sys() -> Self {
+        Error::Error(ERROR_SYSTEM_ERROR)
+    }
+
+    /// Short hand for `Error::Error(ERROR_PROFILE_NOT_FOUND)`
+    pub fn not_found() -> Self {
+        Error::Error(ERROR_PROFILE_NOT_FOUND)
+    }
+}
+
+/// This function should be used by vpnprofilestore service calls to translate error conditions
+/// into service specific exceptions.
+///
+/// All error conditions get logged by this function, except for ERROR_PROFILE_NOT_FOUND error.
+///
+/// `Error::Error(x)` variants get mapped onto a service specific error code of `x`.
+///
+/// All non `Error` error conditions get mapped onto `ERROR_SYSTEM_ERROR`.
+///
+/// `handle_ok` will be called if `result` is `Ok(value)` where `value` will be passed
+/// as argument to `handle_ok`. `handle_ok` must generate a `BinderResult<T>`, but it
+/// typically returns Ok(value).
+fn map_or_log_err<T, U, F>(result: Result<U>, handle_ok: F) -> BinderResult<T>
+where
+    F: FnOnce(U) -> BinderResult<T>,
+{
+    result.map_or_else(
+        |e| {
+            let root_cause = e.root_cause();
+            let (rc, log_error) = match root_cause.downcast_ref::<Error>() {
+                // Make the profile not found errors silent.
+                Some(Error::Error(ERROR_PROFILE_NOT_FOUND)) => (ERROR_PROFILE_NOT_FOUND, false),
+                Some(Error::Error(e)) => (*e, true),
+                Some(Error::Binder(_, _)) | None => (ERROR_SYSTEM_ERROR, true),
+            };
+            if log_error {
+                log::error!("{:?}", e);
+            }
+            Err(BinderStatus::new_service_specific_error(rc, None))
+        },
+        handle_ok,
+    )
+}
+
+/// Implements IVpnProfileStore AIDL interface.
+pub struct VpnProfileStore {
+    db_path: PathBuf,
+    async_task: AsyncTask,
+}
+
+struct AsyncState {
+    recently_imported: HashSet<(u32, String)>,
+    legacy_loader: LegacyBlobLoader,
+    db_path: PathBuf,
+}
+
+impl VpnProfileStore {
+    /// Creates a new VpnProfileStore instance.
+    pub fn new_native_binder(path: &Path) -> Strong<dyn IVpnProfileStore> {
+        let mut db_path = path.to_path_buf();
+        db_path.push("vpnprofilestore.sqlite");
+
+        let result = Self { db_path, async_task: Default::default() };
+        result.init_shelf(path);
+        BnVpnProfileStore::new_binder(result, BinderFeatures::default())
+    }
+
+    fn open_db(&self) -> Result<DB> {
+        DB::new(&self.db_path).context("In open_db: Failed to open db.")
+    }
+
+    fn get(&self, alias: &str) -> Result<Vec<u8>> {
+        let mut db = self.open_db().context("In get.")?;
+        let calling_uid = ThreadState::get_calling_uid();
+
+        if let Some(profile) =
+            db.get(calling_uid, alias).context("In get: Trying to load profile from DB.")?
+        {
+            return Ok(profile);
+        }
+        if self.get_legacy(calling_uid, alias).context("In get: Trying to migrate legacy blob.")? {
+            // If we were able to migrate a legacy blob try again.
+            if let Some(profile) =
+                db.get(calling_uid, alias).context("In get: Trying to load profile from DB.")?
+            {
+                return Ok(profile);
+            }
+        }
+        Err(Error::not_found()).context("In get: No such profile.")
+    }
+
+    fn put(&self, alias: &str, profile: &[u8]) -> Result<()> {
+        let calling_uid = ThreadState::get_calling_uid();
+        // In order to make sure that we don't have stale legacy profiles, make sure they are
+        // migrated before replacing them.
+        let _ = self.get_legacy(calling_uid, alias);
+        let mut db = self.open_db().context("In put.")?;
+        db.put(calling_uid, alias, profile).context("In put: Trying to insert profile into DB.")
+    }
+
+    fn remove(&self, alias: &str) -> Result<()> {
+        let calling_uid = ThreadState::get_calling_uid();
+        let mut db = self.open_db().context("In remove.")?;
+        // In order to make sure that we don't have stale legacy profiles, make sure they are
+        // migrated before removing them.
+        let _ = self.get_legacy(calling_uid, alias);
+        let removed = db
+            .remove(calling_uid, alias)
+            .context("In remove: Trying to remove profile from DB.")?;
+        if removed {
+            Ok(())
+        } else {
+            Err(Error::not_found()).context("In remove: No such profile.")
+        }
+    }
+
+    fn list(&self, prefix: &str) -> Result<Vec<String>> {
+        let mut db = self.open_db().context("In list.")?;
+        let calling_uid = ThreadState::get_calling_uid();
+        let mut result = self.list_legacy(calling_uid).context("In list.")?;
+        result
+            .append(&mut db.list(calling_uid).context("In list: Trying to get list of profiles.")?);
+        result = result.into_iter().filter(|s| s.starts_with(prefix)).collect();
+        result.sort_unstable();
+        result.dedup();
+        Ok(result)
+    }
+
+    fn init_shelf(&self, path: &Path) {
+        let mut db_path = path.to_path_buf();
+        self.async_task.queue_hi(move |shelf| {
+            let legacy_loader = LegacyBlobLoader::new(&db_path);
+            db_path.push("vpnprofilestore.sqlite");
+
+            shelf.put(AsyncState { legacy_loader, db_path, recently_imported: Default::default() });
+        })
+    }
+
+    fn do_serialized<F, T: Send + 'static>(&self, f: F) -> Result<T>
+    where
+        F: FnOnce(&mut AsyncState) -> Result<T> + Send + 'static,
+    {
+        let (sender, receiver) = std::sync::mpsc::channel::<Result<T>>();
+        self.async_task.queue_hi(move |shelf| {
+            let state = shelf.get_downcast_mut::<AsyncState>().expect("Failed to get shelf.");
+            sender.send(f(state)).expect("Failed to send result.");
+        });
+        receiver.recv().context("In do_serialized: Failed to receive result.")?
+    }
+
+    fn list_legacy(&self, uid: u32) -> Result<Vec<String>> {
+        self.do_serialized(move |state| {
+            state
+                .legacy_loader
+                .list_vpn_profiles(uid)
+                .context("Trying to list legacy vnp profiles.")
+        })
+        .context("In list_legacy.")
+    }
+
+    fn get_legacy(&self, uid: u32, alias: &str) -> Result<bool> {
+        let alias = alias.to_string();
+        self.do_serialized(move |state| {
+            if state.recently_imported.contains(&(uid, alias.clone())) {
+                return Ok(true);
+            }
+            let mut db = DB::new(&state.db_path).context("In open_db: Failed to open db.")?;
+            let migrated =
+                Self::migrate_one_legacy_profile(uid, &alias, &state.legacy_loader, &mut db)
+                    .context("Trying to migrate legacy vpn profile.")?;
+            if migrated {
+                state.recently_imported.insert((uid, alias));
+            }
+            Ok(migrated)
+        })
+        .context("In get_legacy.")
+    }
+
+    fn migrate_one_legacy_profile(
+        uid: u32,
+        alias: &str,
+        legacy_loader: &LegacyBlobLoader,
+        db: &mut DB,
+    ) -> Result<bool> {
+        let blob = legacy_loader
+            .read_vpn_profile(uid, alias)
+            .context("In migrate_one_legacy_profile: Trying to read legacy vpn profile.")?;
+        if let Some(profile) = blob {
+            db.put(uid, alias, &profile)
+                .context("In migrate_one_legacy_profile: Trying to insert profile into DB.")?;
+            legacy_loader
+                .remove_vpn_profile(uid, alias)
+                .context("In migrate_one_legacy_profile: Trying to delete legacy profile.")?;
+            Ok(true)
+        } else {
+            Ok(false)
+        }
+    }
+}
+
+impl binder::Interface for VpnProfileStore {}
+
+impl IVpnProfileStore for VpnProfileStore {
+    fn get(&self, alias: &str) -> BinderResult<Vec<u8>> {
+        let _wp = wd::watch_millis("IVpnProfileStore::get", 500);
+        map_or_log_err(self.get(alias), Ok)
+    }
+    fn put(&self, alias: &str, profile: &[u8]) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IVpnProfileStore::put", 500);
+        map_or_log_err(self.put(alias, profile), Ok)
+    }
+    fn remove(&self, alias: &str) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IVpnProfileStore::remove", 500);
+        map_or_log_err(self.remove(alias), Ok)
+    }
+    fn list(&self, prefix: &str) -> BinderResult<Vec<String>> {
+        let _wp = wd::watch_millis("IVpnProfileStore::list", 500);
+        map_or_log_err(self.list(prefix), Ok)
+    }
+}
+
+#[cfg(test)]
+mod db_test {
+    use super::*;
+    use keystore2_test_utils::TempDir;
+    use std::sync::Arc;
+    use std::thread;
+    use std::time::Duration;
+    use std::time::Instant;
+
+    static TEST_ALIAS: &str = &"test_alias";
+    static TEST_BLOB1: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+    static TEST_BLOB2: &[u8] = &[2, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+    static TEST_BLOB3: &[u8] = &[3, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+    static TEST_BLOB4: &[u8] = &[3, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+
+    #[test]
+    fn test_profile_db() {
+        let test_dir = TempDir::new("profiledb_test_").expect("Failed to create temp dir.");
+        let mut db =
+            DB::new(&test_dir.build().push("vpnprofile.sqlite")).expect("Failed to open database.");
+
+        // Insert three profiles for owner 2.
+        db.put(2, "test1", TEST_BLOB1).expect("Failed to insert test1.");
+        db.put(2, "test2", TEST_BLOB2).expect("Failed to insert test2.");
+        db.put(2, "test3", TEST_BLOB3).expect("Failed to insert test3.");
+
+        // Check list returns all inserted aliases.
+        assert_eq!(
+            vec!["test1".to_string(), "test2".to_string(), "test3".to_string(),],
+            db.list(2).expect("Failed to list profiles.")
+        );
+
+        // There should be no profiles for owner 1.
+        assert_eq!(Vec::<String>::new(), db.list(1).expect("Failed to list profiles."));
+
+        // Check the content of the three entries.
+        assert_eq!(
+            Some(TEST_BLOB1),
+            db.get(2, "test1").expect("Failed to get profile.").as_deref()
+        );
+        assert_eq!(
+            Some(TEST_BLOB2),
+            db.get(2, "test2").expect("Failed to get profile.").as_deref()
+        );
+        assert_eq!(
+            Some(TEST_BLOB3),
+            db.get(2, "test3").expect("Failed to get profile.").as_deref()
+        );
+
+        // Remove test2 and check and check that it is no longer retrievable.
+        assert!(db.remove(2, "test2").expect("Failed to remove profile."));
+        assert!(db.get(2, "test2").expect("Failed to get profile.").is_none());
+
+        // test2 should now no longer be in the list.
+        assert_eq!(
+            vec!["test1".to_string(), "test3".to_string(),],
+            db.list(2).expect("Failed to list profiles.")
+        );
+
+        // Put on existing alias replaces it.
+        // Verify test1 is TEST_BLOB1.
+        assert_eq!(
+            Some(TEST_BLOB1),
+            db.get(2, "test1").expect("Failed to get profile.").as_deref()
+        );
+        db.put(2, "test1", TEST_BLOB4).expect("Failed to replace test1.");
+        // Verify test1 is TEST_BLOB4.
+        assert_eq!(
+            Some(TEST_BLOB4),
+            db.get(2, "test1").expect("Failed to get profile.").as_deref()
+        );
+    }
+
+    #[test]
+    fn concurrent_vpn_profile_test() -> Result<()> {
+        let temp_dir = Arc::new(
+            TempDir::new("concurrent_vpn_profile_test_").expect("Failed to create temp dir."),
+        );
+
+        let db_path = temp_dir.build().push("vpnprofile.sqlite").to_owned();
+
+        let test_begin = Instant::now();
+
+        let mut db = DB::new(&db_path).expect("Failed to open database.");
+        const PROFILE_COUNT: u32 = 5000u32;
+        const PROFILE_DB_COUNT: u32 = 5000u32;
+
+        let mut actual_profile_count = PROFILE_COUNT;
+        // First insert PROFILE_COUNT profiles.
+        for count in 0..PROFILE_COUNT {
+            if Instant::now().duration_since(test_begin) >= Duration::from_secs(15) {
+                actual_profile_count = count;
+                break;
+            }
+            let alias = format!("test_alias_{}", count);
+            db.put(1, &alias, TEST_BLOB1).expect("Failed to add profile (1).");
+        }
+
+        // Insert more keys from a different thread and into a different namespace.
+        let db_path1 = db_path.clone();
+        let handle1 = thread::spawn(move || {
+            let mut db = DB::new(&db_path1).expect("Failed to open database.");
+
+            for count in 0..actual_profile_count {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let alias = format!("test_alias_{}", count);
+                db.put(2, &alias, TEST_BLOB2).expect("Failed to add profile (2).");
+            }
+
+            // Then delete them again.
+            for count in 0..actual_profile_count {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let alias = format!("test_alias_{}", count);
+                db.remove(2, &alias).expect("Remove Failed (2).");
+            }
+        });
+
+        // And start deleting the first set of profiles.
+        let db_path2 = db_path.clone();
+        let handle2 = thread::spawn(move || {
+            let mut db = DB::new(&db_path2).expect("Failed to open database.");
+
+            for count in 0..actual_profile_count {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let alias = format!("test_alias_{}", count);
+                db.remove(1, &alias).expect("Remove Failed (1)).");
+            }
+        });
+
+        // While a lot of inserting and deleting is going on we have to open database connections
+        // successfully and then insert and delete a specific profile.
+        let db_path3 = db_path.clone();
+        let handle3 = thread::spawn(move || {
+            for _count in 0..PROFILE_DB_COUNT {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let mut db = DB::new(&db_path3).expect("Failed to open database.");
+
+                db.put(3, &TEST_ALIAS, TEST_BLOB3).expect("Failed to add profile (3).");
+
+                db.remove(3, &TEST_ALIAS).expect("Remove failed (3).");
+            }
+        });
+
+        // While thread 3 is inserting and deleting TEST_ALIAS, we try to get the alias.
+        // This may yield an entry or none, but it must not fail.
+        let handle4 = thread::spawn(move || {
+            for _count in 0..PROFILE_DB_COUNT {
+                if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
+                    return;
+                }
+                let mut db = DB::new(&db_path).expect("Failed to open database.");
+
+                // This may return Some or None but it must not fail.
+                db.get(3, &TEST_ALIAS).expect("Failed to get profile (4).");
+            }
+        });
+
+        handle1.join().expect("Thread 1 panicked.");
+        handle2.join().expect("Thread 2 panicked.");
+        handle3.join().expect("Thread 3 panicked.");
+        handle4.join().expect("Thread 4 panicked.");
+
+        Ok(())
+    }
+}
diff --git a/ondevice-signing/Android.bp b/ondevice-signing/Android.bp
new file mode 100644
index 0000000..2e5e02e
--- /dev/null
+++ b/ondevice-signing/Android.bp
@@ -0,0 +1,118 @@
+// Copyright (C) 2020 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.
+// 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",
+  "google-runtime-int",
+  "google-runtime-member-string-references",
+  "misc-move-const-arg",
+  "misc-move-forwarding-reference",
+  "misc-unused-parameters",
+  "misc-unused-using-decls",
+  "misc-use-after-move",
+  "modernize-pass-by-value",
+  "performance-faster-string-find",
+  "performance-for-range-copy",
+  "performance-implicit-conversion-in-loop",
+  "performance-inefficient-vector-operation",
+  "performance-move-const-arg",
+  "performance-move-constructor-init",
+  "performance-noexcept-move-constructor",
+  "performance-unnecessary-value-param",
+]
+
+cc_defaults {
+  cpp_std: "experimental",
+  name: "odsign_flags_defaults",
+  cflags: [
+    "-Wall",
+    "-Wextra",
+    "-Werror",
+    "-Wno-unused-parameter",
+
+    // Some extra flags.
+    "-fstrict-aliasing",
+    "-Wredundant-decls",
+    "-Wshadow",
+    "-Wstrict-aliasing",
+    "-Wthread-safety",
+    "-Wthread-safety-negative",
+    "-Wunreachable-code",
+    "-Wunreachable-code-break",
+    "-Wunreachable-code-return",
+    "-Wunused",
+    "-Wused-but-marked-unused",
+  ],
+  tidy: true,
+  tidy_checks: tidy_errors,
+  tidy_checks_as_errors: tidy_errors,
+  tidy_flags: [
+    "-format-style=file",
+  ],
+}
+
+cc_binary {
+  name: "odsign",
+  defaults: [
+    "odsign_flags_defaults",
+  ],
+  cpp_std: "experimental",
+  init_rc: ["odsign.rc"],
+  srcs: [
+    "odsign_main.cpp",
+    "CertUtils.cpp",
+    "Keymaster.cpp",
+    "KeymasterSigningKey.cpp",
+    "KeystoreKey.cpp",
+    "VerityUtils.cpp",
+  ],
+
+  header_libs: ["odrefresh_headers"],
+
+  static_libs: [
+    "libmini_keyctl_static", // TODO need static?
+    "libc++fs",
+    "lib_odsign_proto",
+  ],
+
+  shared_libs: [
+    "android.hardware.keymaster@4.1",
+    "android.system.keystore2-V1-cpp",
+    "android.hardware.security.keymint-V1-cpp",
+    "libbase",
+    "libbinder",
+    "libcrypto",
+    "libcrypto_utils",
+    "libfsverity",
+    "libhidlbase",
+    "liblogwrap",
+    "libkeymaster4support", // For authorization_set
+    "libkeymaster4_1support",
+    "libkeyutils",
+    "libprotobuf-cpp-full",
+    "libutils",
+  ],
+}
diff --git a/ondevice-signing/CertUtils.cpp b/ondevice-signing/CertUtils.cpp
new file mode 100644
index 0000000..b0b75a6
--- /dev/null
+++ b/ondevice-signing/CertUtils.cpp
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2020 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 <android-base/logging.h>
+#include <android-base/result.h>
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/pkcs7.h>
+#include <openssl/rsa.h>
+#include <openssl/x509v3.h>
+
+#include <fcntl.h>
+#include <vector>
+
+#include "KeyConstants.h"
+
+const char kBasicConstraints[] = "CA:TRUE";
+const char kKeyUsage[] = "critical,keyCertSign,cRLSign,digitalSignature";
+const char kSubjectKeyIdentifier[] = "hash";
+constexpr int kCertLifetimeSeconds = 10 * 365 * 24 * 60 * 60;
+
+using android::base::Result;
+// using android::base::ErrnoError;
+using android::base::Error;
+
+static bool add_ext(X509* cert, int nid, const char* value) {
+    size_t len = strlen(value) + 1;
+    std::vector<char> mutableValue(value, value + len);
+    X509V3_CTX context;
+
+    X509V3_set_ctx_nodb(&context);
+
+    X509V3_set_ctx(&context, cert, cert, nullptr, nullptr, 0);
+    X509_EXTENSION* ex = X509V3_EXT_nconf_nid(nullptr, &context, nid, mutableValue.data());
+    if (!ex) {
+        return false;
+    }
+
+    X509_add_ext(cert, ex, -1);
+    X509_EXTENSION_free(ex);
+    return true;
+}
+
+Result<bssl::UniquePtr<RSA>> getRsa(const std::vector<uint8_t>& publicKey) {
+    bssl::UniquePtr<RSA> rsaPubkey(RSA_new());
+    rsaPubkey->n = BN_new();
+    rsaPubkey->e = BN_new();
+
+    BN_bin2bn(publicKey.data(), publicKey.size(), rsaPubkey->n);
+    BN_set_word(rsaPubkey->e, kRsaKeyExponent);
+
+    return rsaPubkey;
+}
+
+Result<void> verifySignature(const std::string& message, const std::string& signature,
+                             const std::vector<uint8_t>& publicKey) {
+    auto rsaKey = getRsa(publicKey);
+    uint8_t hashBuf[SHA256_DIGEST_LENGTH];
+    SHA256(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(message.c_str())),
+           message.length(), hashBuf);
+
+    bool success = RSA_verify(NID_sha256, hashBuf, sizeof(hashBuf),
+                              (const uint8_t*)signature.c_str(), signature.length(), rsaKey->get());
+
+    if (!success) {
+        return Error() << "Failed to verify signature.";
+    }
+    return {};
+}
+
+Result<void> createSelfSignedCertificate(
+    const std::vector<uint8_t>& publicKey,
+    const std::function<Result<std::string>(const std::string&)>& signFunction,
+    const std::string& path) {
+    bssl::UniquePtr<X509> x509(X509_new());
+    if (!x509) {
+        return Error() << "Unable to allocate x509 container";
+    }
+    X509_set_version(x509.get(), 2);
+
+    ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), 1);
+    X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
+    X509_gmtime_adj(X509_get_notAfter(x509.get()), kCertLifetimeSeconds);
+
+    // "publicKey" corresponds to the raw public key bytes - need to create
+    // a new RSA key with the correct exponent.
+    auto rsaPubkey = getRsa(publicKey);
+
+    EVP_PKEY* public_key = EVP_PKEY_new();
+    EVP_PKEY_assign_RSA(public_key, rsaPubkey->release());
+
+    if (!X509_set_pubkey(x509.get(), public_key)) {
+        return Error() << "Unable to set x509 public key";
+    }
+
+    X509_NAME* name = X509_get_subject_name(x509.get());
+    if (!name) {
+        return Error() << "Unable to get x509 subject name";
+    }
+    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>("US"), -1, -1, 0);
+    X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>("Android"), -1, -1, 0);
+    X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>("ODS"), -1, -1, 0);
+    if (!X509_set_issuer_name(x509.get(), name)) {
+        return Error() << "Unable to set x509 issuer name";
+    }
+
+    add_ext(x509.get(), NID_basic_constraints, kBasicConstraints);
+    add_ext(x509.get(), NID_key_usage, kKeyUsage);
+    add_ext(x509.get(), NID_subject_key_identifier, kSubjectKeyIdentifier);
+    add_ext(x509.get(), NID_authority_key_identifier, "keyid:always");
+
+    X509_ALGOR_set0(x509->cert_info->signature, OBJ_nid2obj(NID_sha256WithRSAEncryption),
+                    V_ASN1_NULL, NULL);
+    X509_ALGOR_set0(x509->sig_alg, OBJ_nid2obj(NID_sha256WithRSAEncryption), V_ASN1_NULL, NULL);
+
+    // Get the data to be signed
+    char* to_be_signed_buf(nullptr);
+    size_t to_be_signed_length = i2d_re_X509_tbs(x509.get(), (unsigned char**)&to_be_signed_buf);
+
+    auto signed_data = signFunction(std::string(to_be_signed_buf, to_be_signed_length));
+    if (!signed_data.ok()) {
+        return signed_data.error();
+    }
+
+    // This is the only part that doesn't use boringssl default functions - we manually copy in the
+    // signature that was provided to us.
+    x509->signature->data = (unsigned char*)OPENSSL_malloc(signed_data->size());
+    memcpy(x509->signature->data, signed_data->c_str(), signed_data->size());
+    x509->signature->length = signed_data->size();
+
+    x509->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+    x509->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    auto f = fopen(path.c_str(), "wbe");
+    if (f == nullptr) {
+        return Error() << "Failed to open " << path;
+    }
+    i2d_X509_fp(f, x509.get());
+    fclose(f);
+
+    EVP_PKEY_free(public_key);
+    return {};
+}
+
+Result<std::vector<uint8_t>> extractPublicKey(EVP_PKEY* pkey) {
+    if (pkey == nullptr) {
+        return Error() << "Failed to extract public key from x509 cert";
+    }
+
+    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
+        return Error() << "The public key is not an RSA key";
+    }
+
+    RSA* rsa = EVP_PKEY_get1_RSA(pkey);
+    auto num_bytes = BN_num_bytes(rsa->n);
+    std::vector<uint8_t> pubKey(num_bytes);
+    int res = BN_bn2bin(rsa->n, pubKey.data());
+    RSA_free(rsa);
+
+    if (!res) {
+        return Error() << "Failed to convert public key to bytes";
+    }
+
+    return pubKey;
+}
+
+Result<std::vector<uint8_t>>
+extractPublicKeyFromSubjectPublicKeyInfo(const std::vector<uint8_t>& keyData) {
+    auto keyDataBytes = keyData.data();
+    EVP_PKEY* public_key = d2i_PUBKEY(nullptr, &keyDataBytes, keyData.size());
+
+    return extractPublicKey(public_key);
+}
+
+Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::vector<uint8_t>& keyData) {
+    auto keyDataBytes = keyData.data();
+    bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &keyDataBytes, keyData.size()));
+    if (decoded_cert.get() == nullptr) {
+        return Error() << "Failed to decode X509 certificate.";
+    }
+    bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
+
+    return extractPublicKey(decoded_pkey.get());
+}
+
+Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::string& path) {
+    X509* cert;
+    auto f = fopen(path.c_str(), "re");
+    if (f == nullptr) {
+        return Error() << "Failed to open " << path;
+    }
+    if (!d2i_X509_fp(f, &cert)) {
+        fclose(f);
+        return Error() << "Unable to decode x509 cert at " << path;
+    }
+
+    fclose(f);
+    return extractPublicKey(X509_get_pubkey(cert));
+}
+
+Result<std::vector<uint8_t>> createPkcs7(const std::vector<uint8_t>& signed_digest) {
+    CBB out, outer_seq, wrapped_seq, seq, digest_algos_set, digest_algo, null;
+    CBB content_info, issuer_and_serial, signer_infos, signer_info, sign_algo, signature;
+    uint8_t *pkcs7_data, *name_der;
+    size_t pkcs7_data_len, name_der_len;
+    BIGNUM* serial = BN_new();
+    int sig_nid = NID_rsaEncryption;
+
+    X509_NAME* name = X509_NAME_new();
+    if (!name) {
+        return Error() << "Unable to get x509 subject name";
+    }
+    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>("US"), -1, -1, 0);
+    X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>("Android"), -1, -1, 0);
+    X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>("ODS"), -1, -1, 0);
+
+    BN_set_word(serial, 1);
+    name_der_len = i2d_X509_NAME(name, &name_der);
+    CBB_init(&out, 1024);
+
+    if (!CBB_add_asn1(&out, &outer_seq, CBS_ASN1_SEQUENCE) ||
+        !OBJ_nid2cbb(&outer_seq, NID_pkcs7_signed) ||
+        !CBB_add_asn1(&outer_seq, &wrapped_seq,
+                      CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
+        // See https://tools.ietf.org/html/rfc2315#section-9.1
+        !CBB_add_asn1(&wrapped_seq, &seq, CBS_ASN1_SEQUENCE) ||
+        !CBB_add_asn1_uint64(&seq, 1 /* version */) ||
+        !CBB_add_asn1(&seq, &digest_algos_set, CBS_ASN1_SET) ||
+        !CBB_add_asn1(&digest_algos_set, &digest_algo, CBS_ASN1_SEQUENCE) ||
+        !OBJ_nid2cbb(&digest_algo, NID_sha256) ||
+        !CBB_add_asn1(&digest_algo, &null, CBS_ASN1_NULL) ||
+        !CBB_add_asn1(&seq, &content_info, CBS_ASN1_SEQUENCE) ||
+        !OBJ_nid2cbb(&content_info, NID_pkcs7_data) ||
+        !CBB_add_asn1(&seq, &signer_infos, CBS_ASN1_SET) ||
+        !CBB_add_asn1(&signer_infos, &signer_info, CBS_ASN1_SEQUENCE) ||
+        !CBB_add_asn1_uint64(&signer_info, 1 /* version */) ||
+        !CBB_add_asn1(&signer_info, &issuer_and_serial, CBS_ASN1_SEQUENCE) ||
+        !CBB_add_bytes(&issuer_and_serial, name_der, name_der_len) ||
+        !BN_marshal_asn1(&issuer_and_serial, serial) ||
+        !CBB_add_asn1(&signer_info, &digest_algo, CBS_ASN1_SEQUENCE) ||
+        !OBJ_nid2cbb(&digest_algo, NID_sha256) ||
+        !CBB_add_asn1(&digest_algo, &null, CBS_ASN1_NULL) ||
+        !CBB_add_asn1(&signer_info, &sign_algo, CBS_ASN1_SEQUENCE) ||
+        !OBJ_nid2cbb(&sign_algo, sig_nid) || !CBB_add_asn1(&sign_algo, &null, CBS_ASN1_NULL) ||
+        !CBB_add_asn1(&signer_info, &signature, CBS_ASN1_OCTETSTRING) ||
+        !CBB_add_bytes(&signature, signed_digest.data(), signed_digest.size()) ||
+        !CBB_finish(&out, &pkcs7_data, &pkcs7_data_len)) {
+        return Error() << "Failed to create PKCS7 certificate.";
+    }
+
+    return std::vector<uint8_t>(&pkcs7_data[0], &pkcs7_data[pkcs7_data_len]);
+}
diff --git a/ondevice-signing/CertUtils.h b/ondevice-signing/CertUtils.h
new file mode 100644
index 0000000..66dff04
--- /dev/null
+++ b/ondevice-signing/CertUtils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <android-base/result.h>
+
+android::base::Result<void> createSelfSignedCertificate(
+    const std::vector<uint8_t>& publicKey,
+    const std::function<android::base::Result<std::string>(const std::string&)>& signFunction,
+    const std::string& path);
+android::base::Result<std::vector<uint8_t>> createPkcs7(const std::vector<uint8_t>& signedData);
+
+android::base::Result<std::vector<uint8_t>>
+extractPublicKeyFromX509(const std::vector<uint8_t>& x509);
+android::base::Result<std::vector<uint8_t>>
+extractPublicKeyFromSubjectPublicKeyInfo(const std::vector<uint8_t>& subjectKeyInfo);
+android::base::Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::string& path);
+
+android::base::Result<void> verifySignature(const std::string& message,
+                                            const std::string& signature,
+                                            const std::vector<uint8_t>& publicKey);
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/ondevice-signing/KeyConstants.h
similarity index 76%
copy from keystore/binder/android/security/keymaster/OperationResult.aidl
copy to ondevice-signing/KeyConstants.h
index db689d4..9e1a513 100644
--- a/keystore/binder/android/security/keymaster/OperationResult.aidl
+++ b/ondevice-signing/KeyConstants.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-package android.security.keymaster;
-
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
+static constexpr int kRsaKeySize = 2048;
+static constexpr int kRsaKeyExponent = 65537;
diff --git a/ondevice-signing/Keymaster.cpp b/ondevice-signing/Keymaster.cpp
new file mode 100644
index 0000000..f9bf9b2
--- /dev/null
+++ b/ondevice-signing/Keymaster.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2020 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 <string>
+
+#include <android-base/logging.h>
+#include <keymasterV4_1/Keymaster.h>
+#include <keymasterV4_1/authorization_set.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "Keymaster.h"
+
+using AuthorizationSet = ::android::hardware::keymaster::V4_0::AuthorizationSet;
+using AuthorizationSetBuilder = ::android::hardware::keymaster::V4_0::AuthorizationSetBuilder;
+using Digest = ::android::hardware::keymaster::V4_0::Digest;
+using ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode;
+using HardwareAuthToken = ::android::hardware::keymaster::V4_0::HardwareAuthToken;
+using HidlBuf = ::android::hardware::hidl_vec<uint8_t>;
+using KeyCharacteristics = ::android::hardware::keymaster::V4_0::KeyCharacteristics;
+using KeyFormat = ::android::hardware::keymaster::V4_0::KeyFormat;
+using KeyParameter = ::android::hardware::keymaster::V4_0::KeyParameter;
+using KeyPurpose = ::android::hardware::keymaster::V4_0::KeyPurpose;
+using KmSupport = ::android::hardware::keymaster::V4_1::support::Keymaster;
+using KmDevice = ::android::hardware::keymaster::V4_1::IKeymasterDevice;
+using OperationHandle = ::android::hardware::keymaster::V4_0::OperationHandle;
+using PaddingMode = ::android::hardware::keymaster::V4_0::PaddingMode;
+using VerificationToken = ::android::hardware::keymaster::V4_0::VerificationToken;
+
+using android::sp;
+using android::base::Error;
+using android::base::Result;
+using android::hardware::hidl_vec;
+
+Keymaster::Keymaster() {}
+
+bool Keymaster::initialize() {
+    // TODO(b/165630556): Stop using Keymaster directly and migrate to keystore2
+    // (once available).
+    auto devices = KmSupport::enumerateAvailableDevices();
+    sp<KmDevice> devToUse = nullptr;
+    for (const auto& dev : devices) {
+        auto version = dev->halVersion();
+        if (version.majorVersion > 4 || (version.majorVersion == 4 && version.minorVersion >= 1)) {
+            // TODO we probably have a preference for the SE, hoping Keystore2 will provide this
+            LOG(INFO) << "Using keymaster " << version.keymasterName << " "
+                      << (int)version.majorVersion << "." << (int)version.minorVersion;
+            devToUse = dev;
+            break;
+        }
+    }
+
+    if (devToUse == nullptr) {
+        LOG(WARNING) << "Didn't find a keymaster to use.";
+    }
+    mDevice = devToUse;
+
+    return mDevice != nullptr;
+}
+
+std::optional<Keymaster> Keymaster::getInstance() {
+    static Keymaster keymaster;
+
+    if (!keymaster.initialize()) {
+        return {};
+    } else {
+        return {keymaster};
+    }
+}
+
+Result<std::vector<uint8_t>> Keymaster::createKey() const {
+    ErrorCode error;
+    HidlBuf keyBlob;
+
+    auto params = AuthorizationSetBuilder()
+                      .Authorization(::android::hardware::keymaster::V4_0::TAG_NO_AUTH_REQUIRED)
+                      // TODO MAKE SURE WE ADD THE EARLY_BOOT_ONLY FLAG here
+                      // currently doesn't work on cuttlefish (b/173618442)
+                      //.Authorization(::android::hardware::keymaster::V4_1::TAG_EARLY_BOOT_ONLY)
+                      .RsaSigningKey(2048, 65537)
+                      .Digest(Digest::SHA_2_256)
+                      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
+
+    mDevice->generateKey(params.hidl_data(), [&](ErrorCode hidl_error, const HidlBuf& hidl_key_blob,
+                                                 const KeyCharacteristics&
+                                                 /* hidl_key_characteristics */) {
+        error = hidl_error;
+        keyBlob = hidl_key_blob;
+    });
+
+    if (error != ErrorCode::OK) {
+        return Error() << "Error creating keymaster signing key: "
+                       << static_cast<std::underlying_type<ErrorCode>::type>(error);
+    }
+
+    return keyBlob;
+}
+
+static ErrorCode Begin(const sp<KmDevice>& keymaster_, KeyPurpose purpose, const HidlBuf& key_blob,
+                       const AuthorizationSet& in_params, AuthorizationSet* out_params,
+                       OperationHandle* op_handle) {
+    ErrorCode error;
+    OperationHandle saved_handle = *op_handle;
+    CHECK(keymaster_
+              ->begin(purpose, key_blob, in_params.hidl_data(), HardwareAuthToken(),
+                      [&](ErrorCode hidl_error, const hidl_vec<KeyParameter>& hidl_out_params,
+                          uint64_t hidl_op_handle) {
+                          error = hidl_error;
+                          *out_params = hidl_out_params;
+                          *op_handle = hidl_op_handle;
+                      })
+              .isOk());
+    if (error != ErrorCode::OK) {
+        // Some implementations may modify *op_handle on error.
+        *op_handle = saved_handle;
+    }
+    return error;
+}
+
+static ErrorCode Update(const sp<KmDevice>& keymaster_, OperationHandle op_handle,
+                        const AuthorizationSet& in_params, const std::string& input,
+                        AuthorizationSet* out_params, std::string* output, size_t* input_consumed) {
+    ErrorCode error;
+    HidlBuf inputData(input.size());
+    memcpy(inputData.data(), input.c_str(), input.size());
+    CHECK(keymaster_
+              ->update(op_handle, in_params.hidl_data(), inputData, HardwareAuthToken(),
+                       VerificationToken(),
+                       [&](ErrorCode hidl_error, uint32_t hidl_input_consumed,
+                           const hidl_vec<KeyParameter>& hidl_out_params,
+                           const HidlBuf& hidl_output) {
+                           error = hidl_error;
+                           out_params->push_back(AuthorizationSet(hidl_out_params));
+                           std::string retdata(reinterpret_cast<const char*>(hidl_output.data()),
+                                               hidl_output.size());
+                           output->append(retdata);
+                           *input_consumed = hidl_input_consumed;
+                       })
+              .isOk());
+    return error;
+}
+
+static ErrorCode Finish(const sp<KmDevice>& keymaster_, OperationHandle op_handle,
+                        const AuthorizationSet& in_params, const std::string& input,
+                        const std::string& signature, AuthorizationSet* out_params,
+                        std::string* output) {
+    ErrorCode error;
+    HidlBuf inputData(input.size());
+    memcpy(inputData.data(), input.c_str(), input.size());
+    HidlBuf signatureData(signature.size());
+    memcpy(signatureData.data(), signature.c_str(), signature.size());
+    // TODO still need to handle error -62 - key requires upgrade
+    CHECK(keymaster_
+              ->finish(op_handle, in_params.hidl_data(), inputData, signatureData,
+                       HardwareAuthToken(), VerificationToken(),
+                       [&](ErrorCode hidl_error, const hidl_vec<KeyParameter>& hidl_out_params,
+                           const HidlBuf& hidl_output) {
+                           error = hidl_error;
+                           *out_params = hidl_out_params;
+                           std::string retdata(reinterpret_cast<const char*>(hidl_output.data()),
+                                               hidl_output.size());
+                           output->append(retdata);
+                       })
+              .isOk());
+    return error;
+}
+
+static std::string ProcessMessage(const sp<KmDevice>& keymaster_, const HidlBuf& key_blob,
+                                  KeyPurpose operation, const std::string& message,
+                                  const AuthorizationSet& in_params, AuthorizationSet* out_params) {
+    AuthorizationSet begin_out_params;
+    OperationHandle op_handle_;
+    ErrorCode ec =
+        Begin(keymaster_, operation, key_blob, in_params, &begin_out_params, &op_handle_);
+
+    std::string output;
+    size_t consumed = 0;
+    AuthorizationSet update_params;
+    AuthorizationSet update_out_params;
+    ec = Update(keymaster_, op_handle_, update_params, message, &update_out_params, &output,
+                &consumed);
+
+    std::string unused;
+    AuthorizationSet finish_params;
+    AuthorizationSet finish_out_params;
+    ec = Finish(keymaster_, op_handle_, finish_params, message.substr(consumed), unused,
+                &finish_out_params, &output);
+
+    out_params->push_back(begin_out_params);
+    out_params->push_back(finish_out_params);
+    return output;
+}
+
+Result<std::vector<uint8_t>>
+Keymaster::extractPublicKey(const std::vector<uint8_t>& keyBlob) const {
+    std::vector<uint8_t> publicKey;
+    ErrorCode error;
+
+    mDevice->exportKey(KeyFormat::X509, keyBlob, {} /* clientId */, {} /* appData */,
+                       [&](ErrorCode hidl_error, const HidlBuf& keyData) {
+                           error = hidl_error;
+                           publicKey = keyData;
+                       });
+
+    if (error != ErrorCode::OK) {
+        return Error() << "Error extracting public key: "
+                       << static_cast<std::underlying_type<ErrorCode>::type>(error);
+    }
+
+    return publicKey;
+}
+
+Result<KeymasterVerifyResult> Keymaster::verifyKey(const std::vector<uint8_t>& keyBlob) const {
+    ErrorCode error;
+    KeyCharacteristics characteristics;
+
+    mDevice->getKeyCharacteristics(
+        keyBlob, {} /* clientId */, {} /* appData */,
+        [&](ErrorCode hidl_error, const KeyCharacteristics& hidl_characteristics) {
+            error = hidl_error;
+            characteristics = hidl_characteristics;
+        });
+
+    if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
+        return KeymasterVerifyResult::UPGRADE;
+    }
+
+    if (error != ErrorCode::OK) {
+        return Error() << "Error getting key characteristics: "
+                       << static_cast<std::underlying_type<ErrorCode>::type>(error);
+    }
+
+    // TODO(b/165630556)
+    // Verify this is an early boot key and the other key parameters
+    return KeymasterVerifyResult::OK;
+}
+
+Result<std::vector<uint8_t>> Keymaster::upgradeKey(const std::vector<uint8_t>& keyBlob) const {
+    ErrorCode error;
+    HidlBuf newKeyBlob;
+
+    // TODO deduplicate
+    auto params = AuthorizationSetBuilder()
+                      .Authorization(::android::hardware::keymaster::V4_0::TAG_NO_AUTH_REQUIRED)
+                      // TODO MAKE SURE WE ADD THE EARLY_BOOT_ONLY FLAG here
+                      // currently doesn't work on cuttlefish (b/173618442)
+                      //.Authorization(::android::hardware::keymaster::V4_1::TAG_EARLY_BOOT_ONLY)
+                      .RsaSigningKey(2048, 65537)
+                      .Digest(Digest::SHA_2_256)
+                      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
+
+    mDevice->upgradeKey(keyBlob, params.hidl_data(),
+                        [&](ErrorCode hidl_error, const HidlBuf& hidl_key_blob) {
+                            error = hidl_error;
+                            newKeyBlob = hidl_key_blob;
+                        });
+
+    if (error != ErrorCode::OK) {
+        return Error() << "Error upgrading keymaster signing key: "
+                       << static_cast<std::underlying_type<ErrorCode>::type>(error);
+    }
+
+    return newKeyBlob;
+}
+
+Result<std::string> Keymaster::sign(const std::vector<uint8_t>& keyBlob,
+                                    const std::string& message) const {
+    AuthorizationSet out_params;
+    auto params = AuthorizationSetBuilder()
+                      .Digest(Digest::SHA_2_256)
+                      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
+    std::string signature =
+        ProcessMessage(mDevice, keyBlob, KeyPurpose::SIGN, message, params, &out_params);
+    if (!out_params.empty()) {
+        return Error() << "Error signing key: expected empty out params.";
+    }
+    return signature;
+}
diff --git a/ondevice-signing/Keymaster.h b/ondevice-signing/Keymaster.h
new file mode 100644
index 0000000..455289f
--- /dev/null
+++ b/ondevice-signing/Keymaster.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <optional>
+
+#include <android-base/macros.h>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+
+#include <keymasterV4_1/Keymaster.h>
+
+#include <utils/StrongPointer.h>
+
+enum class KeymasterVerifyResult {
+    OK = 0,
+    UPGRADE = -1,
+};
+
+class Keymaster {
+    using KmDevice = ::android::hardware::keymaster::V4_1::IKeymasterDevice;
+
+  public:
+    static std::optional<Keymaster> getInstance();
+
+    android::base::Result<std::vector<uint8_t>> createKey() const;
+
+    android::base::Result<std::vector<uint8_t>>
+    extractPublicKey(const std::vector<uint8_t>& keyBlob) const;
+
+    android::base::Result<KeymasterVerifyResult>
+    verifyKey(const std::vector<uint8_t>& keyBlob) const;
+
+    android::base::Result<std::vector<uint8_t>>
+    upgradeKey(const std::vector<uint8_t>& keyBlob) const;
+
+    /* Sign a message with an initialized signing key */
+    android::base::Result<std::string> sign(const std::vector<uint8_t>& keyBlob,
+                                            const std::string& message) const;
+
+  private:
+    Keymaster();
+    bool initialize();
+
+    android::sp<KmDevice> mDevice;
+};
diff --git a/ondevice-signing/KeymasterSigningKey.cpp b/ondevice-signing/KeymasterSigningKey.cpp
new file mode 100644
index 0000000..dc3ef8a
--- /dev/null
+++ b/ondevice-signing/KeymasterSigningKey.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2020 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 <string>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "CertUtils.h"
+#include "Keymaster.h"
+#include "KeymasterSigningKey.h"
+
+using android::base::ErrnoError;
+using android::base::Error;
+using android::base::ReadFileToString;
+using android::base::Result;
+using android::base::unique_fd;
+
+const std::string kSigningKeyBlob = "/data/misc/odsign/key.blob";
+
+KeymasterSigningKey::KeymasterSigningKey() {}
+
+Result<std::unique_ptr<KeymasterSigningKey>>
+KeymasterSigningKey::loadFromBlobAndVerify(const std::string& path) {
+    auto signingKey = std::make_unique<KeymasterSigningKey>();
+
+    auto status = signingKey->initializeFromKeyblob(path);
+
+    if (!status.ok()) {
+        return status.error();
+    }
+
+    return signingKey;
+}
+
+Result<void> KeymasterSigningKey::saveKeyblob(const std::string& path) const {
+    int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
+
+    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), flags, 0600)));
+    if (fd == -1) {
+        return ErrnoError() << "Error creating key blob file " << path;
+    }
+
+    if (!android::base::WriteFully(fd, mVerifiedKeyBlob.data(), mVerifiedKeyBlob.size())) {
+        return ErrnoError() << "Error writing key blob file " << path;
+    } else {
+        return {};
+    }
+}
+
+Result<void> KeymasterSigningKey::createSigningKey() {
+    KeymasterSigningKey signingKey;
+    auto keymaster = Keymaster::getInstance();
+    if (!keymaster.has_value()) {
+        return Error() << "Failed to initialize keymaster.";
+    }
+    mKeymaster = keymaster;
+
+    auto keyBlob = mKeymaster->createKey();
+
+    if (!keyBlob.ok()) {
+        return keyBlob.error();
+    }
+
+    mVerifiedKeyBlob.assign(keyBlob->begin(), keyBlob->end());
+
+    return {};
+}
+
+Result<std::unique_ptr<KeymasterSigningKey>> KeymasterSigningKey::createAndPersistNewKey() {
+    auto signingKey = std::make_unique<KeymasterSigningKey>();
+
+    auto status = signingKey->createSigningKey();
+
+    if (!status.ok()) {
+        return status.error();
+    }
+
+    status = signingKey->saveKeyblob(kSigningKeyBlob);
+    if (!status.ok()) {
+        return status.error();
+    }
+
+    return signingKey;
+}
+
+Result<SigningKey*> KeymasterSigningKey::getInstance() {
+    auto key = loadFromBlobAndVerify(kSigningKeyBlob);
+
+    if (!key.ok()) {
+        key = createAndPersistNewKey();
+        if (!key.ok()) {
+            return key.error();
+        }
+    }
+
+    return key->release();
+}
+
+Result<std::vector<uint8_t>> KeymasterSigningKey::getPublicKey() const {
+    auto publicKey = mKeymaster->extractPublicKey(mVerifiedKeyBlob);
+    if (!publicKey.ok()) {
+        return publicKey.error();
+    }
+
+    // Keymaster returns the public key not in a full X509 cert, but just the
+    // "SubjectPublicKeyInfo"
+    return extractPublicKeyFromSubjectPublicKeyInfo(publicKey.value());
+}
+
+Result<void> KeymasterSigningKey::initializeFromKeyblob(const std::string& path) {
+    std::string keyBlobData;
+    auto keymaster = Keymaster::getInstance();
+    if (!keymaster.has_value()) {
+        return Error() << "Failed to initialize keymaster.";
+    }
+    mKeymaster = keymaster;
+
+    bool result = ReadFileToString(path, &keyBlobData);
+    if (!result) {
+        return ErrnoError() << "Failed to read " << path;
+    }
+
+    std::vector<uint8_t> keyBlob = {keyBlobData.begin(), keyBlobData.end()};
+
+    auto verifyResult = mKeymaster->verifyKey(keyBlob);
+    if (!verifyResult.ok()) {
+        return Error() << "Failed to verify key: " << verifyResult.error().message();
+    }
+
+    if (*verifyResult == KeymasterVerifyResult::UPGRADE) {
+        auto upgradeResult = mKeymaster->upgradeKey(keyBlob);
+        if (!upgradeResult.ok()) {
+            return Error() << "Failed to upgrade key: " << upgradeResult.error().message();
+        }
+        mVerifiedKeyBlob = *upgradeResult;
+        // Make sure we persist the new blob
+        auto saveResult = saveKeyblob(path);
+        if (!saveResult.ok()) {
+            return Error() << "Failed to store upgraded key";
+        }
+    } else {
+        mVerifiedKeyBlob = keyBlob;
+    }
+
+    return {};
+}
+
+Result<std::string> KeymasterSigningKey::sign(const std::string& message) const {
+    return mKeymaster->sign(mVerifiedKeyBlob, message);
+}
diff --git a/ondevice-signing/KeymasterSigningKey.h b/ondevice-signing/KeymasterSigningKey.h
new file mode 100644
index 0000000..e66781f
--- /dev/null
+++ b/ondevice-signing/KeymasterSigningKey.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+
+#include <utils/StrongPointer.h>
+
+#include "Keymaster.h"
+#include "SigningKey.h"
+
+class KeymasterSigningKey : public SigningKey {
+    using KmDevice = ::android::hardware::keymaster::V4_1::IKeymasterDevice;
+
+  public:
+    friend std::unique_ptr<KeymasterSigningKey> std::make_unique<KeymasterSigningKey>();
+    virtual ~KeymasterSigningKey(){};
+
+    // Allow the key to be moved around
+    KeymasterSigningKey& operator=(KeymasterSigningKey&& other) = default;
+    KeymasterSigningKey(KeymasterSigningKey&& other) = default;
+
+    static android::base::Result<SigningKey*> getInstance();
+
+    virtual android::base::Result<std::string> sign(const std::string& message) const;
+    virtual android::base::Result<std::vector<uint8_t>> getPublicKey() const;
+
+  private:
+    KeymasterSigningKey();
+
+    static android::base::Result<std::unique_ptr<KeymasterSigningKey>> createAndPersistNewKey();
+    static android::base::Result<std::unique_ptr<KeymasterSigningKey>>
+    loadFromBlobAndVerify(const std::string& path);
+
+    android::base::Result<void> createSigningKey();
+    android::base::Result<void> initializeFromKeyblob(const std::string& path);
+    android::base::Result<void> saveKeyblob(const std::string& path) const;
+
+    static android::base::Result<KeymasterSigningKey> createNewKey();
+
+    std::optional<Keymaster> mKeymaster;
+    std::vector<uint8_t> mVerifiedKeyBlob;
+
+    DISALLOW_COPY_AND_ASSIGN(KeymasterSigningKey);
+};
diff --git a/ondevice-signing/KeystoreKey.cpp b/ondevice-signing/KeystoreKey.cpp
new file mode 100644
index 0000000..4e59c58
--- /dev/null
+++ b/ondevice-signing/KeystoreKey.cpp
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2021 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 <string>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <binder/IServiceManager.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "CertUtils.h"
+#include "KeyConstants.h"
+#include "KeystoreKey.h"
+
+using android::defaultServiceManager;
+using android::IServiceManager;
+using android::sp;
+using android::String16;
+
+using android::hardware::security::keymint::Algorithm;
+using android::hardware::security::keymint::Digest;
+using android::hardware::security::keymint::KeyParameter;
+using android::hardware::security::keymint::KeyParameterValue;
+using android::hardware::security::keymint::KeyPurpose;
+using android::hardware::security::keymint::PaddingMode;
+using android::hardware::security::keymint::SecurityLevel;
+using android::hardware::security::keymint::Tag;
+
+using android::system::keystore2::CreateOperationResponse;
+using android::system::keystore2::Domain;
+using android::system::keystore2::KeyDescriptor;
+using android::system::keystore2::KeyEntryResponse;
+using android::system::keystore2::KeyMetadata;
+
+using android::base::Error;
+using android::base::Result;
+
+// Keystore boot level that the odsign key uses
+static const int kOdsignBootLevel = 30;
+
+static KeyDescriptor getKeyDescriptor() {
+    // AIDL parcelable objects don't have constructor
+    static KeyDescriptor descriptor;
+    static std::once_flag flag;
+    std::call_once(flag, [&]() {
+        descriptor.domain = Domain::SELINUX;
+        descriptor.alias = String16("ondevice-signing");
+        descriptor.nspace = 101;  // odsign_key
+    });
+
+    return descriptor;
+}
+
+KeystoreKey::KeystoreKey() {}
+
+Result<KeyMetadata> KeystoreKey::createNewKey(const KeyDescriptor& descriptor) {
+    std::vector<KeyParameter> params;
+
+    KeyParameter algo;
+    algo.tag = Tag::ALGORITHM;
+    algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::RSA);
+    params.push_back(algo);
+
+    KeyParameter key_size;
+    key_size.tag = Tag::KEY_SIZE;
+    key_size.value = KeyParameterValue::make<KeyParameterValue::integer>(kRsaKeySize);
+    params.push_back(key_size);
+
+    KeyParameter digest;
+    digest.tag = Tag::DIGEST;
+    digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
+    params.push_back(digest);
+
+    KeyParameter padding;
+    padding.tag = Tag::PADDING;
+    padding.value =
+        KeyParameterValue::make<KeyParameterValue::paddingMode>(PaddingMode::RSA_PKCS1_1_5_SIGN);
+    params.push_back(padding);
+
+    KeyParameter exponent;
+    exponent.tag = Tag::RSA_PUBLIC_EXPONENT;
+    exponent.value = KeyParameterValue::make<KeyParameterValue::longInteger>(kRsaKeyExponent);
+    params.push_back(exponent);
+
+    KeyParameter purpose;
+    purpose.tag = Tag::PURPOSE;
+    purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
+    params.push_back(purpose);
+
+    KeyParameter auth;
+    auth.tag = Tag::NO_AUTH_REQUIRED;
+    auth.value = KeyParameterValue::make<KeyParameterValue::boolValue>(true);
+    params.push_back(auth);
+
+    KeyParameter boot_level;
+    boot_level.tag = Tag::MAX_BOOT_LEVEL;
+    boot_level.value = KeyParameterValue::make<KeyParameterValue::integer>(kOdsignBootLevel);
+    params.push_back(boot_level);
+
+    KeyMetadata metadata;
+    auto status = mSecurityLevel->generateKey(descriptor, {}, params, 0, {}, &metadata);
+    if (!status.isOk()) {
+        return Error() << "Failed to create new key";
+    }
+
+    return metadata;
+}
+
+bool KeystoreKey::initialize() {
+    sp<IServiceManager> sm = defaultServiceManager();
+    if (sm == nullptr) {
+        return false;
+    }
+    auto service = sm->getService(String16("android.system.keystore2.IKeystoreService/default"));
+    if (service == nullptr) {
+        return false;
+    }
+    mService = interface_cast<android::system::keystore2::IKeystoreService>(service);
+    if (mService == nullptr) {
+        return false;
+    }
+
+    auto status = mService->getSecurityLevel(SecurityLevel::STRONGBOX, &mSecurityLevel);
+    if (!status.isOk()) {
+        status = mService->getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT, &mSecurityLevel);
+        if (!status.isOk()) {
+            return false;
+        }
+    }
+
+    auto descriptor = getKeyDescriptor();
+    // See if we can fetch an existing key
+    KeyEntryResponse keyEntryResponse;
+    LOG(INFO) << "Trying to retrieve existing keystore key...";
+    status = mService->getKeyEntry(descriptor, &keyEntryResponse);
+    bool keyValid = false;
+
+    if (status.isOk()) {
+        // Make sure this is an early boot key
+        for (const auto& auth : keyEntryResponse.metadata.authorizations) {
+            if (auth.keyParameter.tag == Tag::MAX_BOOT_LEVEL) {
+                if (auth.keyParameter.value.get<KeyParameterValue::integer>() == kOdsignBootLevel) {
+                    keyValid = true;
+                    break;
+                }
+            }
+        }
+        if (!keyValid) {
+            LOG(WARNING) << "Found invalid keystore key without MAX_BOOT_LEVEL tag";
+        }
+    }
+
+    if (!keyValid) {
+        LOG(INFO) << "Existing keystore key not found or invalid, creating new key";
+        auto newKeyStatus = createNewKey(descriptor);
+        if (!newKeyStatus.ok()) {
+            LOG(ERROR) << "Failed to create new key";
+            return false;
+        }
+        mKeyMetadata = *newKeyStatus;
+    } else {
+        mKeyMetadata = keyEntryResponse.metadata;
+    }
+
+    LOG(ERROR) << "Initialized Keystore key.";
+    return true;
+}
+
+Result<SigningKey*> KeystoreKey::getInstance() {
+    static KeystoreKey keystoreKey;
+
+    if (!keystoreKey.initialize()) {
+        return Error() << "Failed to initialize keystore key.";
+    } else {
+        return &keystoreKey;
+    }
+}
+
+static std::vector<KeyParameter> getSignOpParameters() {
+    std::vector<KeyParameter> opParameters;
+
+    KeyParameter algo;
+    algo.tag = Tag::ALGORITHM;
+    algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::RSA);
+    opParameters.push_back(algo);
+
+    KeyParameter digest;
+    digest.tag = Tag::DIGEST;
+    digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
+    opParameters.push_back(digest);
+
+    KeyParameter padding;
+    padding.tag = Tag::PADDING;
+    padding.value =
+        KeyParameterValue::make<KeyParameterValue::paddingMode>(PaddingMode::RSA_PKCS1_1_5_SIGN);
+    opParameters.push_back(padding);
+
+    KeyParameter purpose;
+    purpose.tag = Tag::PURPOSE;
+    purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
+    opParameters.push_back(purpose);
+
+    return opParameters;
+}
+
+Result<std::string> KeystoreKey::sign(const std::string& message) const {
+    static auto opParameters = getSignOpParameters();
+
+    CreateOperationResponse opResponse;
+
+    auto status =
+        mSecurityLevel->createOperation(getKeyDescriptor(), opParameters, false, &opResponse);
+    if (!status.isOk()) {
+        return Error() << "Failed to create keystore signing operation: "
+                       << status.serviceSpecificErrorCode();
+    }
+    auto operation = opResponse.iOperation;
+
+    std::optional<std::vector<uint8_t>> out;
+    status = operation->update({message.begin(), message.end()}, &out);
+    if (!status.isOk()) {
+        return Error() << "Failed to call keystore update operation.";
+    }
+
+    std::optional<std::vector<uint8_t>> signature;
+    status = operation->finish({}, {}, &signature);
+    if (!status.isOk()) {
+        return Error() << "Failed to call keystore finish operation.";
+    }
+
+    if (!signature.has_value()) {
+        return Error() << "Didn't receive a signature from keystore finish operation.";
+    }
+
+    std::string result{signature.value().begin(), signature.value().end()};
+
+    return result;
+}
+
+Result<std::vector<uint8_t>> KeystoreKey::getPublicKey() const {
+    auto cert = mKeyMetadata.certificate;
+    if (cert) {
+        return extractPublicKeyFromX509(cert.value());
+    } else {
+        return Error() << "Key did not have a certificate";
+    }
+}
diff --git a/ondevice-signing/KeystoreKey.h b/ondevice-signing/KeystoreKey.h
new file mode 100644
index 0000000..6b9cb57
--- /dev/null
+++ b/ondevice-signing/KeystoreKey.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <optional>
+
+#include <android-base/macros.h>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+
+#include <utils/StrongPointer.h>
+
+#include <android/system/keystore2/IKeystoreService.h>
+
+#include "SigningKey.h"
+
+class KeystoreKey : public SigningKey {
+    using IKeystoreService = ::android::system::keystore2::IKeystoreService;
+    using IKeystoreSecurityLevel = ::android::system::keystore2::IKeystoreSecurityLevel;
+    using KeyDescriptor = ::android::system::keystore2::KeyDescriptor;
+    using KeyMetadata = ::android::system::keystore2::KeyMetadata;
+
+  public:
+    virtual ~KeystoreKey(){};
+    static android::base::Result<SigningKey*> getInstance();
+
+    virtual android::base::Result<std::string> sign(const std::string& message) const;
+    virtual android::base::Result<std::vector<uint8_t>> getPublicKey() const;
+
+  private:
+    KeystoreKey();
+    bool initialize();
+    android::base::Result<KeyMetadata> createNewKey(const KeyDescriptor& descriptor);
+
+    android::sp<IKeystoreService> mService;
+    android::sp<IKeystoreSecurityLevel> mSecurityLevel;
+    KeyMetadata mKeyMetadata;
+};
diff --git a/ondevice-signing/OWNERS b/ondevice-signing/OWNERS
new file mode 100644
index 0000000..72a8eb5
--- /dev/null
+++ b/ondevice-signing/OWNERS
@@ -0,0 +1,3 @@
+maco@google.com
+ngeoffray@google.com
+oth@google.com
diff --git a/ondevice-signing/PREUPLOAD.cfg b/ondevice-signing/PREUPLOAD.cfg
new file mode 100644
index 0000000..4c6fbd6
--- /dev/null
+++ b/ondevice-signing/PREUPLOAD.cfg
@@ -0,0 +1,11 @@
+[Hook Scripts]
+checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
+
+[Builtin Hooks]
+clang_format = true
+commit_msg_changeid_field = true
+commit_msg_test_field = true
+gofmt = true
+
+[Builtin Hooks Options]
+clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
\ No newline at end of file
diff --git a/ondevice-signing/SigningKey.h b/ondevice-signing/SigningKey.h
new file mode 100644
index 0000000..89294fc
--- /dev/null
+++ b/ondevice-signing/SigningKey.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+#include <android-base/result.h>
+
+class SigningKey {
+  public:
+    virtual ~SigningKey(){};
+    /* Sign a message with an initialized signing key */
+    virtual android::base::Result<std::string> sign(const std::string& message) const = 0;
+    /* Retrieve the associated public key */
+    virtual android::base::Result<std::vector<uint8_t>> getPublicKey() const = 0;
+};
diff --git a/ondevice-signing/TEST_MAPPING b/ondevice-signing/TEST_MAPPING
new file mode 100644
index 0000000..03b9b95
--- /dev/null
+++ b/ondevice-signing/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "odsign_e2e_tests"
+    }
+  ]
+}
diff --git a/ondevice-signing/VerityUtils.cpp b/ondevice-signing/VerityUtils.cpp
new file mode 100644
index 0000000..cab92e2
--- /dev/null
+++ b/ondevice-signing/VerityUtils.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2020 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 <filesystem>
+#include <map>
+#include <span>
+#include <string>
+
+#include <fcntl.h>
+#include <linux/fs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <libfsverity.h>
+#include <linux/fsverity.h>
+
+#include "CertUtils.h"
+#include "SigningKey.h"
+
+#define FS_VERITY_MAX_DIGEST_SIZE 64
+
+using android::base::ErrnoError;
+using android::base::Error;
+using android::base::Result;
+using android::base::unique_fd;
+
+static const char* kFsVerityInitPath = "/system/bin/fsverity_init";
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define cpu_to_le16(v) ((__force __le16)(uint16_t)(v))
+#define le16_to_cpu(v) ((__force uint16_t)(__le16)(v))
+#else
+#define cpu_to_le16(v) ((__force __le16)__builtin_bswap16(v))
+#define le16_to_cpu(v) (__builtin_bswap16((__force uint16_t)(v)))
+#endif
+
+struct fsverity_signed_digest {
+    char magic[8]; /* must be "FSVerity" */
+    __le16 digest_algorithm;
+    __le16 digest_size;
+    __u8 digest[];
+};
+
+static std::string toHex(std::span<uint8_t> data) {
+    std::stringstream ss;
+    for (auto it = data.begin(); it != data.end(); ++it) {
+        ss << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned>(*it);
+    }
+    return ss.str();
+}
+
+static int read_callback(void* file, void* buf, size_t count) {
+    int* fd = (int*)file;
+    if (TEMP_FAILURE_RETRY(read(*fd, buf, count)) < 0) return errno ? -errno : -EIO;
+    return 0;
+}
+
+Result<std::vector<uint8_t>> createDigest(const std::string& path) {
+    struct stat filestat;
+    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+    if (fd < 0) {
+        return ErrnoError() << "Failed to open " << path;
+    }
+
+    int ret = stat(path.c_str(), &filestat);
+    if (ret < 0) {
+        return ErrnoError() << "Failed to stat " << path;
+    }
+    struct libfsverity_merkle_tree_params params = {
+        .version = 1,
+        .hash_algorithm = FS_VERITY_HASH_ALG_SHA256,
+        .file_size = static_cast<uint64_t>(filestat.st_size),
+        .block_size = 4096,
+    };
+
+    struct libfsverity_digest* digest;
+    ret = libfsverity_compute_digest(&fd, &read_callback, &params, &digest);
+    if (ret < 0) {
+        return ErrnoError() << "Failed to compute fs-verity digest for " << path;
+    }
+    std::vector<uint8_t> digestVector(&digest->digest[0], &digest->digest[32]);
+    free(digest);
+    return digestVector;
+}
+
+namespace {
+template <typename T> struct DeleteAsPODArray {
+    void operator()(T* x) {
+        if (x) {
+            x->~T();
+            delete[](uint8_t*) x;
+        }
+    }
+};
+}  // namespace
+
+template <typename T> using trailing_unique_ptr = std::unique_ptr<T, DeleteAsPODArray<T>>;
+
+template <typename T>
+static trailing_unique_ptr<T> makeUniqueWithTrailingData(size_t trailing_data_size) {
+    uint8_t* memory = new uint8_t[sizeof(T*) + trailing_data_size];
+    T* ptr = new (memory) T;
+    return trailing_unique_ptr<T>{ptr};
+}
+
+static Result<std::vector<uint8_t>> signDigest(const SigningKey& key,
+                                               const std::vector<uint8_t>& digest) {
+    auto d = makeUniqueWithTrailingData<fsverity_signed_digest>(digest.size());
+
+    memcpy(d->magic, "FSVerity", 8);
+    d->digest_algorithm = cpu_to_le16(FS_VERITY_HASH_ALG_SHA256);
+    d->digest_size = cpu_to_le16(digest.size());
+    memcpy(d->digest, digest.data(), digest.size());
+
+    auto signed_digest = key.sign(std::string((char*)d.get(), sizeof(*d) + digest.size()));
+    if (!signed_digest.ok()) {
+        return signed_digest.error();
+    }
+
+    return std::vector<uint8_t>(signed_digest->begin(), signed_digest->end());
+}
+
+Result<std::string> enableFsVerity(const std::string& path, const SigningKey& key) {
+    auto digest = createDigest(path);
+    if (!digest.ok()) {
+        return digest.error();
+    }
+
+    auto signed_digest = signDigest(key, digest.value());
+    if (!signed_digest.ok()) {
+        return signed_digest.error();
+    }
+
+    auto pkcs7_data = createPkcs7(signed_digest.value());
+
+    struct fsverity_enable_arg arg = {.version = 1};
+
+    arg.sig_ptr = (uint64_t)pkcs7_data->data();
+    arg.sig_size = pkcs7_data->size();
+    arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;
+    arg.block_size = 4096;
+
+    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+    int ret = ioctl(fd, FS_IOC_ENABLE_VERITY, &arg);
+
+    if (ret != 0) {
+        return ErrnoError() << "Failed to call FS_IOC_ENABLE_VERITY on " << path;
+    }
+
+    // Return the root hash as a hex string
+    return toHex(digest.value());
+}
+
+Result<std::map<std::string, std::string>> addFilesToVerityRecursive(const std::string& path,
+                                                                     const SigningKey& key) {
+    std::map<std::string, std::string> digests;
+    std::error_code ec;
+
+    auto it = std::filesystem::recursive_directory_iterator(path, ec);
+    auto end = std::filesystem::recursive_directory_iterator();
+
+    while (!ec && it != end) {
+        if (it->is_regular_file()) {
+            LOG(INFO) << "Adding " << it->path() << " to fs-verity...";
+            auto result = enableFsVerity(it->path(), key);
+            if (!result.ok()) {
+                return result.error();
+            }
+            digests[it->path()] = *result;
+        }
+        ++it;
+    }
+    if (ec) {
+        return Error() << "Failed to iterate " << path << ": " << ec;
+    }
+
+    return digests;
+}
+
+Result<std::string> isFileInVerity(const std::string& path) {
+    unsigned int flags;
+
+    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+    if (fd < 0) {
+        return ErrnoError() << "Failed to open " << path;
+    }
+
+    int ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
+    if (ret < 0) {
+        return ErrnoError() << "Failed to FS_IOC_GETFLAGS for " << path;
+    }
+    if (!(flags & FS_VERITY_FL)) {
+        return Error() << "File is not in fs-verity: " << path;
+    }
+
+    auto d = makeUniqueWithTrailingData<fsverity_digest>(FS_VERITY_MAX_DIGEST_SIZE);
+    d->digest_size = FS_VERITY_MAX_DIGEST_SIZE;
+    ret = ioctl(fd, FS_IOC_MEASURE_VERITY, d.get());
+    if (ret < 0) {
+        return ErrnoError() << "Failed to FS_IOC_MEASURE_VERITY for " << path;
+    }
+    return toHex({&d->digest[0], &d->digest[d->digest_size]});
+}
+
+Result<std::map<std::string, std::string>> verifyAllFilesInVerity(const std::string& path) {
+    std::map<std::string, std::string> digests;
+    std::error_code ec;
+
+    auto it = std::filesystem::recursive_directory_iterator(path, ec);
+    auto end = std::filesystem::recursive_directory_iterator();
+
+    while (!ec && it != end) {
+        if (it->is_regular_file()) {
+            // Verify
+            auto result = isFileInVerity(it->path());
+            if (!result.ok()) {
+                return result.error();
+            }
+            digests[it->path()] = *result;
+        }  // TODO reject other types besides dirs?
+        ++it;
+    }
+    if (ec) {
+        return Error() << "Failed to iterate " << path << ": " << ec;
+    }
+
+    return digests;
+}
+
+Result<void> addCertToFsVerityKeyring(const std::string& path) {
+    const char* const argv[] = {kFsVerityInitPath, "--load-extra-key", "fsv_ods"};
+
+    int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
+    pid_t pid = fork();
+    if (pid == 0) {
+        dup2(fd, STDIN_FILENO);
+        close(fd);
+        int argc = arraysize(argv);
+        char* argv_child[argc + 1];
+        memcpy(argv_child, argv, argc * sizeof(char*));
+        argv_child[argc] = nullptr;
+        execvp(argv_child[0], const_cast<char**>(argv_child));
+        PLOG(ERROR) << "exec in ForkExecvp";
+        _exit(EXIT_FAILURE);
+    } else {
+        close(fd);
+    }
+    if (pid == -1) {
+        return ErrnoError() << "Failed to fork.";
+    }
+    int status;
+    if (waitpid(pid, &status, 0) == -1) {
+        return ErrnoError() << "waitpid() failed.";
+    }
+    if (!WIFEXITED(status)) {
+        return Error() << kFsVerityInitPath << ": abnormal process exit";
+    }
+    if (WEXITSTATUS(status)) {
+        if (status != 0) {
+            return Error() << kFsVerityInitPath << " exited with " << status;
+        }
+    }
+
+    return {};
+}
diff --git a/ondevice-signing/VerityUtils.h b/ondevice-signing/VerityUtils.h
new file mode 100644
index 0000000..84af319
--- /dev/null
+++ b/ondevice-signing/VerityUtils.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <android-base/result.h>
+
+#include "SigningKey.h"
+
+android::base::Result<void> addCertToFsVerityKeyring(const std::string& path);
+android::base::Result<std::vector<uint8_t>> createDigest(const std::string& path);
+android::base::Result<std::map<std::string, std::string>>
+verifyAllFilesInVerity(const std::string& path);
+android::base::Result<std::map<std::string, std::string>>
+addFilesToVerityRecursive(const std::string& path, const SigningKey& key);
diff --git a/ondevice-signing/odsign.rc b/ondevice-signing/odsign.rc
new file mode 100644
index 0000000..044bae7
--- /dev/null
+++ b/ondevice-signing/odsign.rc
@@ -0,0 +1,6 @@
+service odsign /system/bin/odsign
+    class core
+    user root
+    group system
+    oneshot
+    disabled # does not start with the core class
diff --git a/ondevice-signing/odsign_main.cpp b/ondevice-signing/odsign_main.cpp
new file mode 100644
index 0000000..6cab8b6
--- /dev/null
+++ b/ondevice-signing/odsign_main.cpp
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2020 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 <fcntl.h>
+#include <filesystem>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/scopeguard.h>
+#include <logwrap/logwrap.h>
+#include <odrefresh/odrefresh.h>
+
+#include "CertUtils.h"
+#include "KeymasterSigningKey.h"
+#include "KeystoreKey.h"
+#include "VerityUtils.h"
+
+#include "odsign_info.pb.h"
+
+using android::base::ErrnoError;
+using android::base::Error;
+using android::base::Result;
+using android::base::SetProperty;
+
+using OdsignInfo = ::odsign::proto::OdsignInfo;
+
+const std::string kSigningKeyBlob = "/data/misc/odsign/key.blob";
+const std::string kSigningKeyCert = "/data/misc/odsign/key.cert";
+const std::string kOdsignInfo = "/data/misc/odsign/odsign.info";
+const std::string kOdsignInfoSignature = "/data/misc/odsign/odsign.info.signature";
+
+const std::string kArtArtifactsDir = "/data/misc/apexdata/com.android.art/dalvik-cache";
+
+static const char* kOdrefreshPath = "/apex/com.android.art/bin/odrefresh";
+
+static const char* kFsVerityProcPath = "/proc/sys/fs/verity";
+
+static const bool kForceCompilation = false;
+static const bool kUseKeystore = true;
+
+static const char* kOdsignVerificationDoneProp = "odsign.verification.done";
+static const char* kOdsignKeyDoneProp = "odsign.key.done";
+
+static const char* kOdsignVerificationStatusProp = "odsign.verification.success";
+static const char* kOdsignVerificationStatusValid = "1";
+static const char* kOdsignVerificationStatusError = "0";
+
+Result<void> verifyExistingCert(const SigningKey& key) {
+    if (access(kSigningKeyCert.c_str(), F_OK) < 0) {
+        return ErrnoError() << "Key certificate not found: " << kSigningKeyCert;
+    }
+    auto trustedPublicKey = key.getPublicKey();
+    if (!trustedPublicKey.ok()) {
+        return Error() << "Failed to retrieve signing public key.";
+    }
+
+    auto publicKeyFromExistingCert = extractPublicKeyFromX509(kSigningKeyCert);
+    if (!publicKeyFromExistingCert.ok()) {
+        return publicKeyFromExistingCert.error();
+    }
+    if (publicKeyFromExistingCert.value() != trustedPublicKey.value()) {
+        return Error() << "Public key of existing certificate at " << kSigningKeyCert
+                       << " does not match signing public key.";
+    }
+
+    // At this point, we know the cert matches
+    return {};
+}
+
+Result<void> createX509Cert(const SigningKey& key, const std::string& outPath) {
+    auto publicKey = key.getPublicKey();
+
+    if (!publicKey.ok()) {
+        return publicKey.error();
+    }
+
+    auto keymasterSignFunction = [&](const std::string& to_be_signed) {
+        return key.sign(to_be_signed);
+    };
+    createSelfSignedCertificate(*publicKey, keymasterSignFunction, outPath);
+    return {};
+}
+
+art::odrefresh::ExitCode compileArtifacts(bool force) {
+    const char* const argv[] = {kOdrefreshPath, force ? "--force-compile" : "--compile"};
+    const int exit_code =
+        logwrap_fork_execvp(arraysize(argv), argv, nullptr, false, LOG_ALOG, false, nullptr);
+    return static_cast<art::odrefresh::ExitCode>(exit_code);
+}
+
+static std::string toHex(const std::vector<uint8_t>& digest) {
+    std::stringstream ss;
+    for (auto it = digest.begin(); it != digest.end(); ++it) {
+        ss << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned>(*it);
+    }
+    return ss.str();
+}
+
+Result<std::map<std::string, std::string>> computeDigests(const std::string& path) {
+    std::error_code ec;
+    std::map<std::string, std::string> digests;
+
+    auto it = std::filesystem::recursive_directory_iterator(path, ec);
+    auto end = std::filesystem::recursive_directory_iterator();
+
+    while (!ec && it != end) {
+        if (it->is_regular_file()) {
+            auto digest = createDigest(it->path());
+            if (!digest.ok()) {
+                return Error() << "Failed to compute digest for " << it->path();
+            }
+            digests[it->path()] = toHex(*digest);
+        }
+        ++it;
+    }
+    if (ec) {
+        return Error() << "Failed to iterate " << path << ": " << ec;
+    }
+
+    return digests;
+}
+
+Result<void> verifyDigests(const std::map<std::string, std::string>& digests,
+                           const std::map<std::string, std::string>& trusted_digests) {
+    for (const auto& path_digest : digests) {
+        auto path = path_digest.first;
+        auto digest = path_digest.second;
+        if ((trusted_digests.count(path) == 0)) {
+            return Error() << "Couldn't find digest for " << path;
+        }
+        if (trusted_digests.at(path) != digest) {
+            return Error() << "Digest mismatch for " << path;
+        }
+    }
+
+    // All digests matched!
+    if (digests.size() > 0) {
+        LOG(INFO) << "All root hashes match.";
+    }
+    return {};
+}
+
+Result<void> verifyIntegrityFsVerity(const std::map<std::string, std::string>& trusted_digests) {
+    // Just verify that the files are in verity, and get their digests
+    auto result = verifyAllFilesInVerity(kArtArtifactsDir);
+    if (!result.ok()) {
+        return result.error();
+    }
+
+    return verifyDigests(*result, trusted_digests);
+}
+
+Result<void> verifyIntegrityNoFsVerity(const std::map<std::string, std::string>& trusted_digests) {
+    // On these devices, just compute the digests, and verify they match the ones we trust
+    auto result = computeDigests(kArtArtifactsDir);
+    if (!result.ok()) {
+        return result.error();
+    }
+
+    return verifyDigests(*result, trusted_digests);
+}
+
+Result<OdsignInfo> getOdsignInfo(const SigningKey& key) {
+    std::string persistedSignature;
+    OdsignInfo odsignInfo;
+
+    if (!android::base::ReadFileToString(kOdsignInfoSignature, &persistedSignature)) {
+        return ErrnoError() << "Failed to read " << kOdsignInfoSignature;
+    }
+
+    std::fstream odsign_info(kOdsignInfo, std::ios::in | std::ios::binary);
+    if (!odsign_info) {
+        return Error() << "Failed to open " << kOdsignInfo;
+    }
+    odsign_info.seekg(0);
+    // Verify the hash
+    std::string odsign_info_str((std::istreambuf_iterator<char>(odsign_info)),
+                                std::istreambuf_iterator<char>());
+
+    auto publicKey = key.getPublicKey();
+    auto signResult = verifySignature(odsign_info_str, persistedSignature, *publicKey);
+    if (!signResult.ok()) {
+        return Error() << kOdsignInfoSignature << " does not match.";
+    } else {
+        LOG(INFO) << kOdsignInfoSignature << " matches.";
+    }
+
+    odsign_info.seekg(0);
+    if (!odsignInfo.ParseFromIstream(&odsign_info)) {
+        return Error() << "Failed to parse " << kOdsignInfo;
+    }
+
+    LOG(INFO) << "Loaded " << kOdsignInfo;
+    return odsignInfo;
+}
+
+Result<void> persistDigests(const std::map<std::string, std::string>& digests,
+                            const SigningKey& key) {
+    OdsignInfo signInfo;
+    google::protobuf::Map<std::string, std::string> proto_hashes(digests.begin(), digests.end());
+    auto map = signInfo.mutable_file_hashes();
+    *map = proto_hashes;
+
+    std::fstream odsign_info(kOdsignInfo,
+                             std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary);
+    if (!signInfo.SerializeToOstream(&odsign_info)) {
+        return Error() << "Failed to persist root hashes in " << kOdsignInfo;
+    }
+
+    // Sign the signatures with our key itself, and write that to storage
+    odsign_info.seekg(0, std::ios::beg);
+    std::string odsign_info_str((std::istreambuf_iterator<char>(odsign_info)),
+                                std::istreambuf_iterator<char>());
+    auto signResult = key.sign(odsign_info_str);
+    if (!signResult.ok()) {
+        return Error() << "Failed to sign " << kOdsignInfo;
+    }
+    android::base::WriteStringToFile(*signResult, kOdsignInfoSignature);
+    return {};
+}
+
+static int removeArtifacts() {
+    std::error_code ec;
+    auto num_removed = std::filesystem::remove_all(kArtArtifactsDir, ec);
+    if (ec) {
+        LOG(ERROR) << "Can't remove " << kArtArtifactsDir << ": " << ec.message();
+        return 0;
+    } else {
+        if (num_removed > 0) {
+            LOG(INFO) << "Removed " << num_removed << " entries from " << kArtArtifactsDir;
+        }
+        return num_removed;
+    }
+}
+
+static Result<void> verifyArtifacts(const SigningKey& key, bool supportsFsVerity) {
+    auto signInfo = getOdsignInfo(key);
+    // Tell init we're done with the key; this is a boot time optimization
+    // in particular for the no fs-verity case, where we need to do a
+    // costly verification. If the files haven't been tampered with, which
+    // should be the common path, the verification will succeed, and we won't
+    // need the key anymore. If it turns out the artifacts are invalid (eg not
+    // in fs-verity) or the hash doesn't match, we won't be able to generate
+    // new artifacts without the key, so in those cases, remove the artifacts,
+    // and use JIT zygote for the current boot. We should recover automatically
+    // by the next boot.
+    SetProperty(kOdsignKeyDoneProp, "1");
+    if (!signInfo.ok()) {
+        return Error() << signInfo.error().message();
+    }
+    std::map<std::string, std::string> trusted_digests(signInfo->file_hashes().begin(),
+                                                       signInfo->file_hashes().end());
+    Result<void> integrityStatus;
+
+    if (supportsFsVerity) {
+        integrityStatus = verifyIntegrityFsVerity(trusted_digests);
+    } else {
+        integrityStatus = verifyIntegrityNoFsVerity(trusted_digests);
+    }
+    if (!integrityStatus.ok()) {
+        return Error() << integrityStatus.error().message();
+    }
+
+    return {};
+}
+
+int main(int /* argc */, char** /* argv */) {
+    auto errorScopeGuard = []() {
+        // In case we hit any error, remove the artifacts and tell Zygote not to use anything
+        removeArtifacts();
+        // Tell init we don't need to use our key anymore
+        SetProperty(kOdsignKeyDoneProp, "1");
+        // Tell init we're done with verification, and that it was an error
+        SetProperty(kOdsignVerificationDoneProp, "1");
+        SetProperty(kOdsignVerificationStatusProp, kOdsignVerificationStatusError);
+    };
+    auto scope_guard = android::base::make_scope_guard(errorScopeGuard);
+
+    if (!android::base::GetBoolProperty("ro.apex.updatable", false)) {
+        LOG(INFO) << "Device doesn't support updatable APEX, exiting.";
+        return 0;
+    }
+
+    SigningKey* key;
+    if (kUseKeystore) {
+        auto keystoreResult = KeystoreKey::getInstance();
+        if (!keystoreResult.ok()) {
+            LOG(ERROR) << "Could not create keystore key: " << keystoreResult.error().message();
+            return -1;
+        }
+        key = keystoreResult.value();
+    } else {
+        // TODO - keymaster will go away
+        auto keymasterResult = KeymasterSigningKey::getInstance();
+        if (!keymasterResult.ok()) {
+            LOG(ERROR) << "Failed to create keymaster key: " << keymasterResult.error().message();
+            return -1;
+        }
+        key = keymasterResult.value();
+    }
+
+    bool supportsFsVerity = access(kFsVerityProcPath, F_OK) == 0;
+    if (!supportsFsVerity) {
+        LOG(INFO) << "Device doesn't support fsverity. Falling back to full verification.";
+    }
+
+    if (supportsFsVerity) {
+        auto existing_cert = verifyExistingCert(*key);
+        if (!existing_cert.ok()) {
+            LOG(WARNING) << existing_cert.error().message();
+
+            // Try to create a new cert
+            auto new_cert = createX509Cert(*key, kSigningKeyCert);
+            if (!new_cert.ok()) {
+                LOG(ERROR) << "Failed to create X509 certificate: " << new_cert.error().message();
+                // TODO apparently the key become invalid - delete the blob / cert
+                return -1;
+            }
+        } else {
+            LOG(INFO) << "Found and verified existing public key certificate: " << kSigningKeyCert;
+        }
+        auto cert_add_result = addCertToFsVerityKeyring(kSigningKeyCert);
+        if (!cert_add_result.ok()) {
+            LOG(ERROR) << "Failed to add certificate to fs-verity keyring: "
+                       << cert_add_result.error().message();
+            return -1;
+        }
+    }
+
+    art::odrefresh::ExitCode odrefresh_status = compileArtifacts(kForceCompilation);
+    if (odrefresh_status == art::odrefresh::ExitCode::kOkay) {
+        LOG(INFO) << "odrefresh said artifacts are VALID";
+        // A post-condition of validating artifacts is that if the ones on /system
+        // are used, kArtArtifactsDir is removed. Conversely, if kArtArtifactsDir
+        // exists, those are artifacts that will be used, and we should verify them.
+        int err = access(kArtArtifactsDir.c_str(), F_OK);
+        // If we receive any error other than ENOENT, be suspicious
+        bool artifactsPresent = (err == 0) || (err < 0 && errno != ENOENT);
+        if (artifactsPresent) {
+            auto verificationResult = verifyArtifacts(*key, supportsFsVerity);
+            if (!verificationResult.ok()) {
+                LOG(ERROR) << verificationResult.error().message();
+                return -1;
+            }
+        }
+    } else if (odrefresh_status == art::odrefresh::ExitCode::kCompilationSuccess ||
+               odrefresh_status == art::odrefresh::ExitCode::kCompilationFailed) {
+        const bool compiled_all = odrefresh_status == art::odrefresh::ExitCode::kCompilationSuccess;
+        LOG(INFO) << "odrefresh compiled " << (compiled_all ? "all" : "partial")
+                  << " artifacts, returned " << odrefresh_status;
+        Result<std::map<std::string, std::string>> digests;
+        if (supportsFsVerity) {
+            digests = addFilesToVerityRecursive(kArtArtifactsDir, *key);
+        } else {
+            // If we can't use verity, just compute the root hashes and store
+            // those, so we can reverify them at the next boot.
+            digests = computeDigests(kArtArtifactsDir);
+        }
+        if (!digests.ok()) {
+            LOG(ERROR) << digests.error().message();
+            return -1;
+        }
+        auto persistStatus = persistDigests(*digests, *key);
+        if (!persistStatus.ok()) {
+            LOG(ERROR) << persistStatus.error().message();
+            return -1;
+        }
+    } else if (odrefresh_status == art::odrefresh::ExitCode::kCleanupFailed) {
+        LOG(ERROR) << "odrefresh failed cleaning up existing artifacts";
+        return -1;
+    } else {
+        LOG(ERROR) << "odrefresh exited unexpectedly, returned " << odrefresh_status;
+        return -1;
+    }
+
+    LOG(INFO) << "On-device signing done.";
+
+    scope_guard.Disable();
+    // At this point, we're done with the key for sure
+    SetProperty(kOdsignKeyDoneProp, "1");
+    // And we did a successful verification
+    SetProperty(kOdsignVerificationDoneProp, "1");
+    SetProperty(kOdsignVerificationStatusProp, kOdsignVerificationStatusValid);
+    return 0;
+}
diff --git a/keystore/key_attestation_log_handler.h b/ondevice-signing/proto/Android.bp
similarity index 64%
rename from keystore/key_attestation_log_handler.h
rename to ondevice-signing/proto/Android.bp
index a418bfa..fd48f31 100644
--- a/keystore/key_attestation_log_handler.h
+++ b/ondevice-signing/proto/Android.bp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,13 +14,16 @@
  * limitations under the License.
  */
 
-#ifndef _KEY_ATTESTATION_LOG_HANDLER_H_
-#define _KEY_ATTESTATION_LOG_HANDLER_H_
-
-namespace keystore {
-
-void logKeystoreKeyAttestationEvent(bool wasSuccessful, int32_t errorCode);
-
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-#endif  //_KEY_ATTESTATION_LOG_HANDLER_H_
+cc_library_static {
+    name: "lib_odsign_proto",
+    host_supported: true,
+    proto: {
+        export_proto_headers: true,
+        type: "full",
+    },
+    srcs: ["odsign_info.proto"],
+}
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/ondevice-signing/proto/odsign_info.proto
similarity index 73%
copy from keystore/binder/android/security/keymaster/OperationResult.aidl
copy to ondevice-signing/proto/odsign_info.proto
index db689d4..9d49c6c 100644
--- a/keystore/binder/android/security/keymaster/OperationResult.aidl
+++ b/ondevice-signing/proto/odsign_info.proto
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,7 +14,11 @@
  * limitations under the License.
  */
 
-package android.security.keymaster;
+syntax = "proto3";
 
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
+package odsign.proto;
+
+message OdsignInfo {
+  // Map of artifact files to their hashes
+  map<string, string> file_hashes = 1;
+}
diff --git a/provisioner/Android.bp b/provisioner/Android.bp
new file mode 100644
index 0000000..12a21d1
--- /dev/null
+++ b/provisioner/Android.bp
@@ -0,0 +1,69 @@
+//
+// Copyright (C) 2020 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 {
+    // 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,
+    local_include_dir: "binder",
+    srcs: [
+        "binder/android/security/provisioner/*.aidl",
+    ],
+    backend: {
+        java: {
+            platform_apis: true,
+        },
+        cpp: {
+            enabled: false,
+        },
+        ndk: {
+            enabled: false,
+        },
+    },
+}
+
+java_binary {
+    name: "provisioner_cli",
+    wrapper: "provisioner_cli",
+    srcs: ["src/com/android/commands/provisioner/**/*.java"],
+    static_libs: [
+        "android.security.provisioner-java",
+    ],
+}
+
+cc_binary {
+    name: "rkp_factory_extraction_tool",
+    srcs: ["rkp_factory_extraction_tool.cpp"],
+    shared_libs: [
+        "android.hardware.security.keymint-V1-ndk_platform",
+        "libbinder",
+        "libbinder_ndk",
+        "libcppbor_external",
+        "libcppcose_rkp",
+        "libcrypto",
+        "liblog",
+        "libvintf",
+    ],
+    //export_include_dirs: ["include"],
+}
diff --git a/keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl b/provisioner/binder/android/security/provisioner/IProvisionerService.aidl
similarity index 67%
rename from keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl
rename to provisioner/binder/android/security/provisioner/IProvisionerService.aidl
index b42e3d4..f81e9ab 100644
--- a/keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl
+++ b/provisioner/binder/android/security/provisioner/IProvisionerService.aidl
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
-package android.security.keystore;
-
+package android.security.provisioner;
 
 /**
  * @hide
  */
-oneway interface ICredstoreTokenCallback {
-	void onFinished(boolean success, in byte[] authToken, in byte[] verificationToken);
+interface IProvisionerService {
+    byte[] getCertificateRequest(in boolean testMode,
+                                 in int keyCount,
+                                 in byte[] endpointEncryptionKey,
+                                 in byte[] challenge) = 0;
 }
diff --git a/provisioner/provisioner_cli b/provisioner/provisioner_cli
new file mode 100755
index 0000000..7b53d6e
--- /dev/null
+++ b/provisioner/provisioner_cli
@@ -0,0 +1,21 @@
+#!/system/bin/sh
+#
+# Copyright (C) 2020 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.
+#
+# Script to start "provisioner_cli" on the device.
+#
+base=/system
+export CLASSPATH=$base/framework/provisioner_cli.jar
+exec app_process $base/bin com.android.commands.provisioner.Cli "$@"
diff --git a/provisioner/rkp_factory_extraction_tool.cpp b/provisioner/rkp_factory_extraction_tool.cpp
new file mode 100644
index 0000000..d4842b1
--- /dev/null
+++ b/provisioner/rkp_factory_extraction_tool.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2021 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 <string>
+#include <vector>
+
+#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
+#include <android/binder_manager.h>
+#include <cppbor.h>
+#include <keymaster/cppcose/cppcose.h>
+#include <log/log.h>
+#include <vintf/VintfObject.h>
+
+using std::set;
+using std::string;
+using std::vector;
+
+using aidl::android::hardware::security::keymint::DeviceInfo;
+using aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
+using aidl::android::hardware::security::keymint::MacedPublicKey;
+using aidl::android::hardware::security::keymint::ProtectedData;
+
+using android::vintf::HalManifest;
+using android::vintf::VintfObject;
+
+using namespace cppbor;
+using namespace cppcose;
+
+namespace {
+
+const string kPackage = "android.hardware.security.keymint";
+const string kInterface = "IRemotelyProvisionedComponent";
+const string kFormattedName = kPackage + "." + kInterface + "/";
+
+ErrMsgOr<vector<uint8_t>> generateEekChain(size_t length, const vector<uint8_t>& eekId) {
+    auto eekChain = cppbor::Array();
+
+    vector<uint8_t> prevPrivKey;
+    for (size_t i = 0; i < length - 1; ++i) {
+        vector<uint8_t> pubKey(ED25519_PUBLIC_KEY_LEN);
+        vector<uint8_t> privKey(ED25519_PRIVATE_KEY_LEN);
+
+        ED25519_keypair(pubKey.data(), privKey.data());
+
+        // The first signing key is self-signed.
+        if (prevPrivKey.empty()) prevPrivKey = privKey;
+
+        auto coseSign1 = constructCoseSign1(prevPrivKey,
+                                            cppbor::Map() /* payload CoseKey */
+                                                .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
+                                                .add(CoseKey::ALGORITHM, EDDSA)
+                                                .add(CoseKey::CURVE, ED25519)
+                                                .add(CoseKey::PUBKEY_X, pubKey)
+                                                .canonicalize()
+                                                .encode(),
+                                            {} /* AAD */);
+        if (!coseSign1) return coseSign1.moveMessage();
+        eekChain.add(coseSign1.moveValue());
+
+        prevPrivKey = privKey;
+    }
+
+    vector<uint8_t> pubKey(X25519_PUBLIC_VALUE_LEN);
+    vector<uint8_t> privKey(X25519_PRIVATE_KEY_LEN);
+    X25519_keypair(pubKey.data(), privKey.data());
+
+    auto coseSign1 = constructCoseSign1(prevPrivKey,
+                                        cppbor::Map() /* payload CoseKey */
+                                            .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
+                                            .add(CoseKey::KEY_ID, eekId)
+                                            .add(CoseKey::ALGORITHM, ECDH_ES_HKDF_256)
+                                            .add(CoseKey::CURVE, cppcose::X25519)
+                                            .add(CoseKey::PUBKEY_X, pubKey)
+                                            .canonicalize()
+                                            .encode(),
+                                        {} /* AAD */);
+    if (!coseSign1) return coseSign1.moveMessage();
+    eekChain.add(coseSign1.moveValue());
+
+    return eekChain.encode();
+}
+
+std::vector<uint8_t> getChallenge() {
+    return std::vector<uint8_t>(0);
+}
+
+std::vector<uint8_t> composeCertificateRequest(ProtectedData&& protectedData,
+                                               DeviceInfo&& deviceInfo) {
+    Array emptyMacedKeysToSign;
+    emptyMacedKeysToSign
+        .add(std::vector<uint8_t>(0))   // empty protected headers as bstr
+        .add(Map())                     // empty unprotected headers
+        .add(Null())                    // nil for the payload
+        .add(std::vector<uint8_t>(0));  // empty tag as bstr
+    Array certificateRequest;
+    certificateRequest.add(EncodedItem(std::move(deviceInfo.deviceInfo)))
+        .add(getChallenge())  // fake challenge
+        .add(EncodedItem(std::move(protectedData.protectedData)))
+        .add(std::move(emptyMacedKeysToSign));
+    return certificateRequest.encode();
+}
+
+int32_t errorMsg(string name) {
+    std::cerr << "Failed for rkp instance: " << name;
+    return -1;
+}
+
+}  // namespace
+
+int main() {
+    std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+    set<string> rkpNames = manifest->getAidlInstances(kPackage, kInterface);
+    for (auto name : rkpNames) {
+        string fullName = kFormattedName + name;
+        if (!AServiceManager_isDeclared(fullName.c_str())) {
+            ALOGE("Could not find the following instance declared in the manifest: %s\n",
+                  fullName.c_str());
+            return errorMsg(name);
+        }
+        AIBinder* rkpAiBinder = AServiceManager_getService(fullName.c_str());
+        ::ndk::SpAIBinder rkp_binder(rkpAiBinder);
+        auto rkp_service = IRemotelyProvisionedComponent::fromBinder(rkp_binder);
+        std::vector<uint8_t> keysToSignMac;
+        std::vector<MacedPublicKey> emptyKeys;
+
+        // Replace this eek chain generation with the actual production GEEK
+        std::vector<uint8_t> eekId(10);  // replace with real KID later (EEK fingerprint)
+        auto eekOrErr = generateEekChain(3 /* chainlength */, eekId);
+        if (!eekOrErr) {
+            ALOGE("Failed to generate test EEK somehow: %s", eekOrErr.message().c_str());
+            return errorMsg(name);
+        }
+
+        std::vector<uint8_t> eek = eekOrErr.moveValue();
+        DeviceInfo deviceInfo;
+        ProtectedData protectedData;
+        if (rkp_service) {
+            ALOGE("extracting bundle");
+            ::ndk::ScopedAStatus status = rkp_service->generateCertificateRequest(
+                true /* testMode */, emptyKeys, eek, getChallenge(), &deviceInfo, &protectedData,
+                &keysToSignMac);
+            if (!status.isOk()) {
+                ALOGE("Bundle extraction failed. Error code: %d", status.getServiceSpecificError());
+                return errorMsg(name);
+            }
+            std::cout << "\n";
+            std::vector<uint8_t> certificateRequest =
+                composeCertificateRequest(std::move(protectedData), std::move(deviceInfo));
+            std::copy(certificateRequest.begin(), certificateRequest.end(),
+                      std::ostream_iterator<char>(std::cout));
+        }
+    }
+}
diff --git a/provisioner/src/com/android/commands/provisioner/Cli.java b/provisioner/src/com/android/commands/provisioner/Cli.java
new file mode 100644
index 0000000..62afdac
--- /dev/null
+++ b/provisioner/src/com/android/commands/provisioner/Cli.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2020 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 com.android.commands.provisioner;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.security.provisioner.IProvisionerService;
+
+import com.android.internal.os.BaseCommand;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.IllegalArgumentException;
+
+/**
+ * Contains the implementation of the remote provisioning command-line interface.
+ */
+public class Cli extends BaseCommand {
+    /**
+     * Creates an instance of the command-line interface and runs it. This is the entry point of
+     * the tool.
+     */
+    public static void main(String[] args) {
+        new Cli().run(args);
+    }
+
+    /**
+     * Runs the command requested by the invoker. It parses the very first required argument, which
+     * is the command, and calls the appropriate handler.
+     */
+    @Override
+    public void onRun() throws Exception {
+        String cmd = nextArgRequired();
+        switch (cmd) {
+        case "get-req":
+            getRequest();
+            break;
+
+        case "help":
+            onShowUsage(System.out);
+            break;
+
+        default:
+            throw new IllegalArgumentException("unknown command: " + cmd);
+        }
+    }
+
+    /**
+     * Retrieves a 'certificate request' from the provisioning service. The COSE-encoded
+     * 'certificate chain' describing the endpoint encryption key (EEK) to use for encryption is
+     * read from the standard input. The retrieved request is written to the standard output.
+     */
+    private void getRequest() throws Exception {
+        // Process options.
+        boolean test = false;
+        byte[] challenge = null;
+        int count = 0;
+        String arg;
+        while ((arg = nextArg()) != null) {
+            switch (arg) {
+            case "--test":
+                test = true;
+                break;
+
+            case "--challenge":
+                // TODO: We may need a different encoding of the challenge.
+                challenge = nextArgRequired().getBytes();
+                break;
+
+            case "--count":
+                count = Integer.parseInt(nextArgRequired());
+                if (count < 0) {
+                    throw new IllegalArgumentException(
+                            "--count must be followed by non-negative number");
+                }
+                break;
+
+            default:
+                throw new IllegalArgumentException("unknown argument: " + arg);
+            }
+        }
+
+        // Send the request over to the provisioning service and write the result to stdout.
+        byte[] res = getService().getCertificateRequest(test, count, readAll(System.in), challenge);
+        if (res != null) {
+            System.out.write(res);
+        }
+    }
+
+    /**
+     * Retrieves an implementation of the IProvisionerService interface. It allows the caller to
+     * call into the service via binder.
+     */
+    private static IProvisionerService getService() throws RemoteException {
+        IBinder binder = ServiceManager.getService("remote-provisioner");
+        if (binder == null) {
+            throw new RemoteException("Provisioning service is inaccessible");
+        }
+        return IProvisionerService.Stub.asInterface(binder);
+    }
+
+    /** Reads all data from the provided input stream and returns it as a byte array. */
+    private static byte[] readAll(InputStream in) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+        int read;
+        while ((read = in.read(buf)) != -1) {
+            out.write(buf, 0, read);
+        }
+        return out.toByteArray();
+    }
+
+    /**
+     * Writes the usage information to the given stream. This is displayed to users of the tool when
+     * they ask for help or when they pass incorrect arguments to the tool.
+     */
+    @Override
+    public void onShowUsage(PrintStream out) {
+        out.println(
+                "Usage: provisioner_cli <command> [options]\n" +
+                "Commands: help\n" +
+                "          get-req [--count <n>] [--test] [--challenge <v>]");
+    }
+}
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 120000
index 0000000..ee92d9e
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1 @@
+../../build/soong/scripts/rustfmt.toml
\ No newline at end of file
