diff --git a/OWNERS b/OWNERS
index fca66f8..93c024d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,8 @@
-swillden@google.com
 cbrubaker@google.com
+hasinitg@google.com
+jbires@google.com
 jdanis@google.com
-kroot@google.com
\ No newline at end of file
+kroot@google.com
+sethmo@google.com
+swillden@google.com
+zeuthen@google.com
diff --git a/fsverity_init/fsverity_init.cpp b/fsverity_init/fsverity_init.cpp
index b81fb22..7bc6022 100644
--- a/fsverity_init/fsverity_init.cpp
+++ b/fsverity_init/fsverity_init.cpp
@@ -37,18 +37,21 @@
     return true;
 }
 
-void LoadKeyFromStdin(key_serial_t keyring_id, const char* keyname) {
+bool 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;
+        return false;
     }
     if (!LoadKeyToKeyring(keyring_id, keyname, content.c_str(), content.size())) {
         LOG(ERROR) << "Failed to load key from stdin";
+        return false;
     }
+    return true;
 }
 
 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;
@@ -59,22 +62,24 @@
     }
 }
 
-void LoadKeyFromDirectory(key_serial_t keyring_id, const char* keyname, const char* dir) {
+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;
-
-        LoadKeyFromFile(keyring_id, keyname, 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) {
@@ -98,7 +103,9 @@
             LOG(ERROR) << "--load-extra-key requires <key_name> argument.";
             return -1;
         }
-        LoadKeyFromStdin(keyring_id, argv[2]);
+        if (!LoadKeyFromStdin(keyring_id, argv[2])) {
+            return -1;
+        }
     } else if (command == "--lock") {
         // Requires files backed by fs-verity to be verified with a key in .fs-verity
         // keyring.
diff --git a/identity/Android.bp b/identity/Android.bp
index ed8ff2f..ecdf9a4 100644
--- a/identity/Android.bp
+++ b/identity/Android.bp
@@ -39,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",
+        "android.security.authorization-ndk",
     ],
     static_libs: [
         "android.hardware.identity-V3-cpp",
         "android.hardware.keymaster-V3-cpp",
-        "libcppbor",
+        "libcppbor_external",
     ]
 }
 
diff --git a/identity/Credential.cpp b/identity/Credential.cpp
index 4a2bae1..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,6 +31,11 @@
 #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"
@@ -46,8 +49,6 @@
 using std::promise;
 using std::tuple;
 
-using android::security::keystore::IKeystoreService;
-
 using ::android::hardware::identity::IWritableIdentityCredential;
 
 using ::android::hardware::identity::support::ecKeyPairGetPkcs12;
@@ -55,11 +56,17 @@
 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, uid_t callingUid,
                        HardwareInformation hwInfo, sp<IIdentityCredentialStore> halStoreBinder,
@@ -117,73 +124,94 @@
                                                 "Error loading data for credential");
     }
 
-    selectedAuthKey_ = data->selectAuthKey(allowUsingExhaustedKeys, allowUsingExpiredKeys);
-    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,
@@ -279,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.
     //
@@ -303,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, allowUsingExpiredKeys);
-            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;
@@ -750,31 +766,36 @@
     //
     // 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, halApiVersion_);
+    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 reconnect to the HAL when the
-    // credential has been updated... otherwise the remote object will have
-    // stale data for future calls (e.g. getAuthKeysNeedingCertification().
+    // 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 joys and pitfalls of mutable objects...
+    // The way this is implemented is that setCredentialToReloadWhenUpdated()
+    // instructs the WritableCredential to call writableCredentialPersonalized()
+    // on |this|.
     //
-    writableCredential->setCredentialUpdatedCallback([this] {
-        Status status = this->ensureOrReplaceHalBinder();
-        if (!status.isOk()) {
-            LOG(ERROR) << "Error loading credential";
-        }
-    });
+    //
+    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 7f08515..a76f3cc 100644
--- a/identity/Credential.h
+++ b/identity/Credential.h
@@ -50,6 +50,7 @@
     ~Credential();
 
     Status ensureOrReplaceHalBinder();
+    void writableCredentialPersonalized();
 
     // ICredential overrides
     Status createEphemeralKeyPair(vector<uint8_t>* _aidl_return) override;
@@ -94,12 +95,13 @@
     HardwareInformation hwInfo_;
     sp<IIdentityCredentialStore> halStoreBinder_;
 
-    const AuthKeyData* selectedAuthKey_ = nullptr;
     uint64_t selectedChallenge_ = 0;
 
     sp<IIdentityCredential> halBinder_;
     int halApiVersion_;
 
+    bool ensureChallenge();
+
     ssize_t
     calcExpectedDeviceNameSpacesSize(const vector<uint8_t>& requestMessage,
                                      const vector<RequestNamespaceParcel>& requestNamespaces,
diff --git a/identity/CredentialData.cpp b/identity/CredentialData.cpp
index 96c436a..74b995d 100644
--- a/identity/CredentialData.cpp
+++ b/identity/CredentialData.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CredentialData"
+#define LOG_TAG "credstore"
 
 #include <chrono>
 
@@ -273,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";
@@ -325,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";
diff --git a/identity/CredentialData.h b/identity/CredentialData.h
index b037997..24b55d3 100644
--- a/identity/CredentialData.h
+++ b/identity/CredentialData.h
@@ -55,7 +55,7 @@
 
     vector<uint8_t> certificate;
     vector<uint8_t> keyBlob;
-    int64_t expirationDateMillisSinceEpoch;
+    int64_t expirationDateMillisSinceEpoch = 0;
     vector<uint8_t> staticAuthenticationData;
     vector<uint8_t> pendingCertificate;
     vector<uint8_t> pendingKeyBlob;
diff --git a/identity/CredentialStore.cpp b/identity/CredentialStore.cpp
index f77294e..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>
 
@@ -90,7 +90,7 @@
     }
 
     sp<IWritableCredential> writableCredential = new WritableCredential(
-        dataPath_, credentialName, docType, false, hwInfo_, halWritableCredential, halApiVersion_);
+        dataPath_, credentialName, docType, false, hwInfo_, halWritableCredential);
     *_aidl_return = writableCredential;
     return Status::ok();
 }
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 cd29017..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>
diff --git a/identity/WritableCredential.cpp b/identity/WritableCredential.cpp
index d0688b8..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>
@@ -41,15 +41,14 @@
 WritableCredential::WritableCredential(const string& dataPath, const string& credentialName,
                                        const string& docType, bool isUpdate,
                                        HardwareInformation hwInfo,
-                                       sp<IWritableIdentityCredential> halBinder, int halApiVersion)
+                                       sp<IWritableIdentityCredential> halBinder)
     : dataPath_(dataPath), credentialName_(credentialName), docType_(docType), isUpdate_(isUpdate),
-      hwInfo_(std::move(hwInfo)), halBinder_(halBinder), halApiVersion_(halApiVersion) {}
+      hwInfo_(std::move(hwInfo)), halBinder_(halBinder) {}
 
 WritableCredential::~WritableCredential() {}
 
-void WritableCredential::setCredentialUpdatedCallback(
-    std::function<void()>&& onCredentialUpdatedCallback) {
-    onCredentialUpdatedCallback_ = onCredentialUpdatedCallback;
+void WritableCredential::setCredentialToReloadWhenUpdated(sp<Credential> credential) {
+    credentialToReloadWhenUpdated_ = credential;
 }
 
 Status WritableCredential::ensureAttestationCertificateExists(const vector<uint8_t>& challenge) {
@@ -268,7 +267,10 @@
                                                 "Error saving credential data to disk");
     }
 
-    onCredentialUpdatedCallback_();
+    if (credentialToReloadWhenUpdated_) {
+        credentialToReloadWhenUpdated_->writableCredentialPersonalized();
+        credentialToReloadWhenUpdated_.clear();
+    }
 
     *_aidl_return = proofOfProvisioningSignature;
     return Status::ok();
diff --git a/identity/WritableCredential.h b/identity/WritableCredential.h
index 6ff31ae..838b956 100644
--- a/identity/WritableCredential.h
+++ b/identity/WritableCredential.h
@@ -24,6 +24,8 @@
 
 #include <android/hardware/identity/IIdentityCredentialStore.h>
 
+#include "Credential.h"
+
 namespace android {
 namespace security {
 namespace identity {
@@ -38,13 +40,15 @@
   public:
     WritableCredential(const string& dataPath, const string& credentialName, const string& docType,
                        bool isUpdate, HardwareInformation hwInfo,
-                       sp<IWritableIdentityCredential> halBinder, int halApiVersion);
+                       sp<IWritableIdentityCredential> halBinder);
     ~WritableCredential();
 
     // Used when updating a credential
     void setAttestationCertificate(const vector<uint8_t>& attestationCertificate);
     void setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey);
-    void setCredentialUpdatedCallback(std::function<void()>&& onCredentialUpdatedCallback);
+
+    // Used by Credential::update()
+    void setCredentialToReloadWhenUpdated(sp<Credential> credential);
 
     // IWritableCredential overrides
     Status getCredentialKeyCertificateChain(const vector<uint8_t>& challenge,
@@ -61,13 +65,12 @@
     bool isUpdate_;
     HardwareInformation hwInfo_;
     sp<IWritableIdentityCredential> halBinder_;
-    int halApiVersion_;
 
     vector<uint8_t> attestationCertificate_;
     int keyCount_ = 0;
     int maxUsesPerKey_ = 1;
 
-    std::function<void()> onCredentialUpdatedCallback_ = []() {};
+    sp<Credential> credentialToReloadWhenUpdated_;
 
     ssize_t calcExpectedProofOfProvisioningSize(
         const vector<AccessControlProfileParcel>& accessControlProfiles,
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 9980765..cb75cde 100644
--- a/keystore-engine/Android.bp
+++ b/keystore-engine/Android.bp
@@ -26,7 +26,6 @@
 
     srcs: [
         "android_engine.cpp",
-        "keystore_backend_binder.cpp",
         "keystore2_engine.cpp",
     ],
 
@@ -37,15 +36,10 @@
     ],
 
     shared_libs: [
-        "android.system.keystore2-V1-ndk_platform",
-        "libbinder",
+        "android.system.keystore2-V1-ndk",
         "libbinder_ndk",
         "libcrypto",
         "libcutils",
-        "libhidlbase",
-        "libkeystore_aidl",
-        "libkeystore_binder",
-        "libkeystore_parcelables",
         "liblog",
         "libbase",
         "libutils",
@@ -53,14 +47,15 @@
 
 }
 
-// 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",
     ],
 
@@ -68,17 +63,14 @@
         "-fvisibility=hidden",
         "-Wall",
         "-Werror",
-        "-DBACKEND_WIFI_HIDL",
     ],
 
     shared_libs: [
-        "android.system.keystore2-V1-ndk_platform",
-        "android.system.wifi.keystore@1.0",
+        "android.system.keystore2-V1-ndk",
         "libbase",
         "libbinder_ndk",
         "libcrypto",
         "liblog",
-        "libhidlbase",
         "libcutils",
         "libutils",
     ],
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index 5881523..e46204e 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -22,307 +22,10 @@
 
 #define LOG_TAG "keystore-engine"
 
-#include <pthread.h>
-#include <string.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>
-
 #include "keystore2_engine.h"
 
-#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 */
-
 extern "C" {
 
 EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id) __attribute__((visibility("default")));
@@ -334,48 +37,7 @@
 EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id) {
     ALOGV("EVP_PKEY_from_keystore(\"%s\")", key_id);
 
-    if (auto ks2_key = EVP_PKEY_from_keystore2(key_id)) {
-        return ks2_key;
-    }
-
-    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
index 18534a1..ee550ca 100644
--- a/keystore-engine/keystore2_engine.cpp
+++ b/keystore-engine/keystore2_engine.cpp
@@ -33,7 +33,7 @@
 
 #define AT __func__ << ":" << __LINE__ << " "
 
-constexpr const char keystore2_service_name[] = "android.system.keystore2";
+constexpr const char keystore2_service_name[] = "android.system.keystore2.IKeystoreService/default";
 const std::string keystore2_grant_id_prefix("ks2_keystore-engine_grant_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 7278cee..ad4b4b1 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -35,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"],
 
@@ -133,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",
+        "android.system.keystore2-V1-ndk",
         "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 {
@@ -248,7 +87,7 @@
 }
 
 // Library for keystore clients using the WiFi HIDL interface
-cc_library_shared {
+cc_library {
     name: "libkeystore-wifi-hidl",
     defaults: ["keystore_defaults"],
 
@@ -265,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/KeyStore.cpp b/keystore/KeyStore.cpp
deleted file mode 100644
index 1f80899..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, SecurityLevel(i));
-        }
-    }
-}
-
-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 7841a80..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 N> struct tuple_size<keystore::Devices<T, N>> {
-  public:
-    static constexpr size_t value = std::tuple_size<std::array<T, N>>::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/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/IKeystoreOperationResultCallback.aidl b/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
deleted file mode 100644
index f37b838..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreOperationResultCallback.aidl
+++ /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.
- */
-
-package android.security.keystore;
-
-import android.security.keystore.KeystoreResponse;
-import android.security.keymaster.OperationResult;
-
-/**
- * @hide
- */
-@SensitiveData
-oneway interface IKeystoreOperationResultCallback {
-    void onFinished(in OperationResult result);
-}
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 e0879dd..0000000
--- a/keystore/binder/android/security/keystore/IKeystoreService.aidl
+++ /dev/null
@@ -1,93 +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
- */
-@SensitiveData
-interface IKeystoreService {
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    int getState(int userId);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    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(maxTargetSdk = 30, trackingBug = 170729553)
-    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/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_attestation_log_handler.h b/keystore/key_attestation_log_handler.h
deleted file mode 100644
index a418bfa..0000000
--- a/keystore/key_attestation_log_handler.h
+++ /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.
- */
-
-#ifndef _KEY_ATTESTATION_LOG_HANDLER_H_
-#define _KEY_ATTESTATION_LOG_HANDLER_H_
-
-namespace keystore {
-
-void logKeystoreKeyAttestationEvent(bool wasSuccessful, int32_t errorCode);
-
-}
-
-#endif  //_KEY_ATTESTATION_LOG_HANDLER_H_
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 4e5bc48..0000000
--- a/keystore/key_store_service.cpp
+++ /dev/null
@@ -1,1480 +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 isDeviceIdAttestationTag(Tag tag) {
-    switch (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;
-    case Tag::INVALID:
-    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::INCLUDE_UNIQUE_ID:
-    case Tag::BLOB_USAGE_REQUIREMENTS:
-    case Tag::BOOTLOADER_ONLY:
-    case Tag::ROLLBACK_RESISTANCE:
-    case Tag::HARDWARE_TYPE:
-    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::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::APPLICATION_ID:
-    case Tag::APPLICATION_DATA:
-    case Tag::CREATION_DATETIME:
-    case Tag::ORIGIN:
-    case Tag::ROOT_OF_TRUST:
-    case Tag::OS_VERSION:
-    case Tag::OS_PATCHLEVEL:
-    case Tag::UNIQUE_ID:
-    case Tag::ATTESTATION_CHALLENGE:
-    case Tag::ATTESTATION_APPLICATION_ID:
-    case Tag::VENDOR_PATCHLEVEL:
-    case Tag::BOOT_PATCHLEVEL:
-    case Tag::ASSOCIATED_DATA:
-    case Tag::NONCE:
-    case Tag::MAC_LENGTH:
-    case Tag::RESET_SINCE_ID_ROTATION:
-    case Tag::CONFIRMATION_TOKEN:
-        return false;
-        // no default, all values must be present in the switch, in this way the compiler ensures
-        // that new values added in the Tag enum are also added here.
-    }
-}
-
-// These are attestation id tags that are not unique per device and don't require special permission
-// to be attested. Any addition to this list needs privacy review and approval (PWG).
-bool isDevicePropertyAttestationTag(Tag tag) {
-    switch (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:
-        return true;
-    default:
-        return false;
-    }
-}
-
-bool isDeviceIdAttestationRequested(const KeymasterArguments& params) {
-    const hardware::hidl_vec<KeyParameter>& paramsVec = params.getParameters();
-    for (size_t i = 0; i < paramsVec.size(); ++i) {
-        if (isDeviceIdAttestationTag(paramsVec[i].tag)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-// Device properties can be attested safely without special permission
-bool needsPermissionToAttestDeviceIds(const KeymasterArguments& params) {
-    const hardware::hidl_vec<KeyParameter>& paramsVec = params.getParameters();
-    for (size_t i = 0; i < paramsVec.size(); ++i) {
-        if (isDeviceIdAttestationTag(paramsVec[i].tag) &&
-            !isDevicePropertyAttestationTag(paramsVec[i].tag)) {
-            return true;
-        }
-    }
-    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 (needsPermissionToAttestDeviceIds(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();
-
-    // Request special permission only for unique ids
-    if (needsPermissionToAttestDeviceIds(params)) {
-        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 cbb184c..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,
-                                 SecurityLevel internalSecurityLevel)
-    : keymasterDevice_(std::move(keymasterDevice)), operationMap_(keyStore), keyStore_(keyStore),
-      internalSecurityLevel_(internalSecurityLevel) {
-    // 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(internalSecurityLevel_);
-            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(internalSecurityLevel_);
-            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);
-
-        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(internalSecurityLevel_);
-            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 fbd52b4..0000000
--- a/keystore/keymaster_worker.h
+++ /dev/null
@@ -1,307 +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_;
-
-    /**
-     * Models the security level of this worker internal to KeyStore.
-     *
-     * When the device has only a software Keymaster, KeyStore will set it on the TEE slot and
-     * instantiate a new in-process software Keymaster. In that case there is a mismatch between the
-     * security level used by KeyStore and what is reported from the HAL. This represents the level
-     * used internally by KeyStore.
-     *
-     * This value is used to associate blobs to the corresponding Keymaster backend. It does not
-     * indicate an actual Keymaster HAL security level and should never be exposed to users.
-     */
-    SecurityLevel internalSecurityLevel_;
-
-    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,
-                    SecurityLevel internalSecurityLevel);
-
-    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_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..43f72a9 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.IKeystoreService/default";
+
+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 052f394..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(keymaster::KmVersion::KEYMASTER_2))->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 327eb93..f51cc2f 100644
--- a/keystore/tests/Android.bp
+++ b/keystore/tests/Android.bp
@@ -18,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",
     ],
@@ -35,7 +31,6 @@
         "libhidlbase",
         "libkeymaster4support",
         "libkeymaster4_1support",
-        "libkeystore_test",
         "liblog",
         "libutils",
     ],
@@ -63,17 +58,14 @@
     ],
     name: "confirmationui_invocation_test",
     static_libs: [
-        "android.hardware.confirmationui@1.0",
         "libbase",
         "libgtest_main",
         "libutils",
         "liblog",
+        "android.security.apc-ndk",
     ],
     shared_libs: [
-        "libbinder",
-        "libkeystore_aidl", // for IKeyStoreService.asInterface()
-        "libkeystore_binder",
-        "libkeystore_parcelables",
+        "libbinder_ndk",
     ],
    sanitize: {
      cfi: false,
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
index 812d5e6..9c3ce6e 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -21,19 +21,22 @@
     default_applicable_licenses: ["system_security_license"],
 }
 
-rust_library {
-    name: "libkeystore2",
+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.metrics-rust",
         "android.security.remoteprovisioning-rust",
-        "android.security.usermanager-rust",
         "android.system.keystore2-V1-rust",
         "libanyhow",
         "libbinder_rs",
@@ -42,14 +45,28 @@
         "libkeystore2_crypto_rust",
         "libkeystore2_km_compat",
         "libkeystore2_selinux",
+        "libkeystore2_vintf_rust",
         "liblazy_static",
         "liblibc",
         "liblibsqlite3_sys",
+        "liblog_event_list",
         "liblog_rust",
         "librand",
         "librusqlite",
+        "librustutils",
         "libthiserror",
     ],
+    shared_libs: [
+        "libcutils",
+    ],
+    features: [
+        "watchdog",
+    ],
+}
+
+rust_library {
+    name: "libkeystore2",
+    defaults: ["libkeystore2_defaults"],
 }
 
 rust_library {
@@ -59,41 +76,24 @@
     rustlibs: [
         "liblog_rust",
         "librand",
-    ]
+    ],
 }
 
 rust_test {
     name: "keystore2_test",
     crate_name: "keystore2",
-    srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
     compile_multilib: "first",
+    defaults: ["libkeystore2_defaults"],
     rustlibs: [
-        "android.hardware.security.keymint-V1-rust",
-        "android.hardware.security.secureclock-V1-rust",
-        "android.security.apc-rust",
-        "android.security.authorization-rust",
-        "android.security.compat-rust",
-        "android.security.remoteprovisioning-rust",
-        "android.security.usermanager-rust",
-        "android.system.keystore2-V1-rust",
         "libandroid_logger",
-        "libanyhow",
-        "libbinder_rs",
-        "libkeystore2_aaid-rust",
-        "libkeystore2_apc_compat-rust",
-        "libkeystore2_crypto_rust",
-        "libkeystore2_km_compat",
-        "libkeystore2_selinux",
         "libkeystore2_test_utils",
-        "liblazy_static",
-        "liblibc",
-        "liblibsqlite3_sys",
-        "liblog_rust",
-        "librand",
-        "librusqlite",
-        "libthiserror",
+        "libnix",
+    ],
+    // The test should always include watchdog.
+    features: [
+        "watchdog",
     ],
 }
 
@@ -105,6 +105,43 @@
         "libbinder_rs",
         "libkeystore2",
         "liblog_rust",
+        "liblegacykeystore-rust",
+        "librusqlite",
     ],
     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",
+        "android.security.compat-ndk",
+        "libc",
+        "libdl_android",
+        "libdl",
+        "libandroidicu",
+        "libkeymint",
+        "libkeystore2_aaid",
+        "libkeystore2_apc_compat",
+        "libkeystore2_crypto",
+        "libkm_compat_service",
+        "libkm_compat",
+        "libm",
+        "libstatspull",
+        "libstatssocket",
+    ],
+
+    vintf_fragments: ["android.system.keystore2-service.xml"],
+
+    required: ["keystore_cli_v2"],
 }
diff --git a/keystore2/TEST_MAPPING b/keystore2/TEST_MAPPING
index 99a1e60..16b6f85 100644
--- a/keystore2/TEST_MAPPING
+++ b/keystore2/TEST_MAPPING
@@ -8,6 +8,9 @@
     },
     {
       "name": "keystore2_test"
+    },
+    {
+      "name": "CtsIdentityTestCases"
     }
   ]
 }
diff --git a/keystore2/aaid/Android.bp b/keystore2/aaid/Android.bp
index d27fdf6..3417960 100644
--- a/keystore2/aaid/Android.bp
+++ b/keystore2/aaid/Android.bp
@@ -39,8 +39,8 @@
 
     bindgen_flags: [
         "--size_t-is-usize",
-        "--whitelist-function=aaid_keystore_attestation_id",
-        "--whitelist-var=KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE",
+        "--allowlist-function=aaid_keystore_attestation_id",
+        "--allowlist-var=KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE",
     ],
 }
 
@@ -57,3 +57,13 @@
         "libkeystore2_aaid",
     ],
 }
+
+rust_test {
+    name: "libkeystore2_aaid_bindgen_test",
+    srcs: [":libkeystore2_aaid_bindgen"],
+    crate_name: "keystore2_aaid_bindgen_test",
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    clippy_lints: "none",
+    lints: "none",
+}
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index c92417b..4a7b7b4 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -24,15 +24,20 @@
 aidl_interface {
     name: "android.security.attestationmanager",
     srcs: [ "android/security/attestationmanager/*.aidl", ],
-    imports: [ "android.hardware.security.keymint" ],
+    imports: [ "android.hardware.security.keymint-V1" ],
     unstable: true,
     backend: {
         java: {
-            sdk_version: "module_current",
+            platform_apis: true,
+            srcs_available: true,
         },
         rust: {
             enabled: true,
         },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        }
     },
 }
 
@@ -40,19 +45,21 @@
     name: "android.security.authorization",
     srcs: [ "android/security/authorization/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint",
-        "android.hardware.security.secureclock",
+        "android.hardware.security.keymint-V1",
+        "android.hardware.security.secureclock-V1",
     ],
     unstable: true,
     backend: {
         java: {
-            sdk_version: "module_current",
+            platform_apis: true,
+            srcs_available: true,
         },
         rust: {
             enabled: true,
         },
         ndk: {
             enabled: true,
+            apps_enabled: false,
         }
     },
 }
@@ -64,10 +71,14 @@
     backend: {
         java: {
             enabled: true,
+            srcs_available: true,
         },
         rust: {
             enabled: true,
         },
+        ndk: {
+            enabled: true,
+        }
     },
 }
 
@@ -75,21 +86,23 @@
     name: "android.security.compat",
     srcs: [ "android/security/compat/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint",
-        "android.hardware.security.secureclock",
-        "android.hardware.security.sharedsecret",
+        "android.hardware.security.keymint-V1",
+        "android.hardware.security.secureclock-V1",
+        "android.hardware.security.sharedsecret-V1",
     ],
     unstable: true,
     backend: {
         java: {
-            sdk_version: "module_current",
+            platform_apis: true,
+            srcs_available: true,
         },
         rust: {
             enabled: true,
         },
         ndk: {
             enabled: true,
-        }
+            apps_enabled: false,
+        },
     },
 }
 
@@ -97,17 +110,17 @@
     name: "android.security.remoteprovisioning",
     srcs: [ "android/security/remoteprovisioning/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint",
+        "android.hardware.security.keymint-V1",
     ],
     unstable: true,
     backend: {
         java: {
-            enabled: true,
-            sdk_version: "module_current",
             platform_apis: true,
+            srcs_available: true,
         },
         ndk: {
             enabled: true,
+            apps_enabled: false,
         },
         rust: {
             enabled: true,
@@ -116,21 +129,65 @@
 }
 
 aidl_interface {
-    name: "android.security.usermanager",
-    srcs: [ "android/security/usermanager/*.aidl" ],
+    name: "android.security.maintenance",
+    srcs: [ "android/security/maintenance/*.aidl" ],
     imports: [
-        "android.system.keystore2",
+        "android.system.keystore2-V1",
     ],
     unstable: true,
     backend: {
         java: {
-            sdk_version: "module_current",
+            platform_apis: true,
+            srcs_available: true,
         },
         rust: {
             enabled: true,
         },
         ndk: {
             enabled: true,
+            apps_enabled: false,
         }
     },
 }
+
+aidl_interface {
+    name: "android.security.legacykeystore",
+    srcs: [ "android/security/legacykeystore/*.aidl" ],
+    unstable: true,
+    backend: {
+        java: {
+            platform_apis: true,
+            srcs_available: true,
+        },
+        rust: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        }
+    },
+}
+
+aidl_interface {
+    name: "android.security.metrics",
+    srcs: [ "android/security/metrics/*.aidl" ],
+    imports: [
+        "android.system.keystore2-V1",
+    ],
+    unstable: true,
+    backend: {
+        java: {
+            platform_apis: true,
+            srcs_available: true,
+        },
+        rust: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+            apps_enabled: false,
+        }
+    },
+}
+
diff --git a/keystore2/aidl/android/security/apc/IConfirmationCallback.aidl b/keystore2/aidl/android/security/apc/IConfirmationCallback.aidl
index f47d7f5..277b9dd 100644
--- a/keystore2/aidl/android/security/apc/IConfirmationCallback.aidl
+++ b/keystore2/aidl/android/security/apc/IConfirmationCallback.aidl
@@ -21,6 +21,7 @@
 /**
  * This callback interface must be implemented by the client to receive the result of the user
  * confirmation.
+ * @hide
  */
 interface IConfirmationCallback {
     /**
diff --git a/keystore2/aidl/android/security/apc/IProtectedConfirmation.aidl b/keystore2/aidl/android/security/apc/IProtectedConfirmation.aidl
index 26ccf0f..3162224 100644
--- a/keystore2/aidl/android/security/apc/IProtectedConfirmation.aidl
+++ b/keystore2/aidl/android/security/apc/IProtectedConfirmation.aidl
@@ -18,6 +18,7 @@
 
 import android.security.apc.IConfirmationCallback;
 
+/** @hide */
 interface IProtectedConfirmation {
 
     /**
diff --git a/keystore2/aidl/android/security/apc/ResponseCode.aidl b/keystore2/aidl/android/security/apc/ResponseCode.aidl
index 7ae3e1c..9a3619f 100644
--- a/keystore2/aidl/android/security/apc/ResponseCode.aidl
+++ b/keystore2/aidl/android/security/apc/ResponseCode.aidl
@@ -19,6 +19,7 @@
 /**
  * Used as service specific exception code by IProtectedConfirmation and as result
  * code by IConfirmationCallback
+ * @hide
  */
 @Backing(type="int")
 enum ResponseCode {
diff --git a/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl b/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl
index a1592ec..dc37b1b 100644
--- a/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl
+++ b/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl
@@ -18,7 +18,6 @@
 
 /**
  * Simple data holder for a byte array, allowing for multidimensional arrays in AIDL.
- *
  * @hide
  */
 parcelable ByteArray {
diff --git a/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl b/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl
index 85eee57..e77a21e 100644
--- a/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl
+++ b/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl
@@ -21,7 +21,6 @@
 
 /**
  * Internal interface for performing device attestation.
- *
  * @hide
  */
 interface IAttestationManager {
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
index df64401..3f33431 100644
--- a/keystore2/aidl/android/security/authorization/IKeystoreAuthorization.aidl
+++ b/keystore2/aidl/android/security/authorization/IKeystoreAuthorization.aidl
@@ -16,15 +16,17 @@
 
 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.
@@ -45,6 +47,8 @@
      * ## 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.
@@ -53,7 +57,60 @@
      * @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 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
index 877a916..c7553a2 100644
--- a/keystore2/aidl/android/security/authorization/LockScreenEvent.aidl
+++ b/keystore2/aidl/android/security/authorization/LockScreenEvent.aidl
@@ -14,6 +14,7 @@
 
 package android.security.authorization;
 
+/** @hide */
 @Backing(type="int")
 enum LockScreenEvent {
     UNLOCK = 0,
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
index 4b6a93b..50bfa19 100644
--- a/keystore2/aidl/android/security/compat/IKeystoreCompatService.aidl
+++ b/keystore2/aidl/android/security/compat/IKeystoreCompatService.aidl
@@ -25,6 +25,7 @@
  * 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 {
     /**
diff --git a/keystore2/aidl/android/security/legacykeystore/ILegacyKeystore.aidl b/keystore2/aidl/android/security/legacykeystore/ILegacyKeystore.aidl
new file mode 100644
index 0000000..fe93673
--- /dev/null
+++ b/keystore2/aidl/android/security/legacykeystore/ILegacyKeystore.aidl
@@ -0,0 +1,98 @@
+/*
+ * 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.legacykeystore;
+
+/**
+ * Internal interface for accessing and storing legacy keystore blobs.
+ * Before Android S, Keystore offered a key-value store that was intended for storing
+ * data associated with certain types of keys. E.g., public certificates for asymmetric keys.
+ * This key value store no longer exists as part of the Keystore 2.0 protocol.
+ * However, there are some clients that used Keystore in an unintended way.
+ * This interface exists to give these clients a grace period to migrate their keys
+ * out of legacy keystore. In Android S, this legacy keystore may be used as keystore was
+ * used in earlier versions, and provides access to entries that were put into keystore
+ * before Android S.
+ *
+ * DEPRECATION NOTICE: In Android T, the `put` function is slated to be removed.
+ * This will allow clients to use the `get`, `list`, and `remove` API to migrate blobs out
+ * of legacy keystore.
+ * @hide
+ */
+interface ILegacyKeystore {
+
+    /**
+     * Special value indicating the callers uid.
+     */
+    const int UID_SELF = -1;
+
+    /**
+     * Service specific error code indicating that an unexpected system error occurred.
+     */
+    const int ERROR_SYSTEM_ERROR = 4;
+
+    /**
+     * Service specific error code indicating that the caller does not have the
+     * right to access the requested uid.
+     */
+    const int ERROR_PERMISSION_DENIED = 6;
+
+    /**
+     * Service specific error code indicating that the entry was not found.
+     */
+    const int ERROR_ENTRY_NOT_FOUND = 7;
+
+    /**
+     * Returns the blob stored under the given name.
+     *
+     * @param alias name of the blob entry.
+     * @param uid designates the legacy namespace. Specify UID_SELF for the caller's namespace.
+     * @return The unstructured blob that was passed as blob parameter into put()
+     */
+    byte[] get(in String alias, int uid);
+
+    /**
+     * Stores one entry as unstructured blob under the given alias.
+     * Overwrites existing entries with the same alias.
+     *
+     * @param alias name of the new entry.
+     * @param uid designates the legacy namespace. Specify UID_SELF for the caller's namespace.
+     * @param blob the payload of the new entry.
+     *
+     * IMPORTANT DEPRECATION NOTICE: This function is slated to be removed in Android T.
+     *     Do not add new callers. The remaining functionality will remain for the purpose
+     *     of migrating legacy configuration out.
+     */
+    void put(in String alias, int uid, in byte[] blob);
+
+    /**
+     * Deletes the entry under the given alias.
+     *
+     * @param alias name of the entry to be removed.
+     * @param uid designates the legacy namespace of the entry. Specify UID_SELF for the caller's
+     *            namespace.
+     */
+    void remove(in String alias, int uid);
+
+    /**
+     * Returns a list of aliases of entries stored. The list is filtered by prefix.
+     * The resulting strings are the full aliases including the prefix.
+     *
+     * @param prefix used to filter results.
+     * @param uid legacy namespace to list. Specify UID_SELF for caller's namespace.
+     */
+    String[] list(in String prefix, int uid);
+}
diff --git a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
new file mode 100644
index 0000000..6a37c78
--- /dev/null
+++ b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
@@ -0,0 +1,134 @@
+// 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);
+
+    /**
+     * Deletes all keys in all hardware keystores.  Used when keystore is reset completely.  After
+     * this function is called all keys with Tag::ROLLBACK_RESISTANCE in their hardware-enforced
+     * authorization lists must be rendered permanently unusable.  Keys without
+     * Tag::ROLLBACK_RESISTANCE may or may not be rendered unusable.
+     */
+    void deleteAllKeys();
+}
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/metrics/Algorithm.aidl b/keystore2/aidl/android/security/metrics/Algorithm.aidl
new file mode 100644
index 0000000..8e8d107
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/Algorithm.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.metrics;
+
+/**
+ * Algorithm enum as defined in stats/enums/system/security/keystore2/enums.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum Algorithm {
+    /** ALGORITHM is prepended because UNSPECIFIED exists in other enums as well. */
+    ALGORITHM_UNSPECIFIED = 0,
+
+    /** Asymmetric algorithms. */
+    RSA = 1,
+
+    /** 2 removed, do not reuse. */
+    EC = 3,
+
+    /** Block cipher algorithms. */
+    AES = 32,
+    TRIPLE_DES = 33,
+
+    /** MAC algorithms. */
+    HMAC = 128,
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/AtomID.aidl b/keystore2/aidl/android/security/metrics/AtomID.aidl
new file mode 100644
index 0000000..166e753
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/AtomID.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.metrics;
+
+/**
+ * Atom IDs as defined in frameworks/proto_logging/stats/atoms.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum AtomID {
+    STORAGE_STATS = 10103,
+    RKP_POOL_STATS = 10104,
+    KEY_CREATION_WITH_GENERAL_INFO = 10118,
+    KEY_CREATION_WITH_AUTH_INFO = 10119,
+    KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO = 10120,
+    KEYSTORE2_ATOM_WITH_OVERFLOW = 10121,
+    KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO = 10122,
+    KEY_OPERATION_WITH_GENERAL_INFO = 10123,
+    RKP_ERROR_STATS = 10124,
+    CRASH_STATS = 10125,
+}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl b/keystore2/aidl/android/security/metrics/CrashStats.aidl
similarity index 69%
rename from keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl
rename to keystore2/aidl/android/security/metrics/CrashStats.aidl
index b42e3d4..8ca043b 100644
--- a/keystore/binder/android/security/keystore/ICredstoreTokenCallback.aidl
+++ b/keystore2/aidl/android/security/metrics/CrashStats.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2020, The Android Open Source Project
+/*
+ * 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.
@@ -14,12 +14,10 @@
  * limitations under the License.
  */
 
-package android.security.keystore;
+package android.security.metrics;
 
-
-/**
- * @hide
- */
-oneway interface ICredstoreTokenCallback {
-	void onFinished(boolean success, in byte[] authToken, in byte[] verificationToken);
-}
+/** @hide */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable CrashStats {
+    int count_of_crash_events;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/EcCurve.aidl b/keystore2/aidl/android/security/metrics/EcCurve.aidl
new file mode 100644
index 0000000..b190d83
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/EcCurve.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics;
+
+/**
+ * EcCurve enum as defined in Keystore2KeyCreationWithGeneralInfo of
+ * frameworks/proto_logging/stats/atoms.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum EcCurve {
+    /** Unspecified takes 0. Other values are incremented by 1 compared to the keymint spec. */
+    EC_CURVE_UNSPECIFIED = 0,
+    P_224 = 1,
+    P_256 = 2,
+    P_384 = 3,
+    P_521 = 4,
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/HardwareAuthenticatorType.aidl b/keystore2/aidl/android/security/metrics/HardwareAuthenticatorType.aidl
new file mode 100644
index 0000000..b13f6ea
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/HardwareAuthenticatorType.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics;
+
+/**
+ * HardwareAuthenticatorType enum as defined in Keystore2KeyCreationWithAuthInfo of
+ * frameworks/proto_logging/stats/atoms.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum HardwareAuthenticatorType {
+    /** Unspecified takes 0. Other values are incremented by 1 compared to keymint spec. */
+    AUTH_TYPE_UNSPECIFIED = 0,
+    NONE = 1,
+    PASSWORD = 2,
+    FINGERPRINT = 3,
+    ANY = 5,
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/IKeystoreMetrics.aidl b/keystore2/aidl/android/security/metrics/IKeystoreMetrics.aidl
new file mode 100644
index 0000000..342cf01
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/IKeystoreMetrics.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.KeystoreAtom;
+import android.security.metrics.AtomID;
+
+/**
+ * IKeystoreMetrics interface exposes the method for system server to pull metrics from keystore.
+ * @hide
+ */
+interface IKeystoreMetrics {
+    /**
+     * Allows the metrics routing proxy to pull the metrics from keystore.
+     *
+     * @return an array of KeystoreAtom objects with the atomID. There can be multiple atom objects
+     * for the same atomID, encapsulating different combinations of values for the atom fields.
+     * If there is no atom object found for the atomID in the metrics store, an empty array is
+     * returned.
+     *
+     * Callers require 'PullMetrics' permission.
+     *
+     * @param atomID - ID of the atom to be pulled.
+     *
+     * Errors are reported as service specific errors.
+     */
+    KeystoreAtom[] pullMetrics(in AtomID atomID);
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/KeyCreationWithAuthInfo.aidl b/keystore2/aidl/android/security/metrics/KeyCreationWithAuthInfo.aidl
new file mode 100644
index 0000000..ff200bc
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/KeyCreationWithAuthInfo.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.HardwareAuthenticatorType;
+import android.security.metrics.SecurityLevel;
+
+/**
+ * Atom that encapsulates authentication related information in key creation events.
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable KeyCreationWithAuthInfo {
+    HardwareAuthenticatorType user_auth_type;
+    /**
+     * Base 10 logarithm of time out in seconds.
+     * Logarithm is taken in order to reduce the cardinaltiy.
+     */
+    int log10_auth_key_timeout_seconds;
+    SecurityLevel security_level;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/KeyCreationWithGeneralInfo.aidl b/keystore2/aidl/android/security/metrics/KeyCreationWithGeneralInfo.aidl
new file mode 100644
index 0000000..74cd9ef
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/KeyCreationWithGeneralInfo.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.Algorithm;
+import android.security.metrics.EcCurve;
+import android.security.metrics.KeyOrigin;
+
+/**
+ * Atom that encapsulates a set of general information in key creation events.
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable KeyCreationWithGeneralInfo {
+    Algorithm algorithm;
+    int key_size;
+    EcCurve ec_curve;
+    KeyOrigin key_origin;
+    int error_code;
+    boolean attestation_requested = false;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/KeyCreationWithPurposeAndModesInfo.aidl b/keystore2/aidl/android/security/metrics/KeyCreationWithPurposeAndModesInfo.aidl
new file mode 100644
index 0000000..dda61c4
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/KeyCreationWithPurposeAndModesInfo.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.Algorithm;
+
+/**
+ * Atom that encapsulates the repeated fields in key creation events.
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable KeyCreationWithPurposeAndModesInfo {
+    Algorithm algorithm;
+    int purpose_bitmap;
+    int padding_mode_bitmap;
+    int digest_bitmap;
+    int block_mode_bitmap;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/KeyOperationWithGeneralInfo.aidl b/keystore2/aidl/android/security/metrics/KeyOperationWithGeneralInfo.aidl
new file mode 100644
index 0000000..d70aaf3
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/KeyOperationWithGeneralInfo.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.Outcome;
+import android.security.metrics.SecurityLevel;
+
+/**
+ * Atom that encapsulates a set of general information in key operation events.
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable KeyOperationWithGeneralInfo {
+    Outcome outcome;
+    int error_code;
+    boolean key_upgraded;
+    SecurityLevel security_level;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/KeyOperationWithPurposeAndModesInfo.aidl b/keystore2/aidl/android/security/metrics/KeyOperationWithPurposeAndModesInfo.aidl
new file mode 100644
index 0000000..e3769e1
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/KeyOperationWithPurposeAndModesInfo.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.Purpose;
+
+/**
+ * Atom that encapsulates the purpose, padding mode, digest and block mode fields in key operations.
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable KeyOperationWithPurposeAndModesInfo {
+    Purpose purpose;
+    int padding_mode_bitmap;
+    int digest_bitmap;
+    int block_mode_bitmap;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/KeyOrigin.aidl b/keystore2/aidl/android/security/metrics/KeyOrigin.aidl
new file mode 100644
index 0000000..b472bc3
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/KeyOrigin.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.metrics;
+
+/**
+ * KeyOrigin enum as defined in Keystore2KeyCreationWithGeneralInfo of
+ * frameworks/proto_logging/stats/atoms.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum KeyOrigin {
+    /** Unspecified takes 0. Other values are incremented by 1 compared to keymint spec. */
+    ORIGIN_UNSPECIFIED = 0,
+
+    /** Generated in KeyMint.  Should not exist outside the TEE. */
+    GENERATED = 1,
+
+    /** Derived inside KeyMint.  Likely exists off-device. */
+    DERIVED = 2,
+
+    /** Imported into KeyMint.  Existed as cleartext in Android. */
+    IMPORTED = 3,
+
+    /** Previously used for another purpose that is now obsolete. */
+    RESERVED = 4,
+
+    /** Securely imported into KeyMint. */
+    SECURELY_IMPORTED = 5,
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/Keystore2AtomWithOverflow.aidl b/keystore2/aidl/android/security/metrics/Keystore2AtomWithOverflow.aidl
new file mode 100644
index 0000000..f2ac399
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/Keystore2AtomWithOverflow.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.AtomID;
+
+/**
+ * Logs the atom id of the atoms associated with key creation/operation events, that have reached
+ * the maximum storage limit allocated for different atom objects of that atom,
+ * in keystore in-memory store.
+ *
+ * Size of the storage bucket for each atom is limited considering their expected cardinaltity.
+ * This limit may exceed if the dimensions of the atoms take a large number of unexpected
+ * combinations. This atom is used to track such cases.
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable Keystore2AtomWithOverflow {
+    AtomID atom_id;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/KeystoreAtom.aidl b/keystore2/aidl/android/security/metrics/KeystoreAtom.aidl
new file mode 100644
index 0000000..266267a
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/KeystoreAtom.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.KeystoreAtomPayload;
+
+/**
+ * Encapsulates a particular atom object of type KeystoreAtomPayload its count. Note that
+ * the field: count is only relevant for the atom types that are stored in the
+ * in-memory metrics store. E.g. count field is not relevant for the atom types such as StorageStats
+ * and RkpPoolStats that are not stored in the metrics store.
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable KeystoreAtom {
+    KeystoreAtomPayload payload;
+    int count;
+}
diff --git a/keystore2/aidl/android/security/metrics/KeystoreAtomPayload.aidl b/keystore2/aidl/android/security/metrics/KeystoreAtomPayload.aidl
new file mode 100644
index 0000000..a3e4dd6
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/KeystoreAtomPayload.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.KeyCreationWithGeneralInfo;
+import android.security.metrics.KeyCreationWithPurposeAndModesInfo;
+import android.security.metrics.KeyCreationWithAuthInfo;
+import android.security.metrics.KeyOperationWithGeneralInfo;
+import android.security.metrics.KeyOperationWithPurposeAndModesInfo;
+import android.security.metrics.StorageStats;
+import android.security.metrics.Keystore2AtomWithOverflow;
+import android.security.metrics.RkpErrorStats;
+import android.security.metrics.RkpPoolStats;
+import android.security.metrics.CrashStats;
+
+/** @hide */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+union KeystoreAtomPayload {
+    StorageStats storageStats;
+    RkpPoolStats rkpPoolStats;
+    KeyCreationWithGeneralInfo keyCreationWithGeneralInfo;
+    KeyCreationWithAuthInfo keyCreationWithAuthInfo;
+    KeyCreationWithPurposeAndModesInfo keyCreationWithPurposeAndModesInfo;
+    Keystore2AtomWithOverflow keystore2AtomWithOverflow;
+    KeyOperationWithPurposeAndModesInfo keyOperationWithPurposeAndModesInfo;
+    KeyOperationWithGeneralInfo keyOperationWithGeneralInfo;
+    RkpErrorStats rkpErrorStats;
+    CrashStats crashStats;
+}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl b/keystore2/aidl/android/security/metrics/Outcome.aidl
similarity index 61%
copy from keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
copy to keystore2/aidl/android/security/metrics/Outcome.aidl
index e1f0ffe..006548b 100644
--- a/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
+++ b/keystore2/aidl/android/security/metrics/Outcome.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2018, The Android Open Source Project
+/*
+ * 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.
@@ -14,14 +14,19 @@
  * limitations under the License.
  */
 
-package android.security.keystore;
-
-import android.security.keystore.KeystoreResponse;
-import android.security.keymaster.KeyCharacteristics;
+package android.security.metrics;
 
 /**
+ * Outcome enum as defined in Keystore2KeyOperationWithGeneralInfo of
+ * frameworks/proto_logging/stats/atoms.proto.
  * @hide
  */
-oneway interface IKeystoreKeyCharacteristicsCallback {
-	void onFinished(in KeystoreResponse response, in KeyCharacteristics charactersistics);
+@Backing(type="int")
+enum Outcome {
+    OUTCOME_UNSPECIFIED = 0,
+    DROPPED = 1,
+    SUCCESS = 2,
+    ABORT = 3,
+    PRUNED = 4,
+    ERROR = 5,
 }
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl b/keystore2/aidl/android/security/metrics/PoolStatus.aidl
similarity index 64%
rename from keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
rename to keystore2/aidl/android/security/metrics/PoolStatus.aidl
index e42e927..3530163 100644
--- a/keystore/binder/android/security/keystore/IKeystoreExportKeyCallback.aidl
+++ b/keystore2/aidl/android/security/metrics/PoolStatus.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2018, The Android Open Source Project
+/*
+ * 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.
@@ -14,14 +14,17 @@
  * limitations under the License.
  */
 
-package android.security.keystore;
-
-import android.security.keystore.KeystoreResponse;
-import android.security.keymaster.ExportResult;
+package android.security.metrics;
 
 /**
+ * Status of the remotely provisioned keys, as defined in RkpPoolStats of
+ * frameworks/proto_logging/stats/atoms.proto.
  * @hide
  */
-oneway interface IKeystoreExportKeyCallback {
-	void onFinished(in ExportResult result);
+@Backing(type="int")
+enum PoolStatus {
+    EXPIRING = 1,
+    UNASSIGNED = 2,
+    ATTESTED = 3,
+    TOTAL = 4,
 }
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/Purpose.aidl b/keystore2/aidl/android/security/metrics/Purpose.aidl
new file mode 100644
index 0000000..f003cea
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/Purpose.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.metrics;
+
+/**
+ * Purpose enum as defined in Keystore2KeyOperationWithPurposeAndModesInfo of
+ * frameworks/proto_logging/stats/atoms.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum Purpose {
+    /** Unspecified takes 0. Other values are incremented by 1 compared to keymint spec. */
+    KEY_PURPOSE_UNSPECIFIED = 0,
+
+    /** Usable with RSA, 3DES and AES keys. */
+    ENCRYPT = 1,
+
+    /** Usable with RSA, 3DES and AES keys. */
+    DECRYPT = 2,
+
+    /** Usable with RSA, EC and HMAC keys. */
+    SIGN = 3,
+
+    /** Usable with RSA, EC and HMAC keys. */
+    VERIFY = 4,
+
+    /** 4 is reserved */
+
+    /** Usable with RSA keys. */
+    WRAP_KEY = 6,
+
+    /** Key Agreement, usable with EC keys. */
+    AGREE_KEY = 7,
+
+    /**
+     * Usable as an attestation signing key.  Keys with this purpose must not have any other
+     * purpose.
+     */
+    ATTEST_KEY = 8,
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/RkpError.aidl b/keystore2/aidl/android/security/metrics/RkpError.aidl
new file mode 100644
index 0000000..c33703d
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/RkpError.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics;
+
+/**
+ * KeyOrigin enum as defined in RkpErrorStats of frameworks/proto_logging/stats/atoms.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum RkpError {
+    RKP_ERROR_UNSPECIFIED = 0,
+
+    /** The key pool is out of keys. */
+    OUT_OF_KEYS = 1,
+
+    /** Falling back to factory provisioned keys during hybrid mode. */
+    FALL_BACK_DURING_HYBRID = 2,
+}
\ No newline at end of file
diff --git a/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl b/keystore2/aidl/android/security/metrics/RkpErrorStats.aidl
similarity index 62%
rename from keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
rename to keystore2/aidl/android/security/metrics/RkpErrorStats.aidl
index e1f0ffe..616d129 100644
--- a/keystore/binder/android/security/keystore/IKeystoreKeyCharacteristicsCallback.aidl
+++ b/keystore2/aidl/android/security/metrics/RkpErrorStats.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2018, The Android Open Source Project
+/*
+ * 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.
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package android.security.keystore;
+package android.security.metrics;
 
-import android.security.keystore.KeystoreResponse;
-import android.security.keymaster.KeyCharacteristics;
-
+import android.security.metrics.RkpError;
 /**
+ * Atom that encapsulates error information in remote key provisioning events.
  * @hide
  */
-oneway interface IKeystoreKeyCharacteristicsCallback {
-	void onFinished(in KeystoreResponse response, in KeyCharacteristics charactersistics);
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable RkpErrorStats {
+    RkpError rkpError;
 }
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/RkpPoolStats.aidl b/keystore2/aidl/android/security/metrics/RkpPoolStats.aidl
new file mode 100644
index 0000000..016b6ff
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/RkpPoolStats.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.SecurityLevel;
+
+/**
+ * Count of keys in the attestation key pool related to Remote Key Provisioning (RKP).
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable RkpPoolStats {
+    SecurityLevel security_level;
+    int expiring;
+    int unassigned;
+    int attested;
+    int total;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/SecurityLevel.aidl b/keystore2/aidl/android/security/metrics/SecurityLevel.aidl
new file mode 100644
index 0000000..f627be2
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/SecurityLevel.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.metrics;
+
+/**
+ * SecurityLevel enum as defined in stats/enums/system/security/keystore2/enums.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum SecurityLevel {
+    /** Unspecified takes 0. Other values are incremented by 1 compared to keymint spec. */
+    SECURITY_LEVEL_UNSPECIFIED = 0,
+    SECURITY_LEVEL_SOFTWARE = 1,
+    SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 2,
+    SECURITY_LEVEL_STRONGBOX = 3,
+    SECURITY_LEVEL_KEYSTORE = 4,
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/Storage.aidl b/keystore2/aidl/android/security/metrics/Storage.aidl
new file mode 100644
index 0000000..1ba6e1f
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/Storage.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.metrics;
+
+/**
+ * Storage enum as defined in Keystore2StorageStats of frameworks/proto_logging/stats/atoms.proto.
+ * @hide
+ */
+@Backing(type="int")
+enum Storage {
+    STORAGE_UNSPECIFIED = 0,
+    KEY_ENTRY = 1,
+    KEY_ENTRY_ID_INDEX = 2,
+    KEY_ENTRY_DOMAIN_NAMESPACE_INDEX = 3,
+    BLOB_ENTRY = 4,
+    BLOB_ENTRY_KEY_ENTRY_ID_INDEX = 5,
+    KEY_PARAMETER = 6,
+    KEY_PARAMETER_KEY_ENTRY_ID_INDEX = 7,
+    KEY_METADATA = 8,
+    KEY_METADATA_KEY_ENTRY_ID_INDEX = 9,
+    GRANT = 10,
+    AUTH_TOKEN = 11,
+    BLOB_METADATA = 12,
+    BLOB_METADATA_BLOB_ENTRY_ID_INDEX =13,
+    METADATA = 14,
+    DATABASE = 15,
+    LEGACY_STORAGE = 16,
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/metrics/StorageStats.aidl b/keystore2/aidl/android/security/metrics/StorageStats.aidl
new file mode 100644
index 0000000..6822e86
--- /dev/null
+++ b/keystore2/aidl/android/security/metrics/StorageStats.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.metrics;
+
+import android.security.metrics.Storage;
+
+/**
+ * Atom that encapsulates a set of general information in key creation events.
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable StorageStats {
+    Storage storage_type;
+    int size;
+    int unused_size;
+}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
index 0d4c30f..ecdc790 100644
--- a/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
+++ b/keystore2/aidl/android/security/remoteprovisioning/IRemoteProvisioning.aidl
@@ -16,9 +16,11 @@
 
 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;
+import android.security.remoteprovisioning.ImplInfo;
 
 /**
  * `IRemoteProvisioning` is the interface provided to use the remote provisioning functionality
@@ -90,7 +92,7 @@
      *                         request.
      */
     byte[] generateCsr(in boolean testMode, in int numCsr, in byte[] eek, in byte[] challenge,
-        in SecurityLevel secLevel, out ProtectedData protectedData);
+        in SecurityLevel secLevel, out ProtectedData protectedData, out DeviceInfo deviceInfo);
 
     /**
      * This method provides a way for the returned attestation certificate chains to be provisioned
@@ -126,11 +128,21 @@
     void generateKeyPair(in boolean is_test_mode, in SecurityLevel secLevel);
 
     /**
-     * This method returns the SecurityLevels of whichever instances of
+     * This method returns implementation information for 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.
+     * know which KM instances it should be generating and managing attestation keys for, and which
+     * EC curves are supported in those instances.
      *
-     * @return The array of security levels.
+     * @return The array of ImplInfo parcelables.
      */
-     SecurityLevel[] getSecurityLevels();
+     ImplInfo[] getImplementationInfo();
+
+    /**
+     * 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/ImplInfo.aidl b/keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl
new file mode 100644
index 0000000..9baeb24
--- /dev/null
+++ b/keystore2/aidl/android/security/remoteprovisioning/ImplInfo.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.remoteprovisioning;
+
+import android.hardware.security.keymint.SecurityLevel;
+
+/**
+ * This parcelable provides information about the underlying IRemotelyProvisionedComponent
+ * implementation.
+ * @hide
+ */
+parcelable ImplInfo {
+    /**
+     * The security level of the underlying implementation: TEE or StrongBox.
+     */
+    SecurityLevel secLevel;
+    /**
+     * An integer denoting which EC curve is supported in the underlying implementation. The current
+     * options are either P256 or 25519, with values defined in
+     * hardware/interfaces/security/keymint/aidl/.../RpcHardwareInfo.aidl
+     */
+    int supportedCurve;
+}
diff --git a/keystore2/aidl/android/security/usermanager/IKeystoreUserManager.aidl b/keystore2/aidl/android/security/usermanager/IKeystoreUserManager.aidl
deleted file mode 100644
index 83edb1a..0000000
--- a/keystore2/aidl/android/security/usermanager/IKeystoreUserManager.aidl
+++ /dev/null
@@ -1,78 +0,0 @@
-// 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.usermanager;
-
-import android.system.keystore2.Domain;
-
-// TODO: mark the interface with @SensitiveData when the annotation is ready (b/176110256).
-
-/**
- * IKeystoreUserManager interface exposes the methods for adding/removing users and changing the
- * user's password.
- * @hide
- */
-interface IKeystoreUserManager {
-
-    /**
-     * 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
-     * @hide
-     */
-    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
-     * @hide
-     */
-    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 do 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
-     * @hide
-     */
-    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.
-     * @hide
-     */
-     void clearNamespace(Domain domain, long nspace);
-}
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
index 9519c8e..df7521e 100644
--- a/keystore2/apc_compat/Android.bp
+++ b/keystore2/apc_compat/Android.bp
@@ -41,12 +41,12 @@
     source_stem: "bindings",
 
     bindgen_flags: [
-        "--whitelist-function=tryGetUserConfirmationService",
-        "--whitelist-function=promptUserConfirmation",
-        "--whitelist-function=abortUserConfirmation",
-        "--whitelist-function=closeUserConfirmationService",
-        "--whitelist-var=INVALID_SERVICE_HANDLE",
-        "--whitelist-var=APC_COMPAT_.*",
+        "--allowlist-function=tryGetUserConfirmationService",
+        "--allowlist-function=promptUserConfirmation",
+        "--allowlist-function=abortUserConfirmation",
+        "--allowlist-function=closeUserConfirmationService",
+        "--allowlist-var=INVALID_SERVICE_HANDLE",
+        "--allowlist-var=APC_COMPAT_.*",
     ],
 }
 
@@ -63,3 +63,13 @@
         "libkeystore2_apc_compat",
     ],
 }
+
+rust_test {
+    name: "libkeystore2_apc_compat_bindgen_test",
+    srcs: [":libkeystore2_apc_compat_bindgen"],
+    crate_name: "keystore2_apc_compat_bindgen_test",
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    clippy_lints: "none",
+    lints: "none",
+}
diff --git a/keystore2/keystore2.rc b/keystore2/keystore2.rc
index c5fc72a..82bf3b8 100644
--- a/keystore2/keystore2.rc
+++ b/keystore2/keystore2.rc
@@ -6,15 +6,8 @@
 #
 # See system/core/init/README.md for information on the init.rc language.
 
-# Start Keystore 2 conditionally
-# TODO b/171563717 Remove when Keystore 2 migration is complete.
-on nonencrypted && property:persist.android.security.keystore2.enable=true
-    enable keystore2
-
 service keystore2 /system/bin/keystore2 /data/misc/keystore
-    class main
+    class early_hal
     user keystore
     group keystore readproc log
     writepid /dev/cpuset/foreground/tasks
-    # TODO b/171563717 Remove when Keystore 2 migration is complete.
-    disabled
diff --git a/keystore2/legacykeystore/Android.bp b/keystore2/legacykeystore/Android.bp
new file mode 100644
index 0000000..da6aa8a
--- /dev/null
+++ b/keystore2/legacykeystore/Android.bp
@@ -0,0 +1,59 @@
+// 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: "liblegacykeystore-rust",
+    crate_name: "legacykeystore",
+    srcs: [
+        "lib.rs",
+    ],
+    rustlibs: [
+        "android.security.legacykeystore-rust",
+        "libanyhow",
+        "libbinder_rs",
+        "libkeystore2",
+        "liblog_rust",
+        "librusqlite",
+        "librustutils",
+        "libthiserror",
+    ],
+}
+
+rust_test {
+    name: "legacykeystore_test",
+    crate_name: "legacykeystore",
+    srcs: ["lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    rustlibs: [
+        "android.security.legacykeystore-rust",
+        "libanyhow",
+        "libbinder_rs",
+        "libkeystore2",
+        "libkeystore2_test_utils",
+        "liblog_rust",
+        "librusqlite",
+        "librustutils",
+        "libthiserror",
+    ],
+}
diff --git a/keystore2/legacykeystore/TEST_MAPPING b/keystore2/legacykeystore/TEST_MAPPING
new file mode 100644
index 0000000..37d1439
--- /dev/null
+++ b/keystore2/legacykeystore/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "legacykeystore_test"
+    }
+  ]
+}
diff --git a/keystore2/legacykeystore/lib.rs b/keystore2/legacykeystore/lib.rs
new file mode 100644
index 0000000..da60297
--- /dev/null
+++ b/keystore2/legacykeystore/lib.rs
@@ -0,0 +1,724 @@
+// 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.legacykeystore interface.
+
+use android_security_legacykeystore::aidl::android::security::legacykeystore::{
+    ILegacyKeystore::BnLegacyKeystore, ILegacyKeystore::ILegacyKeystore,
+    ILegacyKeystore::ERROR_ENTRY_NOT_FOUND, ILegacyKeystore::ERROR_PERMISSION_DENIED,
+    ILegacyKeystore::ERROR_SYSTEM_ERROR, ILegacyKeystore::UID_SELF,
+};
+use android_security_legacykeystore::binder::{
+    BinderFeatures, ExceptionCode, Result as BinderResult, Status as BinderStatus, Strong,
+    ThreadState,
+};
+use anyhow::{Context, Result};
+use keystore2::{
+    async_task::AsyncTask, legacy_blob::LegacyBlobLoader, maintenance::DeleteListener,
+    maintenance::Domain, utils::watchdog as wd,
+};
+use rusqlite::{
+    params, Connection, OptionalExtension, Transaction, TransactionBehavior, NO_PARAMS,
+};
+use std::sync::Arc;
+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.")?,
+        };
+
+        db.init_tables().context("Trying to initialize legacy keystore 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, entry: &[u8]) -> Result<()> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "INSERT OR REPLACE INTO profiles (owner, alias, profile) values (?, ?, ?)",
+                params![caller_uid, alias, entry,],
+            )
+            .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 entry.")
+        })
+    }
+
+    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)
+    }
+
+    fn remove_uid(&mut self, uid: u32) -> Result<()> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute("DELETE FROM profiles WHERE owner = ?;", params![uid])
+                .context("In remove_uid: Failed to delete.")
+        })?;
+        Ok(())
+    }
+
+    fn remove_user(&mut self, user_id: u32) -> Result<()> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            tx.execute(
+                "DELETE FROM profiles WHERE cast ( ( owner/? ) as int) = ?;",
+                params![rustutils::users::AID_USER_OFFSET, user_id],
+            )
+            .context("In remove_uid: Failed to delete.")
+        })?;
+        Ok(())
+    }
+}
+
+/// This is the main LegacyKeystore error type, it wraps binder exceptions and the
+/// LegacyKeystore errors.
+#[derive(Debug, thiserror::Error, PartialEq)]
+pub enum Error {
+    /// Wraps a LegacyKeystore 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_ENTRY_NOT_FOUND)`
+    pub fn not_found() -> Self {
+        Error::Error(ERROR_ENTRY_NOT_FOUND)
+    }
+
+    /// Short hand for `Error::Error(ERROR_PERMISSION_DENIED)`
+    pub fn perm() -> Self {
+        Error::Error(ERROR_PERMISSION_DENIED)
+    }
+}
+
+/// This function should be used by legacykeystore service calls to translate error conditions
+/// into service specific exceptions.
+///
+/// All error conditions get logged by this function, except for ERROR_ENTRY_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 entry not found errors silent.
+                Some(Error::Error(ERROR_ENTRY_NOT_FOUND)) => (ERROR_ENTRY_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,
+    )
+}
+
+struct LegacyKeystoreDeleteListener {
+    legacy_keystore: Arc<LegacyKeystore>,
+}
+
+impl DeleteListener for LegacyKeystoreDeleteListener {
+    fn delete_namespace(&self, domain: Domain, namespace: i64) -> Result<()> {
+        self.legacy_keystore.delete_namespace(domain, namespace)
+    }
+    fn delete_user(&self, user_id: u32) -> Result<()> {
+        self.legacy_keystore.delete_user(user_id)
+    }
+}
+
+/// Implements ILegacyKeystore AIDL interface.
+pub struct LegacyKeystore {
+    db_path: PathBuf,
+    async_task: AsyncTask,
+}
+
+struct AsyncState {
+    recently_imported: HashSet<(u32, String)>,
+    legacy_loader: LegacyBlobLoader,
+    db_path: PathBuf,
+}
+
+impl LegacyKeystore {
+    /// Note: The filename was chosen before the purpose of this module was extended.
+    ///       It is kept for backward compatibility with early adopters.
+    const LEGACY_KEYSTORE_FILE_NAME: &'static str = "vpnprofilestore.sqlite";
+
+    const WIFI_NAMESPACE: i64 = 102;
+    const AID_WIFI: u32 = 1010;
+
+    /// Creates a new LegacyKeystore instance.
+    pub fn new_native_binder(
+        path: &Path,
+    ) -> (Box<dyn DeleteListener + Send + Sync + 'static>, Strong<dyn ILegacyKeystore>) {
+        let mut db_path = path.to_path_buf();
+        db_path.push(Self::LEGACY_KEYSTORE_FILE_NAME);
+
+        let legacy_keystore = Arc::new(Self { db_path, async_task: Default::default() });
+        legacy_keystore.init_shelf(path);
+        let service = LegacyKeystoreService { legacy_keystore: legacy_keystore.clone() };
+        (
+            Box::new(LegacyKeystoreDeleteListener { legacy_keystore }),
+            BnLegacyKeystore::new_binder(service, BinderFeatures::default()),
+        )
+    }
+
+    fn open_db(&self) -> Result<DB> {
+        DB::new(&self.db_path).context("In open_db: Failed to open db.")
+    }
+
+    fn get_effective_uid(uid: i32) -> Result<u32> {
+        const AID_SYSTEM: u32 = 1000;
+        let calling_uid = ThreadState::get_calling_uid();
+        let uid = uid as u32;
+
+        if uid == UID_SELF as u32 || uid == calling_uid {
+            Ok(calling_uid)
+        } else if calling_uid == AID_SYSTEM && uid == Self::AID_WIFI {
+            // The only exception for legacy reasons is allowing SYSTEM to access
+            // the WIFI namespace.
+            // IMPORTANT: If you attempt to add more exceptions, it means you are adding
+            // more callers to this deprecated feature. DON'T!
+            Ok(Self::AID_WIFI)
+        } else {
+            Err(Error::perm()).with_context(|| {
+                format!("In get_effective_uid: caller: {}, requested uid: {}.", calling_uid, uid)
+            })
+        }
+    }
+
+    fn get(&self, alias: &str, uid: i32) -> Result<Vec<u8>> {
+        let mut db = self.open_db().context("In get.")?;
+        let uid = Self::get_effective_uid(uid).context("In get.")?;
+
+        if let Some(entry) = db.get(uid, alias).context("In get: Trying to load entry from DB.")? {
+            return Ok(entry);
+        }
+        if self.get_legacy(uid, alias).context("In get: Trying to migrate legacy blob.")? {
+            // If we were able to migrate a legacy blob try again.
+            if let Some(entry) =
+                db.get(uid, alias).context("In get: Trying to load entry from DB.")?
+            {
+                return Ok(entry);
+            }
+        }
+        Err(Error::not_found()).context("In get: No such entry.")
+    }
+
+    fn put(&self, alias: &str, uid: i32, entry: &[u8]) -> Result<()> {
+        let uid = Self::get_effective_uid(uid).context("In put.")?;
+        // In order to make sure that we don't have stale legacy entries, make sure they are
+        // migrated before replacing them.
+        let _ = self.get_legacy(uid, alias);
+        let mut db = self.open_db().context("In put.")?;
+        db.put(uid, alias, entry).context("In put: Trying to insert entry into DB.")
+    }
+
+    fn remove(&self, alias: &str, uid: i32) -> Result<()> {
+        let uid = Self::get_effective_uid(uid).context("In remove.")?;
+        let mut db = self.open_db().context("In remove.")?;
+        // In order to make sure that we don't have stale legacy entries, make sure they are
+        // migrated before removing them.
+        let _ = self.get_legacy(uid, alias);
+        let removed =
+            db.remove(uid, alias).context("In remove: Trying to remove entry from DB.")?;
+        if removed {
+            Ok(())
+        } else {
+            Err(Error::not_found()).context("In remove: No such entry.")
+        }
+    }
+
+    fn delete_namespace(&self, domain: Domain, namespace: i64) -> Result<()> {
+        let uid = match domain {
+            Domain::APP => namespace as u32,
+            Domain::SELINUX => {
+                if namespace == Self::WIFI_NAMESPACE {
+                    // Namespace WIFI gets mapped to AID_WIFI.
+                    Self::AID_WIFI
+                } else {
+                    // Nothing to do for any other namespace.
+                    return Ok(());
+                }
+            }
+            _ => return Ok(()),
+        };
+
+        if let Err(e) = self.bulk_delete_uid(uid) {
+            log::warn!("In LegacyKeystore::delete_namespace: {:?}", e);
+        }
+        let mut db = self.open_db().context("In LegacyKeystore::delete_namespace.")?;
+        db.remove_uid(uid).context("In LegacyKeystore::delete_namespace.")
+    }
+
+    fn delete_user(&self, user_id: u32) -> Result<()> {
+        if let Err(e) = self.bulk_delete_user(user_id) {
+            log::warn!("In LegacyKeystore::delete_user: {:?}", e);
+        }
+        let mut db = self.open_db().context("In LegacyKeystore::delete_user.")?;
+        db.remove_user(user_id).context("In LegacyKeystore::delete_user.")
+    }
+
+    fn list(&self, prefix: &str, uid: i32) -> Result<Vec<String>> {
+        let mut db = self.open_db().context("In list.")?;
+        let uid = Self::get_effective_uid(uid).context("In list.")?;
+        let mut result = self.list_legacy(uid).context("In list.")?;
+        result.append(&mut db.list(uid).context("In list: Trying to get list of entries.")?);
+        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(Self::LEGACY_KEYSTORE_FILE_NAME);
+
+            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_legacy_keystore_entries_for_uid(uid)
+                .context("Trying to list legacy keystore entries.")
+        })
+        .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_entry(uid, &alias, &state.legacy_loader, &mut db)
+                    .context("Trying to migrate legacy keystore entries.")?;
+            if migrated {
+                state.recently_imported.insert((uid, alias));
+            }
+            Ok(migrated)
+        })
+        .context("In get_legacy.")
+    }
+
+    fn bulk_delete_uid(&self, uid: u32) -> Result<()> {
+        self.do_serialized(move |state| {
+            let entries = state
+                .legacy_loader
+                .list_legacy_keystore_entries_for_uid(uid)
+                .context("In bulk_delete_uid: Trying to list entries.")?;
+            for alias in entries.iter() {
+                if let Err(e) = state.legacy_loader.remove_legacy_keystore_entry(uid, alias) {
+                    log::warn!("In bulk_delete_uid: Failed to delete legacy entry. {:?}", e);
+                }
+            }
+            Ok(())
+        })
+    }
+
+    fn bulk_delete_user(&self, user_id: u32) -> Result<()> {
+        self.do_serialized(move |state| {
+            let entries = state
+                .legacy_loader
+                .list_legacy_keystore_entries_for_user(user_id)
+                .context("In bulk_delete_user: Trying to list entries.")?;
+            for (uid, entries) in entries.iter() {
+                for alias in entries.iter() {
+                    if let Err(e) = state.legacy_loader.remove_legacy_keystore_entry(*uid, alias) {
+                        log::warn!("In bulk_delete_user: Failed to delete legacy entry. {:?}", e);
+                    }
+                }
+            }
+            Ok(())
+        })
+    }
+
+    fn migrate_one_legacy_entry(
+        uid: u32,
+        alias: &str,
+        legacy_loader: &LegacyBlobLoader,
+        db: &mut DB,
+    ) -> Result<bool> {
+        let blob = legacy_loader
+            .read_legacy_keystore_entry(uid, alias)
+            .context("In migrate_one_legacy_entry: Trying to read legacy keystore entry.")?;
+        if let Some(entry) = blob {
+            db.put(uid, alias, &entry)
+                .context("In migrate_one_legacy_entry: Trying to insert entry into DB.")?;
+            legacy_loader
+                .remove_legacy_keystore_entry(uid, alias)
+                .context("In migrate_one_legacy_entry: Trying to delete legacy keystore entry.")?;
+            Ok(true)
+        } else {
+            Ok(false)
+        }
+    }
+}
+
+struct LegacyKeystoreService {
+    legacy_keystore: Arc<LegacyKeystore>,
+}
+
+impl binder::Interface for LegacyKeystoreService {}
+
+impl ILegacyKeystore for LegacyKeystoreService {
+    fn get(&self, alias: &str, uid: i32) -> BinderResult<Vec<u8>> {
+        let _wp = wd::watch_millis("ILegacyKeystore::get", 500);
+        map_or_log_err(self.legacy_keystore.get(alias, uid), Ok)
+    }
+    fn put(&self, alias: &str, uid: i32, entry: &[u8]) -> BinderResult<()> {
+        let _wp = wd::watch_millis("ILegacyKeystore::put", 500);
+        map_or_log_err(self.legacy_keystore.put(alias, uid, entry), Ok)
+    }
+    fn remove(&self, alias: &str, uid: i32) -> BinderResult<()> {
+        let _wp = wd::watch_millis("ILegacyKeystore::remove", 500);
+        map_or_log_err(self.legacy_keystore.remove(alias, uid), Ok)
+    }
+    fn list(&self, prefix: &str, uid: i32) -> BinderResult<Vec<String>> {
+        let _wp = wd::watch_millis("ILegacyKeystore::list", 500);
+        map_or_log_err(self.legacy_keystore.list(prefix, uid), 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_entry_db() {
+        let test_dir = TempDir::new("entrydb_test_").expect("Failed to create temp dir.");
+        let mut db = DB::new(&test_dir.build().push(LegacyKeystore::LEGACY_KEYSTORE_FILE_NAME))
+            .expect("Failed to open database.");
+
+        // Insert three entries 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 entries.")
+        );
+
+        // There should be no entries for owner 1.
+        assert_eq!(Vec::<String>::new(), db.list(1).expect("Failed to list entries."));
+
+        // Check the content of the three entries.
+        assert_eq!(Some(TEST_BLOB1), db.get(2, "test1").expect("Failed to get entry.").as_deref());
+        assert_eq!(Some(TEST_BLOB2), db.get(2, "test2").expect("Failed to get entry.").as_deref());
+        assert_eq!(Some(TEST_BLOB3), db.get(2, "test3").expect("Failed to get entry.").as_deref());
+
+        // Remove test2 and check and check that it is no longer retrievable.
+        assert!(db.remove(2, "test2").expect("Failed to remove entry."));
+        assert!(db.get(2, "test2").expect("Failed to get entry.").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 entries.")
+        );
+
+        // Put on existing alias replaces it.
+        // Verify test1 is TEST_BLOB1.
+        assert_eq!(Some(TEST_BLOB1), db.get(2, "test1").expect("Failed to get entry.").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 entry.").as_deref());
+    }
+
+    #[test]
+    fn test_delete_uid() {
+        let test_dir = TempDir::new("test_delete_uid_").expect("Failed to create temp dir.");
+        let mut db = DB::new(&test_dir.build().push(LegacyKeystore::LEGACY_KEYSTORE_FILE_NAME))
+            .expect("Failed to open database.");
+
+        // Insert three entries 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(3, "test3", TEST_BLOB3).expect("Failed to insert test3.");
+
+        db.remove_uid(2).expect("Failed to remove uid 2");
+
+        assert_eq!(Vec::<String>::new(), db.list(2).expect("Failed to list entries."));
+
+        assert_eq!(vec!["test3".to_string(),], db.list(3).expect("Failed to list entries."));
+    }
+
+    #[test]
+    fn test_delete_user() {
+        let test_dir = TempDir::new("test_delete_user_").expect("Failed to create temp dir.");
+        let mut db = DB::new(&test_dir.build().push(LegacyKeystore::LEGACY_KEYSTORE_FILE_NAME))
+            .expect("Failed to open database.");
+
+        // Insert three entries for owner 2.
+        db.put(2 + 2 * rustutils::users::AID_USER_OFFSET, "test1", TEST_BLOB1)
+            .expect("Failed to insert test1.");
+        db.put(4 + 2 * rustutils::users::AID_USER_OFFSET, "test2", TEST_BLOB2)
+            .expect("Failed to insert test2.");
+        db.put(3, "test3", TEST_BLOB3).expect("Failed to insert test3.");
+
+        db.remove_user(2).expect("Failed to remove user 2");
+
+        assert_eq!(
+            Vec::<String>::new(),
+            db.list(2 + 2 * rustutils::users::AID_USER_OFFSET).expect("Failed to list entries.")
+        );
+
+        assert_eq!(
+            Vec::<String>::new(),
+            db.list(4 + 2 * rustutils::users::AID_USER_OFFSET).expect("Failed to list entries.")
+        );
+
+        assert_eq!(vec!["test3".to_string(),], db.list(3).expect("Failed to list entries."));
+    }
+
+    #[test]
+    fn concurrent_legacy_keystore_entry_test() -> Result<()> {
+        let temp_dir = Arc::new(
+            TempDir::new("concurrent_legacy_keystore_entry_test_")
+                .expect("Failed to create temp dir."),
+        );
+
+        let db_path = temp_dir.build().push(LegacyKeystore::LEGACY_KEYSTORE_FILE_NAME).to_owned();
+
+        let test_begin = Instant::now();
+
+        let mut db = DB::new(&db_path).expect("Failed to open database.");
+        const ENTRY_COUNT: u32 = 5000u32;
+        const ENTRY_DB_COUNT: u32 = 5000u32;
+
+        let mut actual_entry_count = ENTRY_COUNT;
+        // First insert ENTRY_COUNT entries.
+        for count in 0..ENTRY_COUNT {
+            if Instant::now().duration_since(test_begin) >= Duration::from_secs(15) {
+                actual_entry_count = count;
+                break;
+            }
+            let alias = format!("test_alias_{}", count);
+            db.put(1, &alias, TEST_BLOB1).expect("Failed to add entry (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_entry_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 entry (2).");
+            }
+
+            // Then delete them again.
+            for count in 0..actual_entry_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 entries.
+        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_entry_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 entry.
+        let db_path3 = db_path.clone();
+        let handle3 = thread::spawn(move || {
+            for _count in 0..ENTRY_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 entry (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..ENTRY_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 entry (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/keystore2/selinux/Android.bp b/keystore2/selinux/Android.bp
index 18063d3..254f95e 100644
--- a/keystore2/selinux/Android.bp
+++ b/keystore2/selinux/Android.bp
@@ -34,6 +34,7 @@
 
     rustlibs: [
         "libanyhow",
+        "liblazy_static",
         "liblog_rust",
         "libselinux_bindgen",
         "libthiserror",
@@ -56,8 +57,30 @@
     rustlibs: [
         "libandroid_logger",
         "libanyhow",
+        "liblazy_static",
         "liblog_rust",
         "libselinux_bindgen",
         "libthiserror",
     ],
 }
+
+rust_test {
+    name: "keystore2_selinux_concurrency_test",
+    srcs: [
+        "src/concurrency_test.rs",
+    ],
+    crate_name: "keystore2_selinux_concurrency_test",
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+
+    rustlibs: [
+        "libandroid_logger",
+        "libanyhow",
+        "libkeystore2_selinux",
+        "liblazy_static",
+        "liblog_rust",
+        "libnix",
+        "libnum_cpus",
+        "libthiserror",
+    ],
+}
diff --git a/keystore2/selinux/src/concurrency_test.rs b/keystore2/selinux/src/concurrency_test.rs
new file mode 100644
index 0000000..a5d2df2
--- /dev/null
+++ b/keystore2/selinux/src/concurrency_test.rs
@@ -0,0 +1,190 @@
+// 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.
+
+use keystore2_selinux::{check_access, Context};
+use nix::sched::sched_setaffinity;
+use nix::sched::CpuSet;
+use nix::unistd::getpid;
+use std::thread;
+use std::{
+    sync::{atomic::AtomicU8, atomic::Ordering, Arc},
+    time::{Duration, Instant},
+};
+
+#[derive(Clone, Copy)]
+struct CatCount(u8, u8, u8, u8);
+
+impl CatCount {
+    fn next(&mut self) -> CatCount {
+        let result = *self;
+        if self.3 == 255 {
+            if self.2 == 254 {
+                if self.1 == 253 {
+                    if self.0 == 252 {
+                        self.0 = 255;
+                    }
+                    self.0 += 1;
+                    self.1 = self.0;
+                }
+                self.1 += 1;
+                self.2 = self.1;
+            }
+            self.2 += 1;
+            self.3 = self.2;
+        }
+        self.3 += 1;
+        result
+    }
+
+    fn make_string(&self) -> String {
+        format!("c{},c{},c{},c{}", self.0, self.1, self.2, self.3)
+    }
+}
+
+impl Default for CatCount {
+    fn default() -> Self {
+        Self(0, 1, 2, 3)
+    }
+}
+
+/// This test calls selinux_check_access concurrently causing access vector cache misses
+/// in libselinux avc. The test then checks if any of the threads fails to report back
+/// after a burst of access checks. The purpose of the test is to draw out a specific
+/// access vector cache corruption that sends a calling thread into an infinite loop.
+/// This was observed when keystore2 used libselinux concurrently in a non thread safe
+/// way. See b/184006658.
+#[test]
+fn test_concurrent_check_access() {
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag("keystore2_selinux_concurrency_test")
+            .with_min_level(log::Level::Debug),
+    );
+
+    let cpus = num_cpus::get();
+    let turnpike = Arc::new(AtomicU8::new(0));
+    let complete_count = Arc::new(AtomicU8::new(0));
+    let mut threads: Vec<thread::JoinHandle<()>> = Vec::new();
+
+    for i in 0..cpus {
+        log::info!("Spawning thread {}", i);
+        let turnpike_clone = turnpike.clone();
+        let complete_count_clone = complete_count.clone();
+        threads.push(thread::spawn(move || {
+            let mut cpu_set = CpuSet::new();
+            cpu_set.set(i).unwrap();
+            sched_setaffinity(getpid(), &cpu_set).unwrap();
+            let mut cat_count: CatCount = Default::default();
+
+            log::info!("Thread 0 reached turnpike");
+            loop {
+                turnpike_clone.fetch_add(1, Ordering::Relaxed);
+                loop {
+                    match turnpike_clone.load(Ordering::Relaxed) {
+                        0 => break,
+                        255 => return,
+                        _ => {}
+                    }
+                }
+
+                for _ in 0..250 {
+                    let (tctx, sctx, perm, class) = (
+                        Context::new("u:object_r:keystore:s0").unwrap(),
+                        Context::new(&format!(
+                            "u:r:untrusted_app:s0:{}",
+                            cat_count.next().make_string()
+                        ))
+                        .unwrap(),
+                        "use",
+                        "keystore2_key",
+                    );
+
+                    check_access(&sctx, &tctx, class, perm).unwrap();
+                }
+
+                complete_count_clone.fetch_add(1, Ordering::Relaxed);
+                while complete_count_clone.load(Ordering::Relaxed) as usize != cpus {
+                    thread::sleep(Duration::from_millis(5));
+                }
+            }
+        }));
+    }
+
+    let mut i = 0;
+    let run_time = Instant::now();
+
+    loop {
+        const TEST_ITERATIONS: u32 = 500;
+        const MAX_SLEEPS: u64 = 500;
+        const SLEEP_MILLISECONDS: u64 = 5;
+        let mut sleep_count: u64 = 0;
+        while turnpike.load(Ordering::Relaxed) as usize != cpus {
+            thread::sleep(Duration::from_millis(SLEEP_MILLISECONDS));
+            sleep_count += 1;
+            assert!(
+                sleep_count < MAX_SLEEPS,
+                "Waited too long to go ready on iteration {}, only {} are ready",
+                i,
+                turnpike.load(Ordering::Relaxed)
+            );
+        }
+
+        if i % 100 == 0 {
+            let elapsed = run_time.elapsed().as_secs();
+            println!("{:02}:{:02}: Iteration {}", elapsed / 60, elapsed % 60, i);
+        }
+
+        // Give the threads some time to reach and spin on the turn pike.
+        assert_eq!(turnpike.load(Ordering::Relaxed) as usize, cpus, "i = {}", i);
+        if i >= TEST_ITERATIONS {
+            turnpike.store(255, Ordering::Relaxed);
+            break;
+        }
+
+        // Now go.
+        complete_count.store(0, Ordering::Relaxed);
+        turnpike.store(0, Ordering::Relaxed);
+        i += 1;
+
+        // Wait for them to all complete.
+        sleep_count = 0;
+        while complete_count.load(Ordering::Relaxed) as usize != cpus {
+            thread::sleep(Duration::from_millis(SLEEP_MILLISECONDS));
+            sleep_count += 1;
+            if sleep_count >= MAX_SLEEPS {
+                // Enable the following block to park the thread to allow attaching a debugger.
+                if false {
+                    println!(
+                        "Waited {} seconds and we seem stuck. Going to sleep forever.",
+                        (MAX_SLEEPS * SLEEP_MILLISECONDS) as f32 / 1000.0
+                    );
+                    loop {
+                        thread::park();
+                    }
+                } else {
+                    assert!(
+                        sleep_count < MAX_SLEEPS,
+                        "Waited too long to complete on iteration {}, only {} are complete",
+                        i,
+                        complete_count.load(Ordering::Relaxed)
+                    );
+                }
+            }
+        }
+    }
+
+    for t in threads {
+        t.join().unwrap();
+    }
+}
diff --git a/keystore2/selinux/src/lib.rs b/keystore2/selinux/src/lib.rs
index 2b5091d..cf6dfd3 100644
--- a/keystore2/selinux/src/lib.rs
+++ b/keystore2/selinux/src/lib.rs
@@ -20,6 +20,13 @@
 //!  * selabel_lookup for the keystore2_key backend.
 //! And it provides an owning wrapper around context strings `Context`.
 
+use anyhow::Context as AnyhowContext;
+use anyhow::{anyhow, Result};
+use lazy_static::lazy_static;
+pub use selinux::pid_t;
+use selinux::SELABEL_CTX_ANDROID_KEYSTORE2_KEY;
+use selinux::SELINUX_CB_LOG;
+use selinux_bindgen as selinux;
 use std::ffi::{CStr, CString};
 use std::fmt;
 use std::io;
@@ -29,18 +36,18 @@
 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();
 
+lazy_static! {
+    /// `selinux_check_access` is only thread safe if avc_init was called with lock callbacks.
+    /// However, avc_init is deprecated and not exported by androids version of libselinux.
+    /// `selinux_set_callbacks` does not allow setting lock callbacks. So the only option
+    /// that remains right now is to put a big lock around calls into libselinux.
+    /// TODO b/188079221 It should suffice to protect `selinux_check_access` but until we are
+    /// certain of that, we leave the extra locks in place
+    static ref LIB_SELINUX_LOCK: sync::Mutex<()> = Default::default();
+}
+
 fn redirect_selinux_logs_to_logcat() {
     // `selinux_set_callback` assigns the static lifetime function pointer
     // `selinux_log_callback` to a static lifetime variable.
@@ -123,7 +130,7 @@
     fn deref(&self) -> &Self::Target {
         match self {
             Self::Raw(p) => unsafe { CStr::from_ptr(*p) },
-            Self::CString(cstr) => &cstr,
+            Self::CString(cstr) => cstr,
         }
     }
 }
@@ -164,6 +171,8 @@
     /// `selinux_android_keystore2_key_context_handle`.
     pub fn new() -> Result<Self> {
         init_logger_once();
+        let _lock = LIB_SELINUX_LOCK.lock().unwrap();
+
         let handle = unsafe { selinux::selinux_android_keystore2_key_context_handle() };
         if handle.is_null() {
             return Err(anyhow!(Error::sys("Failed to open KeystoreKeyBackend")));
@@ -192,6 +201,8 @@
         match unsafe {
             // No need to initialize the logger here because it cannot run unless
             // KeystoreKeyBackend::new has run.
+            let _lock = LIB_SELINUX_LOCK.lock().unwrap();
+
             selinux::selabel_lookup(self.handle, &mut con, c_key.as_ptr(), Self::BACKEND_TYPE)
         } {
             0 => {
@@ -219,6 +230,8 @@
 ///  * Err(io::Error::last_os_error()) if getcon failed.
 pub fn getcon() -> Result<Context> {
     init_logger_once();
+    let _lock = LIB_SELINUX_LOCK.lock().unwrap();
+
     let mut con: *mut c_char = ptr::null_mut();
     match unsafe { selinux::getcon(&mut con) } {
         0 => {
@@ -241,6 +254,8 @@
 ///  * Err(io::Error::last_os_error()) if getpidcon failed.
 pub fn getpidcon(pid: selinux::pid_t) -> Result<Context> {
     init_logger_once();
+    let _lock = LIB_SELINUX_LOCK.lock().unwrap();
+
     let mut con: *mut c_char = ptr::null_mut();
     match unsafe { selinux::getpidcon(pid, &mut con) } {
         0 => {
@@ -267,6 +282,7 @@
 ///            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)
     })?;
@@ -275,6 +291,8 @@
     })?;
 
     match unsafe {
+        let _lock = LIB_SELINUX_LOCK.lock().unwrap();
+
         selinux::selinux_check_access(
             source.as_ptr(),
             target.as_ptr(),
@@ -455,7 +473,6 @@
 
         check_keystore_perm!(add_auth);
         check_keystore_perm!(clear_ns);
-        check_keystore_perm!(get_state);
         check_keystore_perm!(lock);
         check_keystore_perm!(reset);
         check_keystore_perm!(unlock);
diff --git a/keystore2/src/apc.rs b/keystore2/src/apc.rs
index 767014e..0096686 100644
--- a/keystore2/src/apc.rs
+++ b/keystore2/src/apc.rs
@@ -21,17 +21,17 @@
     sync::{mpsc::Sender, Arc, Mutex},
 };
 
-use crate::utils::{compat_2_response_code, ui_opts_2_compat};
+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::{
-    ExceptionCode, Interface, Result as BinderResult, SpIBinder, Status as BinderStatus, Strong,
+    BinderFeatures, ExceptionCode, Interface, Result as BinderResult, SpIBinder,
+    Status as BinderStatus, Strong, ThreadState,
 };
 use anyhow::{Context, Result};
-use binder::{IBinder, ThreadState};
 use keystore2_apc_compat::ApcHal;
 use keystore2_selinux as selinux;
 use std::time::{Duration, Instant};
@@ -203,11 +203,10 @@
     pub fn new_native_binder(
         confirmation_token_sender: Sender<Vec<u8>>,
     ) -> Result<Strong<dyn IProtectedConfirmation>> {
-        let result = BnProtectedConfirmation::new_binder(Self {
-            state: Arc::new(Mutex::new(ApcState::new(confirmation_token_sender))),
-        });
-        result.as_binder().set_requesting_sid(true);
-        Ok(result)
+        Ok(BnProtectedConfirmation::new_binder(
+            Self { state: Arc::new(Mutex::new(ApcState::new(confirmation_token_sender))) },
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        ))
     }
 
     fn result(
@@ -268,7 +267,7 @@
 
     fn present_prompt(
         &self,
-        listener: &dyn IConfirmationCallback,
+        listener: &binder::Strong<dyn IConfirmationCallback>,
         prompt_text: &str,
         extra_data: &[u8],
         locale: &str,
@@ -327,7 +326,7 @@
         Ok(())
     }
 
-    fn cancel_prompt(&self, listener: &dyn IConfirmationCallback) -> Result<()> {
+    fn cancel_prompt(&self, listener: &binder::Strong<dyn IConfirmationCallback>) -> Result<()> {
         let mut state = self.state.lock().unwrap();
         let hal = match &mut state.session {
             None => {
@@ -358,21 +357,28 @@
 impl IProtectedConfirmation for ApcManager {
     fn presentPrompt(
         &self,
-        listener: &dyn IConfirmationCallback,
+        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: &dyn IConfirmationCallback) -> BinderResult<()> {
+    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
index 9732e79..0515c8f 100644
--- a/keystore2/src/async_task.rs
+++ b/keystore2/src/async_task.rs
@@ -89,8 +89,10 @@
 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>,
@@ -107,25 +109,32 @@
 
 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,
                 }),
             )),
         }
     }
-}
 
-impl AsyncTask {
-    /// Adds a 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.
+    /// 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,
@@ -133,10 +142,10 @@
         self.queue(f, true)
     }
 
-    /// Adds a 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.
+    /// 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,
@@ -144,12 +153,24 @@
         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 {
@@ -169,42 +190,345 @@
         }
 
         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(f) = {
-                    let (mut state, timeout) = condvar
-                        .wait_timeout_while(
-                            state.lock().unwrap(),
-                            Duration::from_secs(30),
-                            |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(f),
-                        (None, false, _) => state.lo_prio_req.pop_front(),
-                        (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;
+                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,
                         }
-                        (None, true, false) => None,
                     }
                 } {
-                    f(&mut shelf)
+                    // 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();
+        // Now that the last low-priority job has completed, the idle task should
+        // fire pretty much immediately.
+        idle_done_receiver.recv_timeout(Duration::from_millis(50)).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(50)).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..b6a8e31
--- /dev/null
+++ b/keystore2/src/attestation_key_utils.rs
@@ -0,0 +1,128 @@
+// 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, Tag::Tag,
+};
+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 if a challenge is present. Alternatively, 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>> {
+    let challenge_present = params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE);
+    match attest_key_descriptor {
+        None if challenge_present => 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 }
+                })
+            }),
+        None => Ok(None),
+        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..3d7d26e
--- /dev/null
+++ b/keystore2/src/audit_log.rs
@@ -0,0 +1,86 @@
+// 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 TAG_KEY_INTEGRITY_VIOLATION: u32 = 210032;
+
+const FLAG_NAMESPACE: i64 = 0x80000000;
+
+/// Encode key owner as either uid or namespace with a flag.
+fn key_owner(domain: Domain, nspace: i64, uid: i32) -> i32 {
+    match domain {
+        Domain::APP => uid,
+        Domain::SELINUX => (nspace | FLAG_NAMESPACE) 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);
+}
+
+/// Logs key integrity violation to NIAP audit log.
+pub fn log_key_integrity_violation(key: &KeyDescriptor) {
+    with_log_context(TAG_KEY_INTEGRITY_VIOLATION, |ctx| {
+        let owner = key_owner(key.domain, key.nspace, key.nspace as i32);
+        ctx.append_str(key.alias.as_ref().map_or("none", String::as_str)).append_i32(owner)
+    })
+}
+
+fn log_key_event(tag: u32, key: &KeyDescriptor, calling_app: uid_t, success: bool) {
+    with_log_context(tag, |ctx| {
+        let owner = key_owner(key.domain, key.nspace, calling_app as i32);
+        ctx.append_i32(if success { 1 } else { 0 })
+            .append_str(key.alias.as_ref().map_or("none", String::as_str))
+            .append_i32(owner)
+    })
+}
+
+fn with_log_context<F>(tag: u32, f: F)
+where
+    F: Fn(LogContext) -> LogContext,
+{
+    if let Some(ctx) = LogContext::new(LogIdSecurity, tag) {
+        let event = f(ctx);
+        LOGS_HANDLER.queue_lo(move |_| {
+            event.write();
+        });
+    }
+}
diff --git a/keystore2/src/authorization.rs b/keystore2/src/authorization.rs
index 02b19c4..777089f 100644
--- a/keystore2/src/authorization.rs
+++ b/keystore2/src/authorization.rs
@@ -15,22 +15,94 @@
 //! This module implements IKeystoreAuthorization AIDL interface.
 
 use crate::error::Error as KeystoreError;
-use crate::error::map_or_log_err;
 use crate::globals::{ENFORCEMENTS, SUPER_KEY, DB, LEGACY_MIGRATOR};
 use crate::permission::KeystorePerm;
 use crate::super_key::UserState;
-use crate::utils::check_keystore_permission;
+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::{Interface, Result as BinderResult, Strong};
-use android_security_authorization::aidl::android::security::authorization::IKeystoreAuthorization::{
-        BnKeystoreAuthorization, IKeystoreAuthorization,
+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_security_authorization:: aidl::android::security::authorization::LockScreenEvent::LockScreenEvent;
-use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
+use android_system_keystore2::aidl::android::system::keystore2::{
+    ResponseCode::ResponseCode as KsResponseCode };
 use anyhow::{Context, Result};
-use binder::IBinder;
+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.
@@ -39,16 +111,17 @@
 impl AuthorizationManager {
     /// Create a new instance of Keystore Authorization service.
     pub fn new_native_binder() -> Result<Strong<dyn IKeystoreAuthorization>> {
-        let result = BnKeystoreAuthorization::new_binder(Self);
-        result.as_binder().set_requesting_sid(true);
-        Ok(result)
+        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.
         check_keystore_permission(KeystorePerm::add_auth()).context("In add_auth_token.")?;
 
-        ENFORCEMENTS.add_auth_token(auth_token.clone())?;
+        ENFORCEMENTS.add_auth_token(auth_token.clone());
         Ok(())
     }
 
@@ -56,15 +129,33 @@
         &self,
         lock_screen_event: LockScreenEvent,
         user_id: i32,
-        password: Option<&[u8]>,
+        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(user_password)) => {
-                //This corresponds to the unlock() method in legacy keystore API.
-                //check permission
+            (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| {
@@ -73,7 +164,7 @@
                             &LEGACY_MIGRATOR,
                             &SUPER_KEY,
                             user_id as u32,
-                            user_password,
+                            &password,
                         )
                     })
                     .context("In on_lock_screen_event: Unlock with password.")?
@@ -89,27 +180,61 @@
                 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(KeystoreError::Rc(ResponseCode::INVALID_ARGUMENT))
+                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)
     }
 
@@ -118,7 +243,37 @@
         lock_screen_event: LockScreenEvent,
         user_id: i32,
         password: Option<&[u8]>,
+        unlocking_sids: Option<&[i64]>,
     ) -> BinderResult<()> {
-        map_or_log_err(self.on_lock_screen_event(lock_screen_event, user_id, password), Ok)
+        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..08c52af
--- /dev/null
+++ b/keystore2/src/boot_level_keys.rs
@@ -0,0 +1,284 @@
+// 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 crate::{
+    database::{KeyType, KeystoreDB},
+    key_parameter::KeyParameterValue,
+    raw_device::KeyMintDevice,
+};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, Digest::Digest, KeyParameter::KeyParameter as KmKeyParameter,
+    KeyParameterValue::KeyParameterValue as KmKeyParameterValue, KeyPurpose::KeyPurpose,
+    SecurityLevel::SecurityLevel, Tag::Tag,
+};
+use anyhow::{Context, Result};
+use keystore2_crypto::{hkdf_expand, ZVec, AES_256_KEY_LENGTH};
+use std::{collections::VecDeque, convert::TryFrom};
+
+fn get_preferred_km_instance_for_level_zero_key() -> Result<KeyMintDevice> {
+    let tee = KeyMintDevice::get(SecurityLevel::TRUSTED_ENVIRONMENT)
+        .context("In get_preferred_km_instance_for_level_zero_key: Get TEE instance failed.")?;
+    if tee.version() >= KeyMintDevice::KEY_MASTER_V4_1 {
+        Ok(tee)
+    } else {
+        match KeyMintDevice::get_or_none(SecurityLevel::STRONGBOX).context(
+            "In get_preferred_km_instance_for_level_zero_key: Get Strongbox instance failed.",
+        )? {
+            Some(strongbox) if strongbox.version() >= KeyMintDevice::KEY_MASTER_V4_1 => {
+                Ok(strongbox)
+            }
+            _ => Ok(tee),
+        }
+    }
+}
+
+/// 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 km_dev = get_preferred_km_instance_for_level_zero_key()
+        .context("In get_level_zero_key: get preferred KM instance failed")?;
+
+    let key_desc = KeyMintDevice::internal_descriptor("boot_level_key".to_string());
+    let mut params = vec![
+        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(),
+    ];
+
+    let has_early_boot_only = km_dev.version() >= KeyMintDevice::KEY_MASTER_V4_1;
+
+    if has_early_boot_only {
+        params.push(KeyParameterValue::EarlyBootOnly.into());
+    } else {
+        params.push(KeyParameterValue::MaxUsesPerBoot(1).into())
+    }
+
+    let (key_id_guard, key_entry) = km_dev
+        .lookup_or_generate_key(db, &key_desc, KeyType::Client, &params, |key_characteristics| {
+            key_characteristics.iter().any(|kc| {
+                if kc.securityLevel == km_dev.security_level() {
+                    kc.authorizations.iter().any(|a| {
+                        matches!(
+                            (has_early_boot_only, a),
+                            (
+                                true,
+                                KmKeyParameter {
+                                    tag: Tag::EARLY_BOOT_ONLY,
+                                    value: KmKeyParameterValue::BoolValue(true)
+                                }
+                            ) | (
+                                false,
+                                KmKeyParameter {
+                                    tag: Tag::MAX_USES_PER_BOOT,
+                                    value: KmKeyParameterValue::Integer(1)
+                                }
+                            )
+                        )
+                    })
+                } else {
+                    false
+                }
+            })
+        })
+        .context("In get_level_zero_key: lookup_or_generate_key failed")?;
+
+    let params = [
+        KeyParameterValue::MacLength(256).into(),
+        KeyParameterValue::Digest(Digest::SHA_2_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!(blkc.level_accessible(0));
+        assert!(blkc.level_accessible(9));
+        assert!(blkc.level_accessible(10));
+        assert!(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!(!blkc.level_accessible(0));
+        assert!(blkc.level_accessible(9));
+        assert!(blkc.level_accessible(10));
+        assert!(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!(!blkc.level_accessible(0));
+        assert!(!blkc.level_accessible(9));
+        assert!(blkc.level_accessible(10));
+        assert!(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!(!blkc.level_accessible(0));
+        assert!(!blkc.level_accessible(9));
+        assert!(blkc.level_accessible(10));
+        assert!(blkc.level_accessible(100));
+        assert_eq!(None, blkc.aes_key(0)?);
+        assert_eq!(Some(v10), blkc.aes_key(10)?);
+        blkc.finish();
+        assert!(!blkc.level_accessible(0));
+        assert!(!blkc.level_accessible(9));
+        assert!(!blkc.level_accessible(10));
+        assert!(!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
index e386735..4e76507 100644
--- a/keystore2/src/crypto/Android.bp
+++ b/keystore2/src/crypto/Android.bp
@@ -59,26 +59,27 @@
     shared_libs: ["libcrypto"],
     bindgen_flags: [
         "--size_t-is-usize",
-        "--whitelist-function", "randomBytes",
-        "--whitelist-function", "AES_gcm_encrypt",
-        "--whitelist-function", "AES_gcm_decrypt",
-        "--whitelist-function", "CreateKeyId",
-        "--whitelist-function", "generateKeyFromPassword",
-        "--whitelist-function", "HKDFExtract",
-        "--whitelist-function", "HKDFExpand",
-        "--whitelist-function", "ECDHComputeKey",
-        "--whitelist-function", "ECKEYGenerateKey",
-        "--whitelist-function", "ECKEYDeriveFromSecret",
-        "--whitelist-function", "EC_KEY_get0_public_key",
-        "--whitelist-function", "ECPOINTPoint2Oct",
-        "--whitelist-function", "ECPOINTOct2Point",
-        "--whitelist-function", "EC_KEY_free",
-        "--whitelist-function", "EC_POINT_free",
-        "--whitelist-function", "extractSubjectFromCertificate",
-        "--whitelist-type", "EC_KEY",
-        "--whitelist-type", "EC_POINT",
-        "--whitelist-var", "EC_MAX_BYTES",
-        "--whitelist-var", "EVP_MAX_MD_SIZE",
+        "--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"],
 }
@@ -124,3 +125,13 @@
         "libcrypto",
     ],
 }
+
+rust_test {
+    name: "libkeystore2_crypto_bindgen_test",
+    srcs: [":libkeystore2_crypto_bindgen"],
+    crate_name: "keystore2_crypto_bindgen_test",
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    clippy_lints: "none",
+    lints: "none",
+}
diff --git a/keystore2/src/crypto/certificate_utils.cpp b/keystore2/src/crypto/certificate_utils.cpp
index 31c7fb4..64bf1d0 100644
--- a/keystore2/src/crypto/certificate_utils.cpp
+++ b/keystore2/src/crypto/certificate_utils.cpp
@@ -19,14 +19,18 @@
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/mem.h>
+#include <openssl/ossl_typ.h>
 #include <openssl/x509v3.h>
 
 #include <functional>
 #include <limits>
-#include <string>
 #include <variant>
 #include <vector>
 
+#ifndef __LP64__
+#include <time64.h>
+#endif
+
 namespace keystore {
 
 namespace {
@@ -167,45 +171,42 @@
     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));
-            }
-        }
+// TODO Once boring ssl can take int64_t instead of time_t we can go back to using
+//      ASN1_TIME_set: https://bugs.chromium.org/p/boringssl/issues/detail?id=416
+std::optional<std::array<char, 16>> toTimeString(int64_t timeMillis) {
+    struct tm time;
+    // If timeMillis is negative the rounding direction should still be to the nearest previous
+    // second.
+    if (timeMillis < 0 && __builtin_add_overflow(timeMillis, -999, &timeMillis)) {
+        return std::nullopt;
     }
+#if defined(__LP64__)
+    time_t timeSeconds = timeMillis / 1000;
+    if (gmtime_r(&timeSeconds, &time) == nullptr) {
+        return std::nullopt;
+    }
+#else
+    time64_t timeSeconds = timeMillis / 1000;
+    if (gmtime64_r(&timeSeconds, &time) == nullptr) {
+        return std::nullopt;
+    }
+#endif
+    std::array<char, 16> buffer;
+    if (__builtin_add_overflow(time.tm_year, 1900, &time.tm_year)) {
+        return std::nullopt;
+    }
+    if (time.tm_year >= 1950 && time.tm_year < 2050) {
+        // UTCTime according to RFC5280 4.1.2.5.1.
+        snprintf(buffer.data(), buffer.size(), "%02d%02d%02d%02d%02d%02dZ", time.tm_year % 100,
+                 time.tm_mon + 1, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
+    } else if (time.tm_year >= 0 && time.tm_year < 10000) {
+        // GeneralizedTime according to RFC5280 4.1.2.5.2.
+        snprintf(buffer.data(), buffer.size(), "%04d%02d%02d%02d%02d%02dZ", time.tm_year,
+                 time.tm_mon + 1, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
+    } else {
+        return std::nullopt;
+    }
+    return buffer;
 }
 
 // Creates a rump certificate structure with serial, subject and issuer names, as well as
@@ -259,19 +260,24 @@
         return std::get<CertUtilsError>(subjectName);
     }
 
-    time_t notBeforeTime = saturate<time_t>(activeDateTimeMilliSeconds / 1000);
+    auto notBeforeTime = toTimeString(activeDateTimeMilliSeconds);
+    if (!notBeforeTime) {
+        return CertUtilsError::TimeError;
+    }
     // Set activation date.
     ASN1_TIME_Ptr notBefore(ASN1_TIME_new());
-    if (!notBefore || !ASN1_TIME_set(notBefore.get(), notBeforeTime) ||
+    if (!notBefore || !ASN1_TIME_set_string(notBefore.get(), notBeforeTime->data()) ||
         !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);
+    auto notAfterTime = toTimeString(usageExpireDateTimeMilliSeconds);
+    if (!notAfterTime) {
+        return CertUtilsError::TimeError;
+    }
 
     ASN1_TIME_Ptr notAfter(ASN1_TIME_new());
-    if (!notAfter || !ASN1_TIME_set(notAfter.get(), notAfterTime) ||
+    if (!notAfter || !ASN1_TIME_set_string(notAfter.get(), notAfterTime->data()) ||
         !X509_set_notAfter(certificate.get(), notAfter.get() /* Don't release; copied */)) {
         return CertUtilsError::BoringSsl;
     }
@@ -512,10 +518,7 @@
     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;
-    }
+std::variant<CertUtilsError, X509_ALGOR_Ptr> makeAlgo(Algo algo, Padding padding, Digest digest) {
     ASN1_STRING_Ptr param;
     int param_type = V_ASN1_UNDEF;
     int nid = 0;
@@ -584,23 +587,29 @@
         return CertUtilsError::InvalidArgument;
     }
 
-    if (!X509_ALGOR_set0(algo_field, OBJ_nid2obj(nid), param_type, param.get())) {
+    X509_ALGOR_Ptr result(X509_ALGOR_new());
+    if (!result) {
+        return CertUtilsError::MemoryAllocation;
+    }
+    if (!X509_ALGOR_set0(result.get(), OBJ_nid2obj(nid), param_type, param.get())) {
         return CertUtilsError::Encoding;
     }
     // The X509 struct took ownership.
     param.release();
-    return CertUtilsError::Ok;
+    return result;
 }
 
 // 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;
+    auto algo_objV = makeAlgo(algo, padding, digest);
+    if (auto error = std::get_if<CertUtilsError>(&algo_objV)) {
+        return *error;
     }
-    if (auto error = makeAndSetAlgo(certificate->cert_info->signature, algo, padding, digest)) {
-        return error;
+    auto& algo_obj = std::get<X509_ALGOR_Ptr>(algo_objV);
+    if (!X509_set1_signature_algo(certificate, algo_obj.get())) {
+        return CertUtilsError::BoringSsl;
     }
 
     uint8_t* cert_buf = nullptr;
@@ -615,13 +624,10 @@
         return CertUtilsError::SignatureFailed;
     }
 
-    if (!ASN1_STRING_set(certificate->signature, signature.data(), signature.size())) {
+    if (!X509_set1_signature_value(certificate, signature.data(), signature.size())) {
         return CertUtilsError::BoringSsl;
     }
 
-    certificate->signature->flags &= ~(0x07);
-    certificate->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-
     return CertUtilsError::Ok;
 }
 
diff --git a/keystore2/src/crypto/crypto.cpp b/keystore2/src/crypto/crypto.cpp
index 2e613fd..5d360a1 100644
--- a/keystore2/src/crypto/crypto.cpp
+++ b/keystore2/src/crypto/crypto.cpp
@@ -225,7 +225,7 @@
 
 EC_KEY* ECKEYGenerateKey() {
     EC_KEY* key = EC_KEY_new();
-    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
     EC_KEY_set_group(key, group);
     auto result = EC_KEY_generate_key(key);
     if (result == 0) {
@@ -236,15 +236,33 @@
     return key;
 }
 
-EC_KEY* ECKEYDeriveFromSecret(const uint8_t* secret, size_t secret_len) {
-    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
-    auto result = EC_KEY_derive_from_secret(group, secret, secret_len);
+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_secp521r1);
+    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);
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
     point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
     auto result = EC_POINT_point2oct(group, point, form, buf, len, nullptr);
     EC_GROUP_free(group);
@@ -252,7 +270,7 @@
 }
 
 EC_POINT* ECPOINTOct2Point(const uint8_t* buf, size_t len) {
-    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
     EC_POINT* point = EC_POINT_new(group);
     auto result = EC_POINT_oct2point(group, point, buf, len, nullptr);
     EC_GROUP_free(group);
diff --git a/keystore2/src/crypto/crypto.hpp b/keystore2/src/crypto/crypto.hpp
index 1b8971f..f841eb3 100644
--- a/keystore2/src/crypto/crypto.hpp
+++ b/keystore2/src/crypto/crypto.hpp
@@ -55,7 +55,9 @@
 
   EC_KEY* ECKEYGenerateKey();
 
-  EC_KEY* ECKEYDeriveFromSecret(const uint8_t *secret, size_t secret_len);
+  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);
 
@@ -67,7 +69,7 @@
 // cert_len, extract the subject, DER-encode it and write the result to
 // subject_buf, which has subject_buf_len capacity.
 //
-// Because the length of the issuer is unknown, and becaue we'd like to (a) be
+// 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.
diff --git a/keystore2/src/crypto/error.rs b/keystore2/src/crypto/error.rs
index 1eec321..a369012 100644
--- a/keystore2/src/crypto/error.rs
+++ b/keystore2/src/crypto/error.rs
@@ -74,9 +74,13 @@
     #[error("Failed to generate key.")]
     ECKEYGenerateKeyFailed,
 
-    /// This is returned if the C implementation of ECKEYDeriveFromSecret returned null.
-    #[error("Failed to derive key.")]
-    ECKEYDeriveFailed,
+    /// 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.")]
diff --git a/keystore2/src/crypto/include/certificate_utils.h b/keystore2/src/crypto/include/certificate_utils.h
index 6c25b9a..cad82b6 100644
--- a/keystore2/src/crypto/include/certificate_utils.h
+++ b/keystore2/src/crypto/include/certificate_utils.h
@@ -39,6 +39,7 @@
 DEFINE_OPENSSL_OBJECT_POINTER(ASN1_TIME);
 DEFINE_OPENSSL_OBJECT_POINTER(EVP_PKEY);
 DEFINE_OPENSSL_OBJECT_POINTER(X509);
+DEFINE_OPENSSL_OBJECT_POINTER(X509_ALGOR);
 DEFINE_OPENSSL_OBJECT_POINTER(X509_EXTENSION);
 DEFINE_OPENSSL_OBJECT_POINTER(X509_NAME);
 DEFINE_OPENSSL_OBJECT_POINTER(EVP_PKEY_CTX);
@@ -53,6 +54,7 @@
         InvalidArgument,
         UnexpectedNullPointer,
         SignatureFailed,
+        TimeError,
     };
 
   private:
@@ -137,6 +139,16 @@
 };
 
 /**
+ * Takes an int64_t representing UNIX epoch time in milliseconds and turns it into a UTCTime
+ * or GeneralizedTime string depending on whether the year is in the interval [1950 .. 2050).
+ * Note: The string returned in the array buffer is NUL terminated and of length 13 (UTCTime)
+ * or 15 (GeneralizedTime).
+ * @param timeMillis
+ * @return UTCTime or GeneralizedTime string.
+ */
+std::optional<std::array<char, 16>> toTimeString(int64_t timeMillis);
+
+/**
  * 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
diff --git a/keystore2/src/crypto/lib.rs b/keystore2/src/crypto/lib.rs
index f23778c..5f8a2ef 100644
--- a/keystore2/src/crypto/lib.rs
+++ b/keystore2/src/crypto/lib.rs
@@ -20,9 +20,9 @@
 pub use error::Error;
 use keystore2_crypto_bindgen::{
     extractSubjectFromCertificate, generateKeyFromPassword, randomBytes, AES_gcm_decrypt,
-    AES_gcm_encrypt, ECDHComputeKey, ECKEYDeriveFromSecret, ECKEYGenerateKey, ECPOINTOct2Point,
-    ECPOINTPoint2Oct, EC_KEY_free, EC_KEY_get0_public_key, EC_POINT_free, HKDFExpand, HKDFExtract,
-    EC_KEY, EC_MAX_BYTES, EC_POINT, EVP_MAX_MD_SIZE,
+    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;
@@ -30,7 +30,7 @@
 pub use zvec::ZVec;
 
 /// Length of the expected initialization vector.
-pub const IV_LENGTH: usize = 16;
+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.
@@ -40,9 +40,9 @@
 /// Length of the expected salt for key from password generation.
 pub const SALT_LENGTH: usize = 16;
 
-// This is the number of bytes of the GCM IV that is expected to be initialized
-// with random bytes.
-const GCM_IV_LENGTH: usize = 12;
+/// 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.
@@ -58,10 +58,15 @@
 
 /// Generate a salt.
 pub fn generate_salt() -> Result<Vec<u8>, Error> {
-    // Safety: salt has the same length as the requested number of random bytes.
-    let mut salt = vec![0; SALT_LENGTH];
-    if unsafe { randomBytes(salt.as_mut_ptr(), SALT_LENGTH) } {
-        Ok(salt)
+    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)
     }
@@ -75,10 +80,13 @@
 /// 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> {
-    if iv.len() != IV_LENGTH {
-        return Err(Error::InvalidIvLength);
-    }
-
+    // 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);
     }
@@ -91,8 +99,8 @@
     let mut result = ZVec::new(data.len())?;
 
     // Safety: The first two arguments must point to buffers with a size given by the third
-    // argument. The key must have a size of 16 or 32 bytes which we check above.
-    // The iv and tag arguments must be 16 bytes, which we also check above.
+    // 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(),
@@ -113,10 +121,9 @@
 /// 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(data: &[u8], key: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>), Error> {
-    let mut iv = vec![0; IV_LENGTH];
-    // Safety: iv is longer than GCM_IV_LENGTH, which is 12 while IV_LENGTH is 16.
-    // The iv needs to be 16 bytes long, but the last 4 bytes remain zeroed.
+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);
     }
@@ -126,60 +133,90 @@
         _ => return Err(Error::InvalidKeyLength),
     }
 
-    let mut result: Vec<u8> = vec![0; data.len()];
+    let mut ciphertext: Vec<u8> = vec![0; plaintext.len()];
     let mut tag: Vec<u8> = vec![0; TAG_LENGTH];
-    match unsafe {
+    // 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(
-            data.as_ptr(),
-            result.as_mut_ptr(),
-            data.len(),
+            plaintext.as_ptr(),
+            ciphertext.as_mut_ptr(),
+            plaintext.len(),
             key.as_ptr(),
             key.len(),
             iv.as_ptr(),
             tag.as_mut_ptr(),
         )
     } {
-        true => Ok((result, iv, tag)),
-        false => Err(Error::EncryptionFailed),
+        Ok((ciphertext, iv, tag))
+    } else {
+        Err(Error::EncryptionFailed)
     }
 }
 
-/// Generates 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_from_password(
-    pw: &[u8],
-    salt: Option<&[u8]>,
-    key_length: usize,
-) -> Result<ZVec, Error> {
-    let salt: *const u8 = match salt {
-        Some(s) => {
-            if s.len() != SALT_LENGTH {
-                return Err(Error::InvalidSaltLength);
-            }
-            s.as_ptr()
-        }
-        None => std::ptr::null(),
-    };
+/// 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),
+}
 
-    match key_length {
-        AES_128_KEY_LENGTH | AES_256_KEY_LENGTH => {}
-        _ => return Err(Error::InvalidKeyLength),
+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,
+        }
     }
 
-    let mut result = ZVec::new(key_length)?;
+    /// 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();
 
-    unsafe {
-        generateKeyFromPassword(
-            result.as_mut_ptr(),
-            result.len(),
-            pw.as_ptr() as *const std::os::raw::c_char,
-            pw.len(),
-            salt,
-        )
-    };
+        let salt: *const u8 = match salt {
+            Some(s) => {
+                if s.len() != SALT_LENGTH {
+                    return Err(Error::InvalidSaltLength);
+                }
+                s.as_ptr()
+            }
+            None => std::ptr::null(),
+        };
 
-    Ok(result)
+        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.
@@ -307,14 +344,32 @@
     Ok(ECKey(key))
 }
 
-/// Calls the boringssl EC_KEY_derive_from_secret function.
-pub fn ec_key_derive_from_secret(secret: &[u8]) -> Result<ECKey, Error> {
-    // Safety: secret is a valid buffer.
-    let result = unsafe { ECKEYDeriveFromSecret(secret.as_ptr(), secret.len()) };
-    if result.is_null() {
-        return Err(Error::ECKEYDeriveFailed);
+/// Calls the boringssl EC_KEY_marshal_private_key function.
+pub fn ec_key_marshal_private_key(key: &ECKey) -> Result<ZVec, Error> {
+    let len = 73; // 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)
     }
-    Ok(ECKey(result))
+}
+
+/// 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.
@@ -326,8 +381,8 @@
 
 /// 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;
+    // We fix the length to 133 (1 + 2 * field_elem_size), as we get an error if it's too small.
+    let len = 133;
     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) };
@@ -354,11 +409,13 @@
     Ok(OwnedECPoint(result))
 }
 
-/// Uses BoringSSL to extract the DER-encoded issuer subject from a
-/// DER-encoded X.509 certificate.
-pub fn parse_issuer_subject_from_certificate(cert_buf: &[u8]) -> Result<Vec<u8>, Error> {
+/// 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(),
@@ -374,12 +431,11 @@
 
     if size < 0 {
         // Our buffer wasn't big enough.  Make one that is just the right size and try again.
-        let negated_size = usize::try_from(-size);
-        retval = match negated_size.ok() {
-            None => return Err(Error::ExtractSubjectFailed),
-            Some(size) => vec![0; size],
-        };
+        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(),
@@ -395,14 +451,8 @@
     }
 
     // Reduce buffer size to the amount written.
-    let safe_size = usize::try_from(size);
-    retval.resize(
-        match safe_size.ok() {
-            None => return Err(Error::ExtractSubjectFailed),
-            Some(size) => size,
-        },
-        0,
-    );
+    let safe_size = usize::try_from(size).map_err(|_e| Error::ExtractSubjectFailed)?;
+    retval.truncate(safe_size);
 
     Ok(retval)
 }
@@ -493,26 +543,26 @@
     }
 
     #[test]
-    fn test_ec() {
-        let key = ec_key_generate_key();
-        assert!(key.is_ok());
-        assert!(!key.unwrap().0.is_null());
+    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 key = ec_key_derive_from_secret(&[42; 16]);
-        assert!(key.is_ok());
-        let key = key.unwrap();
-        assert!(!key.0.is_null());
+        let priv1 = ec_key_generate_key()?;
+        let pub1 = ec_key_get0_public_key(&priv1);
 
-        let point = ec_key_get0_public_key(&key);
+        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 result = ecdh_compute_key(point.get_point(), &key);
-        assert!(result.is_ok());
+        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 oct = ec_point_point_to_oct(point.get_point());
-        assert!(oct.is_ok());
-        let oct = oct.unwrap();
+        let left_key = ecdh_compute_key(pub0.get_point(), &priv1)?;
+        let right_key = ecdh_compute_key(pub1.get_point(), &priv0)?;
 
-        let point2 = ec_point_oct_to_point(oct.as_slice());
-        assert!(point2.is_ok());
+        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
index 119c3fa..bd94928 100644
--- a/keystore2/src/crypto/tests/certificate_utils_test.cpp
+++ b/keystore2/src/crypto/tests/certificate_utils_test.cpp
@@ -315,3 +315,23 @@
     EVP_PKEY_Ptr decoded_pkey(X509_get_pubkey(decoded_cert.get()));
     ASSERT_TRUE(X509_verify(decoded_cert.get(), decoded_pkey.get()));
 }
+
+TEST(TimeStringTests, toTimeStringTest) {
+    // Two test vectors that need to result in UTCTime
+    ASSERT_EQ(std::string(toTimeString(1622758591000)->data()), std::string("210603221631Z"));
+    ASSERT_EQ(std::string(toTimeString(0)->data()), std::string("700101000000Z"));
+    // Two test vectors that need to result in GeneralizedTime.
+    ASSERT_EQ(std::string(toTimeString(16227585910000)->data()), std::string("24840325064510Z"));
+    ASSERT_EQ(std::string(toTimeString(-1622758591000)->data()), std::string("19180731014329Z"));
+
+    // Highest possible UTCTime
+    ASSERT_EQ(std::string(toTimeString(2524607999999)->data()), "491231235959Z");
+    // And one millisecond later must be GeneralizedTime.
+    ASSERT_EQ(std::string(toTimeString(2524608000000)->data()), "20500101000000Z");
+
+    // Earliest possible UTCTime
+    ASSERT_EQ(std::string(toTimeString(-631152000000)->data()), "500101000000Z");
+    // And one millisecond earlier must be GeneralizedTime.
+    // This also checks that the rounding direction does not flip when the input is negative.
+    ASSERT_EQ(std::string(toTimeString(-631152000001)->data()), "19491231235959Z");
+}
diff --git a/keystore2/src/crypto/zvec.rs b/keystore2/src/crypto/zvec.rs
index e75e1dc..78b474e 100644
--- a/keystore2/src/crypto/zvec.rs
+++ b/keystore2/src/crypto/zvec.rs
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#![allow(dead_code)]
-
 use crate::error::Error;
 use nix::sys::mman::{mlock, munlock};
 use std::convert::TryFrom;
@@ -106,12 +104,16 @@
 impl TryFrom<Vec<u8>> for ZVec {
     type Error = Error;
 
-    fn try_from(v: Vec<u8>) -> Result<Self, Self::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()) }?;
         }
-        let len = b.len();
         Ok(Self { elems: b, len })
     }
 }
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 40860be..ae2875c 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -41,31 +41,40 @@
 //! from the database module these functions take permission check
 //! callbacks.
 
-use crate::error::{Error as KsError, ErrorCode, ResponseCode};
+mod perboot;
+pub(crate) mod utils;
+mod versioning;
+
 use crate::impl_metadata; // This is in db_utils.rs
 use crate::key_parameter::{KeyParameter, Tag};
+use crate::metrics_store::log_rkp_error_stats;
 use crate::permission::KeyPermSet;
-use crate::utils::{get_current_time_in_seconds, AID_USER_OFFSET};
+use crate::utils::{get_current_time_in_milliseconds, watchdog as wd, AID_USER_OFFSET};
 use crate::{
-    db_utils::{self, SqlField},
-    gc::Gc,
+    error::{Error as KsError, ErrorCode, ResponseCode},
+    super_key::SuperKeyType,
 };
+use crate::{gc::Gc, super_key::USER_SUPER_KEY};
 use anyhow::{anyhow, Context, Result};
 use std::{convert::TryFrom, convert::TryInto, ops::Deref, time::SystemTimeError};
+use utils as db_utils;
+use utils::SqlField;
 
 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 android_security_metrics::aidl::android::security::metrics::{
+    StorageStats::StorageStats,
+    Storage::Storage as MetricsStorage,
+    RkpError::RkpError as MetricsRkpError,
+};
 
 use keystore2_crypto::ZVec;
 use lazy_static::lazy_static;
@@ -73,7 +82,7 @@
 #[cfg(not(test))]
 use rand::prelude::random;
 use rusqlite::{
-    params,
+    params, params_from_iter,
     types::FromSql,
     types::FromSqlResult,
     types::ToSqlOutput,
@@ -84,7 +93,7 @@
 use std::{
     collections::{HashMap, HashSet},
     path::Path,
-    sync::{Condvar, Mutex},
+    sync::{Arc, Condvar, Mutex},
     time::{Duration, SystemTime},
 };
 
@@ -108,6 +117,8 @@
         /// 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.
@@ -131,7 +142,7 @@
             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))
+                KeyMetaEntry::new_from_sql(db_tag, &SqlField::new(1, row))
                     .context("Failed to read KeyMetaEntry.")?,
             );
             Ok(())
@@ -178,6 +189,11 @@
         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.
@@ -201,7 +217,7 @@
             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))
+                BlobMetaEntry::new_from_sql(db_tag, &SqlField::new(1, row))
                     .context("Failed to read BlobMetaEntry.")?,
             );
             Ok(())
@@ -372,12 +388,12 @@
     }
 
     /// Returns unix epoch time in milliseconds.
-    pub fn to_millis_epoch(&self) -> i64 {
+    pub fn to_millis_epoch(self) -> i64 {
         self.0
     }
 
     /// Returns unix epoch time in seconds.
-    pub fn to_secs_epoch(&self) -> i64 {
+    pub fn to_secs_epoch(self) -> i64 {
         self.0 / 1000
     }
 }
@@ -581,11 +597,14 @@
 
 /// 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.
-#[allow(dead_code)]
 pub struct CertificateChain {
-    private_key: ZVec,
-    batch_cert: ZVec,
-    cert_chain: ZVec,
+    /// 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.
@@ -716,23 +735,29 @@
 /// ownership. It also implements all of Keystore 2.0's database functionality.
 pub struct KeystoreDB {
     conn: Connection,
-    gc: Option<Gc>,
+    gc: Option<Arc<Gc>>,
+    perboot: Arc<perboot::PerbootDB>,
 }
 
 /// Database representation of the monotonic time retrieved from the system call clock_gettime with
-/// CLOCK_MONOTONIC_RAW. Stores monotonic time as i64 in seconds.
+/// CLOCK_MONOTONIC_RAW. Stores monotonic time as i64 in milliseconds.
 #[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())
+        Self(get_current_time_in_milliseconds())
+    }
+
+    /// Returns the value of MonotonicRawTime in milliseconds as i64
+    pub fn milliseconds(&self) -> i64 {
+        self.0
     }
 
     /// Returns the integer value of MonotonicRawTime as i64
     pub fn seconds(&self) -> i64 {
-        self.0
+        self.0 / 1000
     }
 
     /// Like i64::checked_sub.
@@ -755,8 +780,10 @@
 
 /// This struct encapsulates the information to be stored in the database about the auth tokens
 /// received by keystore.
+#[derive(Clone)]
 pub struct AuthTokenEntry {
     auth_token: HardwareAuthToken,
+    // Time received in milliseconds
     time_received: MonotonicRawTime,
 }
 
@@ -787,6 +814,11 @@
     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.
@@ -796,47 +828,52 @@
 
 impl KeystoreDB {
     const UNASSIGNED_KEY_ID: i64 = -1i64;
-    const PERBOOT_DB_FILE_NAME: &'static str = &"file:perboot.sqlite?mode=memory&cache=shared";
+    const CURRENT_DB_VERSION: u32 = 1;
+    const UPGRADERS: &'static [fn(&Transaction) -> Result<u32>] = &[Self::from_0_to_1];
 
-    /// The alias of the user super key.
-    pub const USER_SUPER_KEY_ALIAS: &'static str = &"USER_SUPER_KEY";
-
-    /// 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))
-    }
+    /// Name of the file that holds the cross-boot persistent database.
+    pub const PERSISTENT_DB_FILENAME: &'static str = "persistent.sqlite";
 
     /// 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<Gc>) -> Result<Self> {
-        // Build the path to the sqlite file.
-        let mut persistent_path = db_root.to_path_buf();
-        persistent_path.push("persistent.sqlite");
+    pub fn new(db_root: &Path, gc: Option<Arc<Gc>>) -> Result<Self> {
+        let _wp = wd::watch_millis("KeystoreDB::new", 500);
 
-        // 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 persistent_path = Self::make_persistent_path(db_root)?;
+        let conn = Self::make_connection(&persistent_path)?;
 
-        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 };
+        let mut db = Self { conn, gc, perboot: perboot::PERBOOT_DB.clone() };
         db.with_transaction(TransactionBehavior::Immediate, |tx| {
+            versioning::upgrade_database(tx, Self::CURRENT_DB_VERSION, Self::UPGRADERS)
+                .context("In KeystoreDB::new: trying to upgrade database.")?;
             Self::init_tables(tx).context("Trying to initialize tables.").no_gc()
         })?;
         Ok(db)
     }
 
+    // This upgrade function deletes all MAX_BOOT_LEVEL keys, that were generated before
+    // cryptographic binding to the boot level keys was implemented.
+    fn from_0_to_1(tx: &Transaction) -> Result<u32> {
+        tx.execute(
+            "UPDATE persistent.keyentry SET state = ?
+             WHERE
+                 id IN (SELECT keyentryid FROM persistent.keyparameter WHERE tag = ?)
+             AND
+                 id NOT IN (
+                     SELECT keyentryid FROM persistent.blobentry
+                     WHERE id IN (
+                         SELECT blobentryid FROM persistent.blobmetadata WHERE tag = ?
+                     )
+                 );",
+            params![KeyLifeCycle::Unreferenced, Tag::MAX_BOOT_LEVEL.0, BlobMetaData::MaxBootLevel],
+        )
+        .context("In from_0_to_1: Failed to delete logical boot level keys.")?;
+        Ok(1)
+    }
+
     fn init_tables(tx: &Transaction) -> Result<()> {
         tx.execute(
             "CREATE TABLE IF NOT EXISTS persistent.keyentry (
@@ -944,41 +981,22 @@
         )
         .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> {
+    fn make_persistent_path(db_root: &Path) -> Result<String> {
+        // 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());
+
+        Ok(persistent_path_str)
+    }
+
+    fn make_connection(persistent_file: &str) -> Result<Connection> {
         let conn =
             Connection::open_in_memory().context("Failed to initialize SQLite connection.")?;
 
@@ -996,70 +1014,178 @@
             }
             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;
-        }
+
+        // Drop the cache size from default (2M) to 0.5M
+        conn.execute("PRAGMA persistent.cache_size = -500;", params![])
+            .context("Failed to decrease cache size for persistent db")?;
 
         Ok(conn)
     }
 
+    fn do_table_size_query(
+        &mut self,
+        storage_type: MetricsStorage,
+        query: &str,
+        params: &[&str],
+    ) -> Result<StorageStats> {
+        let (total, unused) = self.with_transaction(TransactionBehavior::Deferred, |tx| {
+            tx.query_row(query, params_from_iter(params), |row| Ok((row.get(0)?, row.get(1)?)))
+                .with_context(|| {
+                    format!("get_storage_stat: Error size of storage type {}", storage_type.0)
+                })
+                .no_gc()
+        })?;
+        Ok(StorageStats { storage_type, size: total, unused_size: unused })
+    }
+
+    fn get_total_size(&mut self) -> Result<StorageStats> {
+        self.do_table_size_query(
+            MetricsStorage::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: MetricsStorage,
+        schema: &str,
+        table: &str,
+    ) -> Result<StorageStats> {
+        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: MetricsStorage) -> Result<StorageStats> {
+        let _wp = wd::watch_millis("KeystoreDB::get_storage_stat", 500);
+
+        match storage_type {
+            MetricsStorage::DATABASE => self.get_total_size(),
+            MetricsStorage::KEY_ENTRY => {
+                self.get_table_size(storage_type, "persistent", "keyentry")
+            }
+            MetricsStorage::KEY_ENTRY_ID_INDEX => {
+                self.get_table_size(storage_type, "persistent", "keyentry_id_index")
+            }
+            MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX => {
+                self.get_table_size(storage_type, "persistent", "keyentry_domain_namespace_index")
+            }
+            MetricsStorage::BLOB_ENTRY => {
+                self.get_table_size(storage_type, "persistent", "blobentry")
+            }
+            MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX => {
+                self.get_table_size(storage_type, "persistent", "blobentry_keyentryid_index")
+            }
+            MetricsStorage::KEY_PARAMETER => {
+                self.get_table_size(storage_type, "persistent", "keyparameter")
+            }
+            MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX => {
+                self.get_table_size(storage_type, "persistent", "keyparameter_keyentryid_index")
+            }
+            MetricsStorage::KEY_METADATA => {
+                self.get_table_size(storage_type, "persistent", "keymetadata")
+            }
+            MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX => {
+                self.get_table_size(storage_type, "persistent", "keymetadata_keyentryid_index")
+            }
+            MetricsStorage::GRANT => self.get_table_size(storage_type, "persistent", "grant"),
+            MetricsStorage::AUTH_TOKEN => {
+                // Since the table is actually a BTreeMap now, unused_size is not meaningfully
+                // reportable
+                // Size provided is only an approximation
+                Ok(StorageStats {
+                    storage_type,
+                    size: (self.perboot.auth_tokens_len() * std::mem::size_of::<AuthTokenEntry>())
+                        as i32,
+                    unused_size: 0,
+                })
+            }
+            MetricsStorage::BLOB_METADATA => {
+                self.get_table_size(storage_type, "persistent", "blobmetadata")
+            }
+            MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX => {
+                self.get_table_size(storage_type, "persistent", "blobmetadata_blobentryid_index")
+            }
+            _ => Err(anyhow::Error::msg(format!("Unsupported storage type: {}", storage_type.0))),
+        }
+    }
+
     /// This function is intended to be used by the garbage collector.
-    /// It deletes the blob given by `blob_id_to_delete`. It then tries to find a superseded
-    /// key blob that might need special handling 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_blob(
+    pub fn handle_next_superseded_blobs(
         &mut self,
-        blob_id_to_delete: Option<i64>,
-    ) -> Result<Option<(i64, Vec<u8>, BlobMetaData)>> {
+        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 blob if one was given.
-            if let Some(blob_id_to_delete) = blob_id_to_delete {
+            // Delete the given blobs.
+            for blob_id in blob_ids_to_delete {
                 tx.execute(
                     "DELETE FROM persistent.blobmetadata WHERE blobentryid = ?;",
-                    params![blob_id_to_delete],
+                    params![blob_id],
                 )
                 .context("Trying to delete blob metadata.")?;
-                tx.execute(
-                    "DELETE FROM persistent.blobentry WHERE id = ?;",
-                    params![blob_id_to_delete],
-                )
-                .context("Trying to blob.")?;
+                tx.execute("DELETE FROM persistent.blobentry WHERE id = ?;", params![blob_id])
+                    .context("Trying to blob.")?;
             }
 
-            // Find another superseded keyblob load its metadata and return it.
-            if let Some((blob_id, blob)) = tx
-                .query_row(
-                    "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)
-                 );",
-                    params![SubComponentType::KEY_BLOB, SubComponentType::KEY_BLOB],
-                    |row| Ok((row.get(0)?, row.get(1)?)),
-                )
-                .optional()
-                .context("Trying to query superseded blob.")?
-            {
-                let blob_metadata = BlobMetaData::load_from_db(blob_id, tx)
-                    .context("Trying to load blob metadata.")?;
-                return Ok(Some((blob_id, blob, blob_metadata))).no_gc();
+            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
@@ -1078,9 +1204,9 @@
             )
             .context("Trying to purge superseded blobs.")?;
 
-            Ok(None).no_gc()
+            Ok(vec![]).no_gc()
         })
-        .context("In handle_next_superseded_blob.")
+        .context("In handle_next_superseded_blobs.")
     }
 
     /// This maintenance function should be called only once before the database is used for the
@@ -1092,6 +1218,8 @@
     /// 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 = ?;",
@@ -1111,10 +1239,12 @@
         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);
+            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>() {
@@ -1131,8 +1261,13 @@
     pub fn store_super_key(
         &mut self,
         user_id: u32,
-        blob_info: &(&[u8], &BlobMetaData),
+        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(
@@ -1144,7 +1279,7 @@
                         KeyType::Super,
                         Domain::APP.0,
                         user_id as i64,
-                        Self::USER_SUPER_KEY_ALIAS,
+                        key_type.alias,
                         KeyLifeCycle::Live,
                         &KEYSTORE_UUID,
                     ],
@@ -1152,9 +1287,10 @@
             })
             .context("Failed to insert into keyentry table.")?;
 
-            let (blob, blob_metadata) = *blob_info;
+            key_metadata.store_in_db(key_id, tx).context("KeyMetaData::store_in_db failed")?;
+
             Self::set_blob_internal(
-                &tx,
+                tx,
                 key_id,
                 SubComponentType::KEY_BLOB,
                 Some(blob),
@@ -1170,18 +1306,24 @@
     }
 
     /// Loads super key of a given user, if exists
-    pub fn load_super_key(&mut self, user_id: u32) -> Result<Option<(KeyIdGuard, KeyEntry)>> {
+    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(String::from("USER_SUPER_KEY")),
+                alias: Some(key_type.alias.into()),
                 blob: None,
             };
-            let id = Self::load_key_entry_id(&tx, &key_descriptor, KeyType::Super);
+            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)
+                    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)))
                 }
@@ -1210,6 +1352,8 @@
     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
@@ -1239,7 +1383,7 @@
             let (id, entry) = match id {
                 Some(id) => (
                     id,
-                    Self::load_key_components(&tx, KeyEntryLoadBits::KM, id)
+                    Self::load_key_components(tx, KeyEntryLoadBits::KM, id)
                         .context("In get_or_create_key_with.")?,
                 ),
 
@@ -1265,13 +1409,13 @@
                     let (blob, metadata) =
                         create_new_key().context("In get_or_create_key_with.")?;
                     Self::set_blob_internal(
-                        &tx,
+                        tx,
                         id,
                         SubComponentType::KEY_BLOB,
                         Some(&blob),
                         Some(&metadata),
                     )
-                    .context("In get_of_create_key_with.")?;
+                    .context("In get_or_create_key_with.")?;
                     (
                         id,
                         KeyEntry {
@@ -1288,18 +1432,6 @@
         .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.
@@ -1339,15 +1471,11 @@
     }
 
     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,
-            ..
-        }))
+        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.
@@ -1360,10 +1488,13 @@
         &mut self,
         domain: &Domain,
         namespace: &i64,
+        key_type: KeyType,
         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()
+            Self::create_key_entry_internal(tx, domain, namespace, key_type, km_uuid).no_gc()
         })
         .context("In create_key_entry.")
     }
@@ -1372,6 +1503,7 @@
         tx: &Transaction,
         domain: &Domain,
         namespace: &i64,
+        key_type: KeyType,
         km_uuid: &Uuid,
     ) -> Result<KeyIdGuard> {
         match *domain {
@@ -1389,7 +1521,7 @@
                      VALUES(?, ?, ?, ?, NULL, ?, ?);",
                     params![
                         id,
-                        KeyType::Client,
+                        key_type,
                         domain.0 as u32,
                         *namespace,
                         KeyLifeCycle::Existing,
@@ -1413,6 +1545,8 @@
         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| {
@@ -1426,7 +1560,7 @@
                 .context("In create_key_entry")?,
             );
             Self::set_blob_internal(
-                &tx,
+                tx,
                 key_id.0,
                 SubComponentType::KEY_BLOB,
                 Some(private_key),
@@ -1435,7 +1569,7 @@
             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)?;
+            metadata.store_in_db(key_id.0, tx)?;
             Ok(()).no_gc()
         })
         .context("In create_attestation_key_entry")
@@ -1455,8 +1589,10 @@
         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()
+            Self::set_blob_internal(tx, key_id.0, sc_type, blob, blob_metadata).need_gc()
         })
         .context("In set_blob.")
     }
@@ -1466,9 +1602,11 @@
     /// 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,
+                tx,
                 Self::UNASSIGNED_KEY_ID,
                 SubComponentType::KEY_BLOB,
                 Some(blob),
@@ -1561,7 +1699,7 @@
     #[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()
+            metadata.store_in_db(key_id.0, tx).no_gc()
         })
         .context("In insert_key_metadata.")
     }
@@ -1576,6 +1714,8 @@
         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(
@@ -1621,16 +1761,16 @@
             metadata.add(KeyMetaEntry::AttestationExpirationDate(DateTime::from_millis_epoch(
                 expiration_date,
             )));
-            metadata.store_in_db(key_id, &tx).context("Failed to insert key metadata.")?;
+            metadata.store_in_db(key_id, tx).context("Failed to insert key metadata.")?;
             Self::set_blob_internal(
-                &tx,
+                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)
+            Self::set_blob_internal(tx, key_id, SubComponentType::CERT, Some(batch_cert), None)
                 .context("Failed to insert cert")?;
             Ok(()).no_gc()
         })
@@ -1645,6 +1785,8 @@
         namespace: i64,
         km_uuid: &Uuid,
     ) -> Result<()> {
+        let _wp = wd::watch_millis("KeystoreDB::assign_attestation_key", 500);
+
         match domain {
             Domain::APP | Domain::SELINUX => {}
             _ => {
@@ -1688,11 +1830,12 @@
                     ],
                 )
                 .context("Failed to assign attestation key")?;
-            if result != 1 {
-                return Err(KsError::sys()).context(format!(
-                    "Expected to update a single entry but instead updated {}.",
-                    result
-                ));
+            if result == 0 {
+                log_rkp_error_stats(MetricsRkpError::OUT_OF_KEYS);
+                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()
         })
@@ -1707,6 +1850,8 @@
         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(
@@ -1732,7 +1877,7 @@
                         km_uuid,
                         num_keys
                     ],
-                    |row| Ok(row.get(0)?),
+                    |row| row.get(0),
                 )?
                 .collect::<rusqlite::Result<Vec<Vec<u8>>>>()
                 .context("Failed to execute statement")?;
@@ -1744,6 +1889,8 @@
     /// 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(
@@ -1767,7 +1914,7 @@
             );
             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)? {
+                if Self::mark_unreferenced(tx, id)? {
                     num_deleted += 1;
                 }
             }
@@ -1776,6 +1923,35 @@
         .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(
@@ -1783,6 +1959,8 @@
         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
@@ -1803,7 +1981,7 @@
                         km_uuid,
                         KeyLifeCycle::Live
                     ],
-                    |row| Ok(row.get(0)?),
+                    |row| row.get(0),
                 )?
                 .collect::<rusqlite::Result<Vec<DateTime>>>()
                 .context("Failed to execute metadata statement")?;
@@ -1850,6 +2028,8 @@
         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 => {}
             _ => {
@@ -1914,8 +2094,8 @@
             }
             Ok(Some(CertificateChain {
                 private_key: ZVec::try_from(km_blob)?,
-                batch_cert: ZVec::try_from(batch_cert_blob)?,
-                cert_chain: ZVec::try_from(cert_chain_blob)?,
+                batch_cert: batch_cert_blob,
+                cert_chain: cert_chain_blob,
             }))
             .no_gc()
         })
@@ -1933,6 +2113,7 @@
         alias: &str,
         domain: &Domain,
         namespace: &i64,
+        key_type: KeyType,
     ) -> Result<bool> {
         match *domain {
             Domain::APP | Domain::SELINUX => {}
@@ -1947,15 +2128,15 @@
             .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],
+                 WHERE alias = ? AND domain = ? AND namespace = ? AND key_type = ?;",
+                params![KeyLifeCycle::Unreferenced, alias, domain.0 as u32, namespace, key_type],
             )
             .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 = ?;",
+                    WHERE id = ? AND domain = ? AND namespace = ? AND state = ? AND key_type = ?;",
                 params![
                     alias,
                     KeyLifeCycle::Live,
@@ -1963,6 +2144,7 @@
                     domain.0 as u32,
                     *namespace,
                     KeyLifeCycle::Existing,
+                    key_type,
                 ],
             )
             .context("In rebind_alias: Failed to set alias.")?;
@@ -1975,20 +2157,89 @@
         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.
+    #[allow(clippy::too_many_arguments)]
     pub fn store_new_key(
         &mut self,
         key: &KeyDescriptor,
+        key_type: KeyType,
         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 } => {
@@ -2000,7 +2251,7 @@
             }
         };
         self.with_transaction(TransactionBehavior::Immediate, |tx| {
-            let key_id = Self::create_key_entry_internal(tx, &domain, namespace, km_uuid)
+            let key_id = Self::create_key_entry_internal(tx, &domain, namespace, key_type, km_uuid)
                 .context("Trying to create new key entry.")?;
             let (blob, blob_metadata) = *blob_info;
             Self::set_blob_internal(
@@ -2008,11 +2259,11 @@
                 key_id.id(),
                 SubComponentType::KEY_BLOB,
                 Some(blob),
-                Some(&blob_metadata),
+                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)
+                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 {
@@ -2020,7 +2271,7 @@
                     tx,
                     key_id.id(),
                     SubComponentType::CERT_CHAIN,
-                    Some(&cert_chain),
+                    Some(cert_chain),
                     None,
                 )
                 .context("Trying to insert the certificate chain.")?;
@@ -2028,7 +2279,7 @@
             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)
+            let need_gc = Self::rebind_alias(tx, &key_id, alias, &domain, namespace, key_type)
                 .context("Trying to rebind alias.")?;
             Ok(key_id).do_gc(need_gc)
         })
@@ -2041,9 +2292,12 @@
     pub fn store_new_certificate(
         &mut self,
         key: &KeyDescriptor,
+        key_type: KeyType,
         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 } => {
@@ -2056,7 +2310,7 @@
             }
         };
         self.with_transaction(TransactionBehavior::Immediate, |tx| {
-            let key_id = Self::create_key_entry_internal(tx, &domain, namespace, km_uuid)
+            let key_id = Self::create_key_entry_internal(tx, &domain, namespace, key_type, km_uuid)
                 .context("Trying to create new key entry.")?;
 
             Self::set_blob_internal(
@@ -2075,7 +2329,7 @@
 
             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)
+            let need_gc = Self::rebind_alias(tx, &key_id, alias, &domain, namespace, key_type)
                 .context("Trying to rebind alias.")?;
             Ok(key_id).do_gc(need_gc)
         })
@@ -2144,7 +2398,7 @@
                 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)
+                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))
@@ -2156,11 +2410,12 @@
                 let mut stmt = tx
                     .prepare(
                         "SELECT keyentryid, access_vector FROM persistent.grant
-                            WHERE grantee = ? AND id = ?;",
+                            WHERE grantee = ? AND id = ? AND
+                            (SELECT state FROM persistent.keyentry WHERE id = keyentryid) = ?;",
                     )
                     .context("Domain::GRANT prepare statement failed")?;
                 let mut rows = stmt
-                    .query(params![caller_uid as i64, key.nspace])
+                    .query(params![caller_uid as i64, key.nspace, KeyLifeCycle::Live])
                     .context("Domain:Grant: query failed.")?;
                 let (key_id, access_vector): (i64, i32) =
                     db_utils::with_rows_extract_one(&mut rows, |row| {
@@ -2308,7 +2563,7 @@
             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)
+                KeyParameter::new_from_sql(tag, &SqlField::new(1, row), sec_level)
                     .context("Failed to read KeyParameter.")?,
             );
             Ok(())
@@ -2323,6 +2578,8 @@
     /// 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(
@@ -2369,6 +2626,8 @@
         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,
@@ -2496,6 +2755,8 @@
         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)
@@ -2525,6 +2786,8 @@
     /// 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.");
@@ -2534,32 +2797,33 @@
                 "DELETE FROM persistent.keymetadata
                 WHERE keyentryid IN (
                     SELECT id FROM persistent.keyentry
-                    WHERE domain = ? AND namespace = ?
+                    WHERE domain = ? AND namespace = ? AND key_type = ?
                 );",
-                params![domain.0, namespace],
+                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 = ?
+                    WHERE domain = ? AND namespace = ? AND key_type = ?
                 );",
-                params![domain.0, namespace],
+                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 = ?
+                    WHERE domain = ? AND namespace = ? AND key_type = ?
                 );",
-                params![domain.0, namespace],
+                params![domain.0, namespace, KeyType::Client],
             )
             .context("Trying to delete grants.")?;
             tx.execute(
-                "DELETE FROM persistent.keyentry WHERE domain = ? AND namespace = ?;",
-                params![domain.0, namespace],
+                "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()
@@ -2567,6 +2831,47 @@
         .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.
@@ -2576,6 +2881,8 @@
         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!(
@@ -2608,7 +2915,7 @@
                     // OR super key:
                     KeyType::Super,
                     user_id,
-                    Self::USER_SUPER_KEY_ALIAS,
+                    USER_SUPER_KEY.alias,
                     KeyLifeCycle::Live
                 ])
                 .context("In unbind_keys_for_user. Failed to query the keys created by apps.")?;
@@ -2634,7 +2941,7 @@
                         }
                     }
                 }
-                notify_gc = Self::mark_unreferenced(&tx, key_id)
+                notify_gc = Self::mark_unreferenced(tx, key_id)
                     .context("In unbind_keys_for_user.")?
                     || notify_gc;
             }
@@ -2648,16 +2955,15 @@
         load_bits: KeyEntryLoadBits,
         key_id: i64,
     ) -> Result<KeyEntry> {
-        let metadata = KeyMetaData::load_from_db(key_id, &tx).context("In load_key_components.")?;
+        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.")?;
+            Self::load_blob_components(key_id, load_bits, tx).context("In load_key_components.")?;
 
-        let parameters = Self::load_key_parameters(key_id, &tx)
+        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)
+        let km_uuid = Self::get_key_km_uuid(tx, key_id)
             .context("In load_key_components: Trying to get KM uuid.")?;
 
         Ok(KeyEntry {
@@ -2675,17 +2981,28 @@
     /// 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>> {
+    pub fn list(
+        &mut self,
+        domain: Domain,
+        namespace: i64,
+        key_type: KeyType,
+    ) -> 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 = ?;",
+                     WHERE domain = ?
+                     AND namespace = ?
+                     AND alias IS NOT NULL
+                     AND state = ?
+                     AND key_type = ?;",
                 )
                 .context("In list: Failed to prepare.")?;
 
             let mut rows = stmt
-                .query(params![domain.0 as u32, namespace, KeyLifeCycle::Live])
+                .query(params![domain.0 as u32, namespace, KeyLifeCycle::Live, key_type])
                 .context("In list: Failed to query.")?;
 
             let mut descriptors: Vec<KeyDescriptor> = Vec::new();
@@ -2717,6 +3034,8 @@
         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.
@@ -2728,7 +3047,7 @@
             // 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)
+                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
@@ -2782,11 +3101,13 @@
         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)
+                Self::load_access_tuple(tx, key, KeyType::Client, caller_uid)
                     .context("In ungrant.")?;
 
             // Perform access control. We must return here if the permission
@@ -2831,100 +3152,59 @@
         }
     }
 
-    /// 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<()> {
-        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()
-        })
+    /// Insert or replace the auth token based on (user_id, auth_id, auth_type)
+    pub fn insert_auth_token(&mut self, auth_token: &HardwareAuthToken) {
+        self.perboot.insert_auth_token_entry(AuthTokenEntry::new(
+            auth_token.clone(),
+            MonotonicRawTime::now(),
+        ))
     }
 
     /// Find the newest auth token matching the given predicate.
-    pub fn find_auth_token_entry<F>(
-        &mut self,
-        p: F,
-    ) -> Result<Option<(AuthTokenEntry, MonotonicRawTime)>>
+    pub fn find_auth_token_entry<F>(&self, p: F) -> Option<(AuthTokenEntry, MonotonicRawTime)>
     where
         F: Fn(&AuthTokenEntry) -> bool,
     {
-        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.")
+        self.perboot.find_auth_token_entry(p).map(|entry| (entry, self.get_last_off_body()))
     }
 
     /// 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<()> {
-        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()
-        })
+    pub fn insert_last_off_body(&self, last_off_body: MonotonicRawTime) {
+        self.perboot.set_last_off_body(last_off_body)
     }
 
     /// Update last_off_body when on_device_off_body is called
-    pub fn update_last_off_body(&mut self, last_off_body: MonotonicRawTime) -> Result<()> {
-        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()
-        })
+    pub fn update_last_off_body(&self, last_off_body: MonotonicRawTime) {
+        self.perboot.set_last_off_body(last_off_body)
     }
 
     /// Get last_off_body time when finding auth tokens
-    fn get_last_off_body(tx: &Transaction) -> Result<MonotonicRawTime> {
-        tx.query_row(
-            "SELECT value from perboot.metadata WHERE key = ?;",
-            params!["last_off_body"],
-            |row| Ok(row.get(0)?),
-        )
-        .context("In get_last_off_body: query_row failed.")
+    fn get_last_off_body(&self) -> MonotonicRawTime {
+        self.perboot.get_last_off_body()
+    }
+
+    /// Load descriptor of a key by key id
+    pub fn load_key_descriptor(&mut self, key_id: i64) -> Result<Option<KeyDescriptor>> {
+        let _wp = wd::watch_millis("KeystoreDB::load_key_descriptor", 500);
+
+        self.with_transaction(TransactionBehavior::Deferred, |tx| {
+            tx.query_row(
+                "SELECT domain, namespace, alias FROM persistent.keyentry WHERE id = ?;",
+                params![key_id],
+                |row| {
+                    Ok(KeyDescriptor {
+                        domain: Domain(row.get(0)?),
+                        nspace: row.get(1)?,
+                        alias: row.get(2)?,
+                        blob: None,
+                    })
+                },
+            )
+            .optional()
+            .context("Trying to load key descriptor")
+            .no_gc()
+        })
+        .context("In load_key_descriptor.")
     }
 }
 
@@ -2948,8 +3228,10 @@
         Timestamp::Timestamp,
     };
     use rusqlite::NO_PARAMS;
-    use rusqlite::{Error, TransactionBehavior};
+    use rusqlite::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;
@@ -2958,9 +3240,9 @@
     use std::time::Instant;
 
     fn new_test_db() -> Result<KeystoreDB> {
-        let conn = KeystoreDB::make_connection("file::memory:", "file::memory:")?;
+        let conn = KeystoreDB::make_connection("file::memory:")?;
 
-        let mut db = KeystoreDB { conn, gc: None };
+        let mut db = KeystoreDB { conn, gc: None, perboot: Arc::new(perboot::PerbootDB::new()) };
         db.with_transaction(TransactionBehavior::Immediate, |tx| {
             KeystoreDB::init_tables(tx).context("Failed to initialize tables.").no_gc()
         })?;
@@ -2971,12 +3253,12 @@
     where
         F: Fn(&Uuid, &[u8]) -> Result<()> + Send + 'static,
     {
-        let super_key = Arc::new(SuperKeyManager::new());
+        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(gc))
+        KeystoreDB::new(path, Some(Arc::new(gc)))
     }
 
     fn rebind_alias(
@@ -2987,7 +3269,7 @@
         namespace: i64,
     ) -> Result<bool> {
         db.with_transaction(TransactionBehavior::Immediate, |tx| {
-            KeystoreDB::rebind_alias(tx, newid, alias, &domain, &namespace).no_gc()
+            KeystoreDB::rebind_alias(tx, newid, alias, &domain, &namespace, KeyType::Client).no_gc()
         })
         .context("In rebind_alias.")
     }
@@ -3046,15 +3328,6 @@
         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(())
     }
 
@@ -3069,8 +3342,8 @@
             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)?;
+        db.insert_auth_token(&auth_token1);
+        let auth_tokens_returned = get_auth_tokens(&db);
         assert_eq!(auth_tokens_returned.len(), 1);
 
         // insert another auth token with the same values for the columns in the UNIQUE constraint
@@ -3084,8 +3357,8 @@
             mac: String::from("mac").into_bytes(),
         };
 
-        db.insert_auth_token(&auth_token2)?;
-        let mut auth_tokens_returned = get_auth_tokens(&mut db)?;
+        db.insert_auth_token(&auth_token2);
+        let mut auth_tokens_returned = get_auth_tokens(&db);
         assert_eq!(auth_tokens_returned.len(), 1);
 
         if let Some(auth_token) = auth_tokens_returned.pop() {
@@ -3103,33 +3376,16 @@
             mac: String::from("mac").into_bytes(),
         };
 
-        db.insert_auth_token(&auth_token3)?;
-        let auth_tokens_returned = get_auth_tokens(&mut db)?;
+        db.insert_auth_token(&auth_token3);
+        let auth_tokens_returned = get_auth_tokens(&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)
+    fn get_auth_tokens(db: &KeystoreDB) -> Vec<AuthTokenEntry> {
+        db.perboot.get_all_auth_token_entries()
     }
 
     #[test]
@@ -3137,7 +3393,7 @@
         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)?;
+        db.create_key_entry(&Domain::APP, &100, KeyType::Client, &KEYSTORE_UUID)?;
         let entries = get_keyentry(&db)?;
         assert_eq!(entries.len(), 1);
 
@@ -3156,8 +3412,8 @@
 
         let mut db = new_test_db()?;
 
-        db.create_key_entry(&Domain::APP, &100, &KEYSTORE_UUID)?;
-        db.create_key_entry(&Domain::SELINUX, &101, &KEYSTORE_UUID)?;
+        db.create_key_entry(&Domain::APP, &100, KeyType::Client, &KEYSTORE_UUID)?;
+        db.create_key_entry(&Domain::SELINUX, &101, KeyType::Client, &KEYSTORE_UUID)?;
 
         let entries = get_keyentry(&db)?;
         assert_eq!(entries.len(), 2);
@@ -3166,15 +3422,15 @@
 
         // Test that we must pass in a valid Domain.
         check_result_is_error_containing_string(
-            db.create_key_entry(&Domain::GRANT, &102, &KEYSTORE_UUID),
+            db.create_key_entry(&Domain::GRANT, &102, KeyType::Client, &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),
+            db.create_key_entry(&Domain::BLOB, &103, KeyType::Client, &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),
+            db.create_key_entry(&Domain::KEY_ID, &104, KeyType::Client, &KEYSTORE_UUID),
             "Domain Domain(4) must be either App or SELinux.",
         );
 
@@ -3209,11 +3465,11 @@
             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());
+        assert!(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.to_vec(), loaded_values.batch_cert);
-        assert_eq!(cert_chain.cert_chain.to_vec(), loaded_values.cert_chain);
+        assert_eq!(cert_chain.batch_cert, loaded_values.batch_cert);
+        assert_eq!(cert_chain.cert_chain, loaded_values.cert_chain);
         Ok(())
     }
 
@@ -3306,8 +3562,8 @@
             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.to_vec());
-        assert_eq!(entry_values.cert_chain, value.cert_chain.to_vec());
+        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(
@@ -3338,6 +3594,23 @@
     }
 
     #[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, KeyType::Client, &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,
@@ -3346,8 +3619,8 @@
         }
 
         let mut db = new_test_db()?;
-        db.create_key_entry(&Domain::APP, &42, &KEYSTORE_UUID)?;
-        db.create_key_entry(&Domain::APP, &42, &KEYSTORE_UUID)?;
+        db.create_key_entry(&Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
+        db.create_key_entry(&Domain::APP, &42, KeyType::Client, &KEYSTORE_UUID)?;
         let entries = get_keyentry(&db)?;
         assert_eq!(entries.len(), 2);
         assert_eq!(
@@ -3683,6 +3956,7 @@
                 alias: Some(TEST_ALIAS.to_string()),
                 blob: None,
             },
+            KeyType::Client,
             TEST_CERT_BLOB,
             &KEYSTORE_UUID,
         )
@@ -4027,6 +4301,327 @@
         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(())
+    }
+
+    #[test]
+    fn test_upgrade_0_to_1() {
+        const ALIAS1: &str = "test_upgrade_0_to_1_1";
+        const ALIAS2: &str = "test_upgrade_0_to_1_2";
+        const ALIAS3: &str = "test_upgrade_0_to_1_3";
+        const UID: u32 = 33;
+        let temp_dir = Arc::new(TempDir::new("test_upgrade_0_to_1").unwrap());
+        let mut db = KeystoreDB::new(temp_dir.path(), None).unwrap();
+        let key_id_untouched1 =
+            make_test_key_entry(&mut db, Domain::APP, UID as i64, ALIAS1, None).unwrap().id();
+        let key_id_untouched2 =
+            make_bootlevel_key_entry(&mut db, Domain::APP, UID as i64, ALIAS2, false).unwrap().id();
+        let key_id_deleted =
+            make_bootlevel_key_entry(&mut db, Domain::APP, UID as i64, ALIAS3, true).unwrap().id();
+
+        let (_, key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(ALIAS1.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(UID as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap();
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id_untouched1, None));
+        let (_, key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(ALIAS2.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(UID as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap();
+        assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_untouched2, false));
+        let (_, key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(ALIAS3.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(UID as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap();
+        assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_deleted, true));
+
+        db.with_transaction(TransactionBehavior::Immediate, |tx| {
+            KeystoreDB::from_0_to_1(tx).no_gc()
+        })
+        .unwrap();
+
+        let (_, key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(ALIAS1.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(UID as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap();
+        assert_eq!(key_entry, make_test_key_entry_test_vector(key_id_untouched1, None));
+        let (_, key_entry) = db
+            .load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(ALIAS2.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(UID as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap();
+        assert_eq!(key_entry, make_bootlevel_test_key_entry_test_vector(key_id_untouched2, false));
+        assert_eq!(
+            Some(&KsError::Rc(ResponseCode::KEY_NOT_FOUND)),
+            db.load_key_entry(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some(ALIAS3.to_string()),
+                    blob: None,
+                },
+                KeyType::Client,
+                KeyEntryLoadBits::BOTH,
+                UID,
+                |k, av| {
+                    assert_eq!(Domain::APP, k.domain);
+                    assert_eq!(UID as i64, k.nspace);
+                    assert!(av.is_none());
+                    Ok(())
+                },
+            )
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<KsError>()
+        );
+    }
+
     static KEY_LOCK_TEST_ALIAS: &str = "my super duper locked key";
 
     #[test]
@@ -4104,7 +4699,7 @@
     }
 
     #[test]
-    fn teset_database_busy_error_code() {
+    fn test_database_busy_error_code() {
         let temp_dir =
             TempDir::new("test_database_busy_error_code_").expect("Failed to create temp dir.");
 
@@ -4145,8 +4740,9 @@
 
         let test_begin = Instant::now();
 
-        let mut db = KeystoreDB::new(temp_dir.path()).expect("Failed to open database.");
         const KEY_COUNT: u32 = 500u32;
+        let mut db =
+            new_test_db_with_gc(temp_dir.path(), |_, _| Ok(())).expect("Failed to open database.");
         const OPEN_DB_COUNT: u32 = 50u32;
 
         let mut actual_key_count = KEY_COUNT;
@@ -4164,7 +4760,8 @@
         // 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.");
+            let mut db = new_test_db_with_gc(temp_dir1.path(), |_, _| Ok(()))
+                .expect("Failed to open database.");
 
             for count in 0..actual_key_count {
                 if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
@@ -4193,7 +4790,8 @@
         // 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.");
+            let mut db = new_test_db_with_gc(temp_dir2.path(), |_, _| Ok(()))
+                .expect("Failed to open database.");
 
             for count in 0..actual_key_count {
                 if Instant::now().duration_since(test_begin) >= Duration::from_secs(40) {
@@ -4209,27 +4807,6 @@
             }
         });
 
-        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
@@ -4241,7 +4818,8 @@
                 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 mut db = new_test_db_with_gc(temp_dir4.path(), |_, _| Ok(()))
+                    .expect("Failed to open database.");
 
                 let alias = format!("test_alias_{}", count);
                 make_test_key_entry(&mut db, Domain::APP, 3, &alias, None)
@@ -4260,9 +4838,6 @@
         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(())
     }
 
@@ -4321,7 +4896,7 @@
                 })
                 .collect();
             list_o_descriptors.sort();
-            let mut list_result = db.list(*domain, *namespace)?;
+            let mut list_result = db.list(*domain, *namespace, KeyType::Client)?;
             list_result.sort();
             assert_eq!(list_o_descriptors, list_result);
 
@@ -4351,7 +4926,7 @@
             loaded_entries.sort_unstable();
             assert_eq!(list_o_ids, loaded_entries);
         }
-        assert_eq!(Vec::<KeyDescriptor>::new(), db.list(Domain::SELINUX, 101)?);
+        assert_eq!(Vec::<KeyDescriptor>::new(), db.list(Domain::SELINUX, 101, KeyType::Client)?);
 
         Ok(())
     }
@@ -4373,7 +4948,6 @@
     }
 
     #[derive(Debug, PartialEq)]
-    #[allow(dead_code)]
     struct KeyEntryRow {
         id: i64,
         key_type: KeyType,
@@ -4391,10 +4965,7 @@
                 Ok(KeyEntryRow {
                     id: row.get(0)?,
                     key_type: row.get(1)?,
-                    domain: match row.get(2)? {
-                        Some(i) => Some(Domain(i)),
-                        None => None,
-                    },
+                    domain: row.get::<_, Option<_>>(2)?.map(Domain),
                     namespace: row.get(3)?,
                     alias: row.get(4)?,
                     state: row.get(5)?,
@@ -4670,7 +5241,7 @@
         alias: &str,
         max_usage_count: Option<i32>,
     ) -> Result<KeyIdGuard> {
-        let key_id = db.create_key_entry(&domain, &namespace, &KEYSTORE_UUID)?;
+        let key_id = db.create_key_entry(&domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
         let mut blob_metadata = BlobMetaData::new();
         blob_metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
         blob_metadata.add(BlobMetaEntry::Salt(vec![1, 2, 3]));
@@ -4722,6 +5293,66 @@
         }
     }
 
+    fn make_bootlevel_key_entry(
+        db: &mut KeystoreDB,
+        domain: Domain,
+        namespace: i64,
+        alias: &str,
+        logical_only: bool,
+    ) -> Result<KeyIdGuard> {
+        let key_id = db.create_key_entry(&domain, &namespace, KeyType::Client, &KEYSTORE_UUID)?;
+        let mut blob_metadata = BlobMetaData::new();
+        if !logical_only {
+            blob_metadata.add(BlobMetaEntry::MaxBootLevel(3));
+        }
+        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 mut params = make_test_params(None);
+        params.push(KeyParameter::new(KeyParameterValue::MaxBootLevel(3), SecurityLevel::KEYSTORE));
+
+        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_bootlevel_test_key_entry_test_vector(key_id: i64, logical_only: bool) -> KeyEntry {
+        let mut params = make_test_params(None);
+        params.push(KeyParameter::new(KeyParameterValue::MaxBootLevel(3), SecurityLevel::KEYSTORE));
+
+        let mut blob_metadata = BlobMetaData::new();
+        if !logical_only {
+            blob_metadata.add(BlobMetaEntry::MaxBootLevel(3));
+        }
+        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;",
@@ -4792,17 +5423,17 @@
     #[test]
     fn test_last_off_body() -> Result<()> {
         let mut db = new_test_db()?;
-        db.insert_last_off_body(MonotonicRawTime::now())?;
+        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 last_off_body_1 = db.get_last_off_body();
         let one_second = Duration::from_secs(1);
         thread::sleep(one_second);
-        db.update_last_off_body(MonotonicRawTime::now())?;
+        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());
+        let last_off_body_2 = db.get_last_off_body();
+        assert!(last_off_body_1 < last_off_body_2);
         Ok(())
     }
 
@@ -4815,11 +5446,11 @@
         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());
+        assert_eq!(1, db.list(Domain::APP, 110000, KeyType::Client)?.len());
+        assert_eq!(0, db.list(Domain::APP, 210000, KeyType::Client)?.len());
 
         db.unbind_keys_for_user(1, true)?;
-        assert_eq!(0, db.list(Domain::APP, 110000)?.len());
+        assert_eq!(0, db.list(Domain::APP, 110000, KeyType::Client)?.len());
 
         Ok(())
     }
@@ -4827,31 +5458,281 @@
     #[test]
     fn test_store_super_key() -> Result<()> {
         let mut db = new_test_db()?;
-        let pw = "xyzabc".as_bytes();
+        let pw: keystore2_crypto::Password = (&b"xyzabc"[..]).into();
         let super_key = keystore2_crypto::generate_aes256_key()?;
-        let secret = String::from("keystore2 is great.");
-        let secret_bytes = secret.into_bytes();
+        let secret_bytes = b"keystore2 is great.";
         let (encrypted_secret, iv, tag) =
-            keystore2_crypto::aes_gcm_encrypt(&secret_bytes, &super_key)?;
+            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, &(&encrypted_super_key, &metadata))?;
+        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", KeyType::Super)?);
+        assert!(db.key_exists(Domain::APP, 1, USER_SUPER_KEY.alias, KeyType::Super)?);
 
-        let (_, key_entry) = db.load_super_key(1)?.unwrap();
-        let loaded_super_key = SuperKeyManager::extract_super_key_from_key_entry(key_entry, &pw)?;
-
-        let decrypted_secret_bytes = keystore2_crypto::aes_gcm_decrypt(
-            &encrypted_secret,
-            &iv,
-            &tag,
-            &loaded_super_key.get_key(),
+        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 = String::from_utf8((&decrypted_secret_bytes).to_vec())?;
-        assert_eq!(String::from("keystore2 is great."), decrypted_secret);
+
+        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<MetricsStorage> {
+        vec![
+            MetricsStorage::KEY_ENTRY,
+            MetricsStorage::KEY_ENTRY_ID_INDEX,
+            MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX,
+            MetricsStorage::BLOB_ENTRY,
+            MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX,
+            MetricsStorage::KEY_PARAMETER,
+            MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX,
+            MetricsStorage::KEY_METADATA,
+            MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX,
+            MetricsStorage::GRANT,
+            MetricsStorage::AUTH_TOKEN,
+            MetricsStorage::BLOB_METADATA,
+            MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX,
+        ]
+    }
+
+    /// 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: i32 = 4096;
+
+        let mut db = new_test_db()?;
+
+        for t in get_valid_statsd_storage_types() {
+            let stat = db.get_storage_stat(t)?;
+            // AuthToken can be less than a page since it's in a btree, not sqlite
+            // TODO(b/187474736) stop using if-let here
+            if let MetricsStorage::AUTH_TOKEN = t {
+            } else {
+                assert!(stat.size >= PAGE_SIZE);
+            }
+            assert!(stat.size >= stat.unused_size);
+        }
+
+        Ok(())
+    }
+
+    fn get_storage_stats_map(db: &mut KeystoreDB) -> BTreeMap<i32, StorageStats> {
+        get_valid_statsd_storage_types()
+            .into_iter()
+            .map(|t| (t.0, db.get_storage_stat(t).unwrap()))
+            .collect()
+    }
+
+    fn assert_storage_increased(
+        db: &mut KeystoreDB,
+        increased_storage_types: Vec<MetricsStorage>,
+        baseline: &mut BTreeMap<i32, StorageStats>,
+    ) {
+        for storage in increased_storage_types {
+            // Verify the expected storage increased.
+            let new = db.get_storage_stat(storage).unwrap();
+            let storage = storage;
+            let old = &baseline[&storage.0];
+            assert!(new.size >= old.size, "{}: {} >= {}", storage.0, new.size, old.size);
+            assert!(
+                new.unused_size <= old.unused_size,
+                "{}: {} <= {}",
+                storage.0,
+                new.unused_size,
+                old.unused_size
+            );
+
+            // Update the baseline with the new value so that it succeeds in the
+            // later comparison.
+            baseline.insert(storage.0, 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, StorageStats>| -> 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, KeyType::Client, &KEYSTORE_UUID)?;
+        assert_storage_increased(
+            &mut db,
+            vec![
+                MetricsStorage::KEY_ENTRY,
+                MetricsStorage::KEY_ENTRY_ID_INDEX,
+                MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX,
+            ],
+            &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![
+                MetricsStorage::BLOB_ENTRY,
+                MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX,
+                MetricsStorage::BLOB_METADATA,
+                MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX,
+            ],
+            &mut working_stats,
+        );
+
+        let params = make_test_params(None);
+        db.insert_keyparameter(&key_id, &params)?;
+        assert_storage_increased(
+            &mut db,
+            vec![MetricsStorage::KEY_PARAMETER, MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX],
+            &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![MetricsStorage::KEY_METADATA, MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX],
+            &mut working_stats,
+        );
+
+        let mut sum = 0;
+        for stat in working_stats.values() {
+            sum += stat.size;
+        }
+        let total = db.get_storage_stat(MetricsStorage::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![MetricsStorage::AUTH_TOKEN], &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![MetricsStorage::GRANT], &mut working_stats);
+
+        Ok(())
+    }
+
+    #[test]
+    fn find_auth_token_entry_returns_latest() -> Result<()> {
+        let mut db = new_test_db()?;
+        db.insert_auth_token(&HardwareAuthToken {
+            challenge: 123,
+            userId: 456,
+            authenticatorId: 789,
+            authenticatorType: kmhw_authenticator_type::ANY,
+            timestamp: Timestamp { milliSeconds: 10 },
+            mac: b"mac0".to_vec(),
+        });
+        std::thread::sleep(std::time::Duration::from_millis(1));
+        db.insert_auth_token(&HardwareAuthToken {
+            challenge: 123,
+            userId: 457,
+            authenticatorId: 789,
+            authenticatorType: kmhw_authenticator_type::ANY,
+            timestamp: Timestamp { milliSeconds: 12 },
+            mac: b"mac1".to_vec(),
+        });
+        std::thread::sleep(std::time::Duration::from_millis(1));
+        db.insert_auth_token(&HardwareAuthToken {
+            challenge: 123,
+            userId: 458,
+            authenticatorId: 789,
+            authenticatorType: kmhw_authenticator_type::ANY,
+            timestamp: Timestamp { milliSeconds: 3 },
+            mac: b"mac2".to_vec(),
+        });
+        // All three entries are in the database
+        assert_eq!(db.perboot.auth_tokens_len(), 3);
+        // It selected the most recent timestamp
+        assert_eq!(db.find_auth_token_entry(|_| true).unwrap().0.auth_token.mac, b"mac2".to_vec());
+        Ok(())
+    }
+
+    #[test]
+    fn test_load_key_descriptor() -> Result<()> {
+        let mut db = new_test_db()?;
+        let key_id = make_test_key_entry(&mut db, Domain::APP, 1, TEST_ALIAS, None)?.0;
+
+        let key = db.load_key_descriptor(key_id)?.unwrap();
+
+        assert_eq!(key.domain, Domain::APP);
+        assert_eq!(key.nspace, 1);
+        assert_eq!(key.alias, Some(TEST_ALIAS.to_string()));
+
+        // No such id
+        assert_eq!(db.load_key_descriptor(key_id + 1)?, None);
         Ok(())
     }
 }
diff --git a/keystore2/src/database/perboot.rs b/keystore2/src/database/perboot.rs
new file mode 100644
index 0000000..7ff35fa
--- /dev/null
+++ b/keystore2/src/database/perboot.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 a per-boot, shared, in-memory storage of auth tokens
+//! and last-time-on-body for the main Keystore 2.0 database module.
+
+use super::{AuthTokenEntry, MonotonicRawTime};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    HardwareAuthToken::HardwareAuthToken, HardwareAuthenticatorType::HardwareAuthenticatorType,
+};
+use lazy_static::lazy_static;
+use std::collections::HashSet;
+use std::sync::atomic::{AtomicI64, Ordering};
+use std::sync::Arc;
+use std::sync::RwLock;
+
+#[derive(PartialEq, PartialOrd, Ord, Eq, Hash)]
+struct AuthTokenId {
+    user_id: i64,
+    auth_id: i64,
+    authenticator_type: HardwareAuthenticatorType,
+}
+
+impl AuthTokenId {
+    fn from_auth_token(tok: &HardwareAuthToken) -> Self {
+        AuthTokenId {
+            user_id: tok.userId,
+            auth_id: tok.authenticatorId,
+            authenticator_type: tok.authenticatorType,
+        }
+    }
+}
+
+//Implements Eq/Hash to only operate on the AuthTokenId portion
+//of the AuthTokenEntry. This allows a HashSet to DTRT.
+#[derive(Clone)]
+struct AuthTokenEntryWrap(AuthTokenEntry);
+
+impl std::hash::Hash for AuthTokenEntryWrap {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        AuthTokenId::from_auth_token(&self.0.auth_token).hash(state)
+    }
+}
+
+impl PartialEq<AuthTokenEntryWrap> for AuthTokenEntryWrap {
+    fn eq(&self, other: &AuthTokenEntryWrap) -> bool {
+        AuthTokenId::from_auth_token(&self.0.auth_token)
+            == AuthTokenId::from_auth_token(&other.0.auth_token)
+    }
+}
+
+impl Eq for AuthTokenEntryWrap {}
+
+/// Per-boot state structure. Currently only used to track auth tokens and
+/// last-off-body.
+#[derive(Default)]
+pub struct PerbootDB {
+    // We can use a .unwrap() discipline on this lock, because only panicking
+    // while holding a .write() lock will poison it. The only write usage is
+    // an insert call which inserts a pre-constructed pair.
+    auth_tokens: RwLock<HashSet<AuthTokenEntryWrap>>,
+    // Ordering::Relaxed is appropriate for accessing this atomic, since it
+    // does not currently need to be synchronized with anything else.
+    last_off_body: AtomicI64,
+}
+
+lazy_static! {
+    /// The global instance of the perboot DB. Located here rather than in globals
+    /// in order to restrict access to the database module.
+    pub static ref PERBOOT_DB: Arc<PerbootDB> = Arc::new(PerbootDB::new());
+}
+
+impl PerbootDB {
+    /// Construct a new perboot database. Currently just uses default values.
+    pub fn new() -> Self {
+        Default::default()
+    }
+    /// Add a new auth token + timestamp to the database, replacing any which
+    /// match all of user_id, auth_id, and auth_type.
+    pub fn insert_auth_token_entry(&self, entry: AuthTokenEntry) {
+        self.auth_tokens.write().unwrap().replace(AuthTokenEntryWrap(entry));
+    }
+    /// Locate an auth token entry which matches the predicate with the most
+    /// recent update time.
+    pub fn find_auth_token_entry<P: Fn(&AuthTokenEntry) -> bool>(
+        &self,
+        p: P,
+    ) -> Option<AuthTokenEntry> {
+        let reader = self.auth_tokens.read().unwrap();
+        let mut matches: Vec<_> = reader.iter().filter(|x| p(&x.0)).collect();
+        matches.sort_by_key(|x| x.0.time_received);
+        matches.last().map(|x| x.0.clone())
+    }
+    /// Get the last time the device was off the user's body
+    pub fn get_last_off_body(&self) -> MonotonicRawTime {
+        MonotonicRawTime(self.last_off_body.load(Ordering::Relaxed))
+    }
+    /// Set the last time the device was off the user's body
+    pub fn set_last_off_body(&self, last_off_body: MonotonicRawTime) {
+        self.last_off_body.store(last_off_body.0, Ordering::Relaxed)
+    }
+    /// Return how many auth tokens are currently tracked.
+    pub fn auth_tokens_len(&self) -> usize {
+        self.auth_tokens.read().unwrap().len()
+    }
+    #[cfg(test)]
+    /// For testing, return all auth tokens currently tracked.
+    pub fn get_all_auth_token_entries(&self) -> Vec<AuthTokenEntry> {
+        self.auth_tokens.read().unwrap().iter().cloned().map(|x| x.0).collect()
+    }
+}
diff --git a/keystore2/src/db_utils.rs b/keystore2/src/database/utils.rs
similarity index 98%
rename from keystore2/src/db_utils.rs
rename to keystore2/src/database/utils.rs
index 90f5616..b4590da 100644
--- a/keystore2/src/db_utils.rs
+++ b/keystore2/src/database/utils.rs
@@ -44,7 +44,7 @@
     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.")?;
+                row_extractor(row).context("In with_rows_extract_all.")?;
             }
             None => break Ok(()),
         }
diff --git a/keystore2/src/database/versioning.rs b/keystore2/src/database/versioning.rs
new file mode 100644
index 0000000..e3a95c8
--- /dev/null
+++ b/keystore2/src/database/versioning.rs
@@ -0,0 +1,379 @@
+// 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.
+
+use anyhow::{anyhow, Context, Result};
+use rusqlite::{params, OptionalExtension, Transaction, NO_PARAMS};
+
+pub fn create_or_get_version(tx: &Transaction, current_version: u32) -> Result<u32> {
+    tx.execute(
+        "CREATE TABLE IF NOT EXISTS persistent.version (
+                id INTEGER PRIMARY KEY,
+                version INTEGER);",
+        NO_PARAMS,
+    )
+    .context("In create_or_get_version: Failed to create version table.")?;
+
+    let version = tx
+        .query_row("SELECT version FROM persistent.version WHERE id = 0;", NO_PARAMS, |row| {
+            row.get(0)
+        })
+        .optional()
+        .context("In create_or_get_version: Failed to read version.")?;
+
+    let version = if let Some(version) = version {
+        version
+    } else {
+        // If no version table existed it could mean one of two things:
+        // 1) This database is completely new. In this case the version has to be set
+        //    to the current version and the current version which also needs to be
+        //    returned.
+        // 2) The database predates db versioning. In this case the version needs to be
+        //    set to 0, and 0 needs to be returned.
+        let version = if tx
+            .query_row(
+                "SELECT name FROM persistent.sqlite_master
+                 WHERE type = 'table' AND name = 'keyentry';",
+                NO_PARAMS,
+                |_| Ok(()),
+            )
+            .optional()
+            .context("In create_or_get_version: Failed to check for keyentry table.")?
+            .is_none()
+        {
+            current_version
+        } else {
+            0
+        };
+
+        tx.execute("INSERT INTO persistent.version (id, version) VALUES(0, ?);", params![version])
+            .context("In create_or_get_version: Failed to insert initial version.")?;
+        version
+    };
+    Ok(version)
+}
+
+pub fn update_version(tx: &Transaction, new_version: u32) -> Result<()> {
+    let updated = tx
+        .execute("UPDATE persistent.version SET version = ? WHERE id = 0;", params![new_version])
+        .context("In update_version: Failed to update row.")?;
+    if updated == 1 {
+        Ok(())
+    } else {
+        Err(anyhow!("In update_version: No rows were updated."))
+    }
+}
+
+pub fn upgrade_database<F>(tx: &Transaction, current_version: u32, upgraders: &[F]) -> Result<()>
+where
+    F: Fn(&Transaction) -> Result<u32> + 'static,
+{
+    if upgraders.len() < current_version as usize {
+        return Err(anyhow!("In upgrade_database: Insufficient upgraders provided."));
+    }
+    let mut db_version = create_or_get_version(tx, current_version)
+        .context("In upgrade_database: Failed to get database version.")?;
+    while db_version < current_version {
+        db_version = upgraders[db_version as usize](tx).with_context(|| {
+            format!("In upgrade_database: Trying to upgrade from db version {}.", db_version)
+        })?;
+    }
+    update_version(tx, db_version).context("In upgrade_database.")
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use rusqlite::{Connection, TransactionBehavior, NO_PARAMS};
+
+    #[test]
+    fn upgrade_database_test() {
+        let mut conn = Connection::open_in_memory().unwrap();
+        conn.execute("ATTACH DATABASE 'file::memory:' as persistent;", NO_PARAMS).unwrap();
+
+        let upgraders: Vec<_> = (0..30_u32)
+            .map(move |i| {
+                move |tx: &Transaction| {
+                    tx.execute(
+                        "INSERT INTO persistent.test (test_field) VALUES(?);",
+                        params![i + 1],
+                    )
+                    .with_context(|| format!("In upgrade_from_{}_to_{}.", i, i + 1))?;
+                    Ok(i + 1)
+                }
+            })
+            .collect();
+
+        for legacy in &[false, true] {
+            if *legacy {
+                conn.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,
+                )
+                .unwrap();
+            }
+            for from in 1..29 {
+                for to in from..30 {
+                    conn.execute("DROP TABLE IF EXISTS persistent.version;", NO_PARAMS).unwrap();
+                    conn.execute("DROP TABLE IF EXISTS persistent.test;", NO_PARAMS).unwrap();
+                    conn.execute(
+                        "CREATE TABLE IF NOT EXISTS persistent.test (
+                            id INTEGER PRIMARY KEY,
+                            test_field INTEGER);",
+                        NO_PARAMS,
+                    )
+                    .unwrap();
+
+                    {
+                        let tx =
+                            conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+                        create_or_get_version(&tx, from).unwrap();
+                        tx.commit().unwrap();
+                    }
+                    {
+                        let tx =
+                            conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+                        upgrade_database(&tx, to, &upgraders).unwrap();
+                        tx.commit().unwrap();
+                    }
+
+                    // In the legacy database case all upgraders starting from 0 have to run. So
+                    // after the upgrade step, the expectations need to be adjusted.
+                    let from = if *legacy { 0 } else { from };
+
+                    // There must be exactly to - from rows.
+                    assert_eq!(
+                        to - from,
+                        conn.query_row(
+                            "SELECT COUNT(test_field) FROM persistent.test;",
+                            NO_PARAMS,
+                            |row| row.get(0)
+                        )
+                        .unwrap()
+                    );
+                    // Each row must have the correct relation between id and test_field. If this
+                    // is not the case, the upgraders were not executed in the correct order.
+                    assert_eq!(
+                        to - from,
+                        conn.query_row(
+                            "SELECT COUNT(test_field) FROM persistent.test
+                             WHERE id = test_field - ?;",
+                            params![from],
+                            |row| row.get(0)
+                        )
+                        .unwrap()
+                    );
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn create_or_get_version_new_database() {
+        let mut conn = Connection::open_in_memory().unwrap();
+        conn.execute("ATTACH DATABASE 'file::memory:' as persistent;", NO_PARAMS).unwrap();
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 3).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 3);
+        }
+
+        // Was the version table created as expected?
+        assert_eq!(
+            Ok("version".to_owned()),
+            conn.query_row(
+                "SELECT name FROM persistent.sqlite_master
+                 WHERE type = 'table' AND name = 'version';",
+                NO_PARAMS,
+                |row| row.get(0),
+            )
+        );
+
+        // There is exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // The version must be set to 3
+        assert_eq!(
+            Ok(3),
+            conn.query_row(
+                "SELECT version from persistent.version WHERE id = 0;",
+                NO_PARAMS,
+                |row| row.get(0)
+            )
+        );
+
+        // Will subsequent calls to create_or_get_version still return the same version even
+        // if the current version changes.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 5).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 3);
+        }
+
+        // There is still exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // Bump the version.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            update_version(&tx, 5).unwrap();
+            tx.commit().unwrap();
+        }
+
+        // Now the version should have changed.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 7).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 5);
+        }
+
+        // There is still exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // The version must be set to 5
+        assert_eq!(
+            Ok(5),
+            conn.query_row(
+                "SELECT version from persistent.version WHERE id = 0;",
+                NO_PARAMS,
+                |row| row.get(0)
+            )
+        );
+    }
+
+    #[test]
+    fn create_or_get_version_legacy_database() {
+        let mut conn = Connection::open_in_memory().unwrap();
+        conn.execute("ATTACH DATABASE 'file::memory:' as persistent;", NO_PARAMS).unwrap();
+        // A legacy (version 0) database is detected if the keyentry table exists but no
+        // version table.
+        conn.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,
+        )
+        .unwrap();
+
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 3).unwrap();
+            tx.commit().unwrap();
+            // In the legacy case, version 0 must be returned.
+            assert_eq!(version, 0);
+        }
+
+        // Was the version table created as expected?
+        assert_eq!(
+            Ok("version".to_owned()),
+            conn.query_row(
+                "SELECT name FROM persistent.sqlite_master
+                 WHERE type = 'table' AND name = 'version';",
+                NO_PARAMS,
+                |row| row.get(0),
+            )
+        );
+
+        // There is exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // The version must be set to 0
+        assert_eq!(
+            Ok(0),
+            conn.query_row(
+                "SELECT version from persistent.version WHERE id = 0;",
+                NO_PARAMS,
+                |row| row.get(0)
+            )
+        );
+
+        // Will subsequent calls to create_or_get_version still return the same version even
+        // if the current version changes.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 5).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 0);
+        }
+
+        // There is still exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // Bump the version.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            update_version(&tx, 5).unwrap();
+            tx.commit().unwrap();
+        }
+
+        // Now the version should have changed.
+        {
+            let tx = conn.transaction_with_behavior(TransactionBehavior::Immediate).unwrap();
+            let version = create_or_get_version(&tx, 7).unwrap();
+            tx.commit().unwrap();
+            assert_eq!(version, 5);
+        }
+
+        // There is still exactly one row in the version table.
+        assert_eq!(
+            Ok(1),
+            conn.query_row("SELECT COUNT(id) from persistent.version;", NO_PARAMS, |row| row
+                .get(0))
+        );
+
+        // The version must be set to 5
+        assert_eq!(
+            Ok(5),
+            conn.query_row(
+                "SELECT version from persistent.version WHERE id = 0;",
+                NO_PARAMS,
+                |row| row.get(0)
+            )
+        );
+    }
+}
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
index cc59c32..997e739 100644
--- a/keystore2/src/enforcements.rs
+++ b/keystore2/src/enforcements.rs
@@ -14,32 +14,35 @@
 
 //! This is the Keystore 2.0 Enforcements module.
 // TODO: more description to follow.
-use crate::database::{AuthTokenEntry, MonotonicRawTime};
 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,
+    TimeStampToken::TimeStampToken,
 };
+use android_security_authorization::aidl::android::security::authorization::ResponseCode::ResponseCode as AuthzResponseCode;
 use android_system_keystore2::aidl::android::system::keystore2::{
-    IKeystoreSecurityLevel::KEY_FLAG_AUTH_BOUND_WITHOUT_CRYPTOGRAPHIC_LSKF_BINDING,
+    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::sync::{
-    mpsc::{channel, Receiver, Sender},
-    Arc, Mutex, Weak,
-};
-use std::time::SystemTime;
 use std::{
     collections::{HashMap, HashSet},
-    sync::mpsc::TryRecvError,
+    sync::{
+        mpsc::{channel, Receiver, Sender, TryRecvError},
+        Arc, Mutex, Weak,
+    },
+    time::SystemTime,
 };
 
 #[derive(Debug)]
@@ -57,47 +60,54 @@
     state: AuthRequestState,
     /// This need to be set to Some to fulfill a AuthRequestState::OpAuth or
     /// AuthRequestState::TimeStampedOpAuth.
-    hat: Option<HardwareAuthToken>,
+    hat: Mutex<Option<HardwareAuthToken>>,
 }
 
+unsafe impl Sync for AuthRequest {}
+
 impl AuthRequest {
-    fn op_auth() -> Arc<Mutex<Self>> {
-        Arc::new(Mutex::new(Self { state: AuthRequestState::OpAuth, hat: None }))
+    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<Mutex<Self>> {
-        Arc::new(Mutex::new(Self {
+    fn timestamped_op_auth(receiver: Receiver<Result<TimeStampToken, Error>>) -> Arc<Self> {
+        Arc::new(Self {
             state: AuthRequestState::TimeStampedOpAuth(receiver),
-            hat: None,
-        }))
+            hat: Mutex::new(None),
+        })
     }
 
     fn timestamp(
         hat: HardwareAuthToken,
         receiver: Receiver<Result<TimeStampToken, Error>>,
-    ) -> Arc<Mutex<Self>> {
-        Arc::new(Mutex::new(Self { state: AuthRequestState::TimeStamp(receiver), hat: Some(hat) }))
+    ) -> Arc<Self> {
+        Arc::new(Self { state: AuthRequestState::TimeStamp(receiver), hat: Mutex::new(Some(hat)) })
     }
 
-    fn add_auth_token(&mut self, hat: HardwareAuthToken) {
-        self.hat = Some(hat)
+    fn add_auth_token(&self, hat: HardwareAuthToken) {
+        *self.hat.lock().unwrap() = Some(hat)
     }
 
-    fn get_auth_tokens(&mut self) -> Result<(HardwareAuthToken, Option<TimeStampToken>)> {
-        match (&self.state, self.hat.is_some()) {
-            (AuthRequestState::OpAuth, true) => Ok((self.hat.take().unwrap(), None)),
-            (AuthRequestState::TimeStampedOpAuth(recv), true)
-            | (AuthRequestState::TimeStamp(recv), true) => {
+    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.")?;
-                let tst = result.context(concat!(
+                Some(result.context(concat!(
                     "In get_auth_tokens: Worker responded with error ",
                     "from generating timestamp token."
-                ))?;
-                Ok((self.hat.take().unwrap(), Some(tst)))
+                ))?)
             }
-            (_, false) => Err(Error::Km(ErrorCode::KEY_USER_NOT_AUTHENTICATED))
-                .context("In get_auth_tokens: No operation auth token received."),
-        }
+            AuthRequestState::OpAuth => None,
+        };
+        Ok((hat, tst))
     }
 }
 
@@ -123,7 +133,7 @@
     /// 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<Mutex<AuthRequest>>),
+    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>),
@@ -165,9 +175,15 @@
     const CLEANUP_PERIOD: u8 = 25;
 
     pub fn add_auth_token(&self, hat: HardwareAuthToken) {
-        let mut map = self.map_and_cleanup_counter.lock().unwrap();
-        let (ref mut map, _) = *map;
-        if let Some((_, recv)) = map.remove_entry(&hat.challenge) {
+        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);
         }
     }
@@ -187,7 +203,7 @@
 }
 
 #[derive(Debug)]
-struct TokenReceiver(Weak<Mutex<AuthRequest>>);
+struct TokenReceiver(Weak<AuthRequest>);
 
 impl TokenReceiver {
     fn is_obsolete(&self) -> bool {
@@ -196,20 +212,16 @@
 
     fn add_auth_token(&self, hat: HardwareAuthToken) {
         if let Some(state_arc) = self.0.upgrade() {
-            let mut state = state_arc.lock().unwrap();
-            state.add_auth_token(hat);
+            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.");
+    let dev = get_timestamp_service().expect(concat!(
+        "Secure Clock service must be present ",
+        "if TimeStampTokens are required."
+    ));
     map_binder_status(dev.generateTimeStamp(challenge))
 }
 
@@ -217,7 +229,7 @@
     if let Err(e) = sender.send(get_timestamp_token(challenge)) {
         log::info!(
             concat!(
-                "In timestamp_token_request: Operation hung up ",
+                "In timestamp_token_request: Receiver hung up ",
                 "before timestamp token could be delivered. {:?}"
             ),
             e
@@ -322,8 +334,7 @@
     /// 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 {
-            let mut state = auth_request.lock().unwrap();
-            Some(state.get_auth_tokens().context("In AuthInfo::get_auth_tokens.")?)
+            Some(auth_request.get_auth_tokens().context("In AuthInfo::get_auth_tokens.")?)
         } else {
             None
         };
@@ -352,6 +363,7 @@
 }
 
 /// 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.
@@ -368,15 +380,6 @@
 }
 
 impl Enforcements {
-    /// Creates an enforcement object with the two data structures it holds and the sender as None.
-    pub fn new() -> Self {
-        Enforcements {
-            device_unlocked_set: Mutex::new(HashSet::new()),
-            op_auth_map: Default::default(),
-            confirmation_token_receiver: Default::default(),
-        }
-    }
-
     /// 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.
@@ -475,6 +478,7 @@
         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
@@ -541,6 +545,9 @@
                 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
@@ -594,6 +601,13 @@
             }
         }
 
+        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,
@@ -620,8 +634,7 @@
                 } 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))
@@ -664,9 +677,10 @@
             // 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) => {
-                (None, DeferredAuthState::TimeStampRequired(hat.take_auth_token()))
-            }
+            (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)
             }
@@ -681,15 +695,11 @@
         })
     }
 
-    fn find_auth_token<F>(p: F) -> Result<Option<(AuthTokenEntry, MonotonicRawTime)>>
+    fn find_auth_token<F>(p: F) -> 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.")
+        DB.with(|db| db.borrow().find_auth_token_entry(p))
     }
 
     /// Checks if the time now since epoch is greater than (or equal, if is_given_time_inclusive is
@@ -733,11 +743,9 @@
     /// 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.")?;
-
+    pub fn add_auth_token(&self, hat: HardwareAuthToken) {
+        DB.with(|db| db.borrow_mut().insert_auth_token(&hat));
         self.op_auth_map.add_auth_token(hat);
-        Ok(())
     }
 
     /// This allows adding an entry to the op_auth_map, indexed by the operation challenge.
@@ -749,22 +757,98 @@
     }
 
     /// Given the set of key parameters and flags, check if super encryption is required.
-    pub fn super_encryption_required(key_parameters: &[KeyParameter], flags: Option<i32>) -> bool {
-        let auth_bound = key_parameters.iter().any(|kp| kp.get_tag() == Tag::USER_SECURE_ID);
-
-        let skip_lskf_binding = if let Some(flags) = flags {
-            (flags & KEY_FLAG_AUTH_BOUND_WITHOUT_CRYPTOGRAPHIC_LSKF_BINDING) != 0
-        } else {
-            false
-        };
-
-        auth_bound && !skip_lskf_binding
+    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
     }
-}
 
-impl Default for Enforcements {
-    fn default() -> Self {
-        Self::new()
+    /// 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)
+        });
+
+        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();
+                let result = Self::find_auth_token(|auth_token_entry: &AuthTokenEntry| {
+                    let token_valid = now_in_millis
+                        .checked_sub(&auth_token_entry.time_received())
+                        .map_or(false, |token_age_in_millis| {
+                            auth_token_max_age_millis > token_age_in_millis.milliseconds()
+                        });
+                    token_valid && auth_token_entry.satisfies(&sids, auth_type)
+                });
+
+                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(
+                    concat!(
+                        "In get_auth_tokens: No auth token found for ",
+                        "the given challenge and 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))
     }
 }
 
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
index d67f5f4..f969cb6 100644
--- a/keystore2/src/error.rs
+++ b/keystore2/src/error.rs
@@ -30,16 +30,13 @@
 //! Keystore functions should use `anyhow::Result` to return error conditions, and
 //! context should be added every time an error is forwarded.
 
-use std::cmp::PartialEq;
-
 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 keystore2_selinux as selinux;
-
 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.
@@ -140,7 +137,7 @@
 /// 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.
+/// 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
@@ -171,31 +168,64 @@
 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| {
-            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::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,
-                },
-            };
+            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 {
 
diff --git a/keystore2/src/fuzzers/Android.bp b/keystore2/src/fuzzers/Android.bp
new file mode 100644
index 0000000..384ab77
--- /dev/null
+++ b/keystore2/src/fuzzers/Android.bp
@@ -0,0 +1,29 @@
+// 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_fuzz {
+    name: "legacy_blob_fuzzer",
+    srcs: ["legacy_blob_fuzzer.rs"],
+    rustlibs: [
+        "libkeystore2",
+    ],
+    fuzz_config: {
+        fuzz_on_haiku_device: true,
+        fuzz_on_haiku_host: false,
+    },
+}
diff --git a/keystore2/src/fuzzers/legacy_blob_fuzzer.rs b/keystore2/src/fuzzers/legacy_blob_fuzzer.rs
new file mode 100644
index 0000000..7e3e848
--- /dev/null
+++ b/keystore2/src/fuzzers/legacy_blob_fuzzer.rs
@@ -0,0 +1,26 @@
+// 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.
+
+#![allow(missing_docs)]
+#![no_main]
+#[macro_use]
+extern crate libfuzzer_sys;
+use keystore2::legacy_blob::LegacyBlobLoader;
+
+fuzz_target!(|data: &[u8]| {
+    if !data.is_empty() {
+        let string = data.iter().filter_map(|c| std::char::from_u32(*c as u32)).collect::<String>();
+        let _res = LegacyBlobLoader::decode_alias(&string);
+    }
+});
diff --git a/keystore2/src/gc.rs b/keystore2/src/gc.rs
index 6cc0f27..25f08c8 100644
--- a/keystore2/src/gc.rs
+++ b/keystore2/src/gc.rs
@@ -20,22 +20,28 @@
 
 use crate::{
     async_task,
-    database::{KeystoreDB, Uuid},
+    database::{BlobMetaData, KeystoreDB, Uuid},
     super_key::SuperKeyManager,
 };
 use anyhow::{Context, Result};
 use async_task::AsyncTask;
-use std::sync::Arc;
+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 and a database connection.
-    /// Both 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.
+    /// 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() -> (
@@ -46,34 +52,43 @@
             + '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 {
-                blob_id_to_delete: None,
+                deleted_blob_ids: vec![],
+                superseded_blobs: vec![],
                 invalidate_key,
                 db,
                 async_task: weak_at,
                 super_key,
+                notified,
             });
         });
-        Self { async_task }
+        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) {
-        self.async_task.queue_lo(|shelf| shelf.get_downcast_mut::<GcInternal>().unwrap().step())
+        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 {
-    blob_id_to_delete: Option<i64>,
+    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 {
@@ -81,16 +96,23 @@
     /// 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 let Some((blob_id, blob, blob_metadata)) = self
-            .db
-            .handle_next_superseded_blob(self.blob_id_to_delete.take())
-            .context("In process_one_key: Trying to handle superseded blob.")?
-        {
-            // Set the blob_id as the next to be deleted blob. So it will be
+        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.blob_id_to_delete = Some(blob_id);
+            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.
@@ -101,7 +123,7 @@
                     .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)
+                (self.invalidate_key)(uuid, &*blob)
                     .context("In process_one_key: Trying to invalidate key.")?;
             }
         }
@@ -110,13 +132,20 @@
 
     /// 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.blob_id_to_delete.is_some() {
+        if !self.deleted_blob_ids.is_empty() {
             if let Some(at) = self.async_task.upgrade() {
-                at.queue_lo(move |shelf| shelf.get_downcast_mut::<GcInternal>().unwrap().step());
+                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
index 9668ee3..eae5ad0 100644
--- a/keystore2/src/globals.rs
+++ b/keystore2/src/globals.rs
@@ -20,7 +20,7 @@
 use crate::legacy_blob::LegacyBlobLoader;
 use crate::legacy_migrator::LegacyMigrator;
 use crate::super_key::SuperKeyManager;
-use crate::utils::Asp;
+use crate::utils::watchdog as wd;
 use crate::{async_task::AsyncTask, database::MonotonicRawTime};
 use crate::{
     database::KeystoreDB,
@@ -32,11 +32,16 @@
     IKeyMintDevice::IKeyMintDevice, IRemotelyProvisionedComponent::IRemotelyProvisionedComponent,
     KeyMintHardwareInfo::KeyMintHardwareInfo, SecurityLevel::SecurityLevel,
 };
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
+    ISecureClock::ISecureClock,
+};
 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::sync::{Arc, Mutex, RwLock};
 use std::{cell::RefCell, sync::Once};
 use std::{collections::HashMap, path::Path, path::PathBuf};
 
@@ -51,27 +56,13 @@
 /// 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 gc = 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()?;
-                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(),
-        )
-    });
+    let db_path = DB_PATH.read().expect("Could not get the database directory.");
 
-    let mut db =
-        KeystoreDB::new(&DB_PATH.lock().expect("Could not get the database directory."), Some(gc))
-            .expect("Failed to open database.");
+    let mut db = KeystoreDB::new(&db_path, 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.");
+        db.insert_last_off_body(MonotonicRawTime::now());
         log::info!("Calling cleanup leftovers.");
         let n = db.cleanup_leftovers().expect("Failed to cleanup database on startup.");
         if n != 0 {
@@ -96,30 +87,33 @@
             RefCell::new(create_thread_local_db());
 }
 
-#[derive(Default)]
-struct DevicesMap {
-    devices_by_uuid: HashMap<Uuid, (Asp, KeyMintHardwareInfo)>,
+struct DevicesMap<T: FromIBinder + ?Sized> {
+    devices_by_uuid: HashMap<Uuid, (Strong<T>, KeyMintHardwareInfo)>,
     uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
 }
 
-impl DevicesMap {
+impl<T: FromIBinder + ?Sized> DevicesMap<T> {
     fn dev_by_sec_level(
         &self,
         sec_level: &SecurityLevel,
-    ) -> Option<(Asp, KeyMintHardwareInfo, Uuid)> {
+    ) -> Option<(Strong<T>, 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)> {
+    fn dev_by_uuid(&self, uuid: &Uuid) -> Option<(Strong<T>, KeyMintHardwareInfo, Uuid)> {
         self.devices_by_uuid
             .get(uuid)
             .map(|(dev, hw_info)| ((*dev).clone(), (*hw_info).clone(), *uuid))
     }
 
+    fn devices(&self) -> Vec<Strong<T>> {
+        self.devices_by_uuid.values().map(|(dev, _)| dev.clone()).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) {
+    fn insert(&mut self, sec_level: SecurityLevel, dev: Strong<T>, 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();
@@ -128,45 +122,77 @@
     }
 }
 
-#[derive(Default)]
-struct RemotelyProvisionedDevicesMap {
-    devices_by_sec_level: HashMap<SecurityLevel, Asp>,
+impl<T: FromIBinder + ?Sized> Default for DevicesMap<T> {
+    fn default() -> Self {
+        Self {
+            devices_by_uuid: HashMap::<Uuid, (Strong<T>, KeyMintHardwareInfo)>::new(),
+            uuid_by_sec_level: Default::default(),
+        }
+    }
 }
 
-impl RemotelyProvisionedDevicesMap {
-    fn dev_by_sec_level(&self, sec_level: &SecurityLevel) -> Option<Asp> {
+struct RemotelyProvisionedDevicesMap<T: FromIBinder + ?Sized> {
+    devices_by_sec_level: HashMap<SecurityLevel, Strong<T>>,
+}
+
+impl<T: FromIBinder + ?Sized> Default for RemotelyProvisionedDevicesMap<T> {
+    fn default() -> Self {
+        Self { devices_by_sec_level: HashMap::<SecurityLevel, Strong<T>>::new() }
+    }
+}
+
+impl<T: FromIBinder + ?Sized> RemotelyProvisionedDevicesMap<T> {
+    fn dev_by_sec_level(&self, sec_level: &SecurityLevel) -> Option<Strong<T>> {
         self.devices_by_sec_level.get(sec_level).map(|dev| (*dev).clone())
     }
 
-    fn insert(&mut self, sec_level: SecurityLevel, dev: Asp) {
+    fn insert(&mut self, sec_level: SecurityLevel, dev: Strong<T>) {
         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(
+    pub static ref DB_PATH: RwLock<PathBuf> = RwLock::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();
+    static ref KEY_MINT_DEVICES: Mutex<DevicesMap<dyn IKeyMintDevice>> = Default::default();
     /// Timestamp service.
-    static ref TIME_STAMP_DEVICE: Mutex<Option<Asp>> = Default::default();
+    static ref TIME_STAMP_DEVICE: Mutex<Option<Strong<dyn ISecureClock>>> = Default::default();
     /// RemotelyProvisionedComponent HAL devices.
-    static ref REMOTELY_PROVISIONED_COMPONENT_DEVICES: Mutex<RemotelyProvisionedDevicesMap> = Default::default();
+    static ref REMOTELY_PROVISIONED_COMPONENT_DEVICES:
+            Mutex<RemotelyProvisionedDevicesMap<dyn IRemotelyProvisionedComponent>> =
+                    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 = Enforcements::new();
+    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.")));
+        &DB_PATH.read().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(ASYNC_TASK.clone()));
+        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 = get_keymint_dev_by_uuid(uuid).map(|(dev, _)| dev)?;
+                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.read().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";
@@ -174,44 +200,76 @@
 /// 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)> {
+fn connect_keymint(
+    security_level: &SecurityLevel,
+) -> Result<(Strong<dyn IKeyMintDevice>, KeyMintHardwareInfo)> {
+    let keymint_instances =
+        get_aidl_instances("android.hardware.security.keymint", 1, "IKeyMintDevice");
+
     let service_name = match *security_level {
-        SecurityLevel::TRUSTED_ENVIRONMENT => format!("{}/default", KEYMINT_SERVICE_NAME),
-        SecurityLevel::STRONGBOX => format!("{}/strongbox", KEYMINT_SERVICE_NAME),
+        SecurityLevel::TRUSTED_ENVIRONMENT => {
+            if keymint_instances.iter().any(|instance| *instance == "default") {
+                Some(format!("{}/default", KEYMINT_SERVICE_NAME))
+            } else {
+                None
+            }
+        }
+        SecurityLevel::STRONGBOX => {
+            if keymint_instances.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 = map_binder_status_code(binder::get_interface(&service_name))
-        .context("In connect_keymint: Trying to connect to genuine KeyMint service.")
-        .or_else(|e| {
-            match e.root_cause().downcast_ref::<Error>() {
-                Some(Error::BinderTransaction(StatusCode::NAME_NOT_FOUND)) => {
-                    // This is a no-op if it was called before.
-                    keystore2_km_compat::add_keymint_device_service();
+    let (keymint, hal_version) = 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.")?,
+            Some(100i32), // The HAL version code for KeyMint V1 is 100.
+        )
+    } 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.")
-                }
-                _ => Err(e),
-            }
-        })?;
+        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.")?,
+            None,
+        )
+    };
 
-    let hw_info = map_km_error(keymint.getHardwareInfo())
+    let wp = wd::watch_millis("In connect_keymint: calling getHardwareInfo()", 500);
+    let mut 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))
+    // The legacy wrapper sets hw_info.versionNumber to the underlying HAL version like so:
+    // 10 * <major> + <minor>, e.g., KM 3.0 = 30. So 30, 40, and 41 are the only viable values.
+    // For KeyMint the versionNumber is implementation defined and thus completely meaningless
+    // to Keystore 2.0. So at this point the versionNumber field is set to the HAL version, so
+    // that higher levels have a meaningful guide as to which feature set to expect from the
+    // implementation. As of this writing the only meaningful version number is 100 for KeyMint V1,
+    // and future AIDL versions should follow the pattern <AIDL version> * 100.
+    if let Some(hal_version) = hal_version {
+        hw_info.versionNumber = hal_version;
+    }
+
+    Ok((keymint, hw_info))
 }
 
 /// Get a keymint device for the given security level either from our cache or
@@ -219,9 +277,9 @@
 /// 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)> {
+) -> Result<(Strong<dyn IKeyMintDevice>, 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) {
+    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.")?;
@@ -235,7 +293,9 @@
 /// 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)> {
+pub fn get_keymint_dev_by_uuid(
+    uuid: &Uuid,
+) -> Result<(Strong<dyn IKeyMintDevice>, 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))
@@ -244,46 +304,53 @@
     }
 }
 
+/// 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 = map_binder_status_code(binder::get_interface(TIME_STAMP_SERVICE_NAME))
-        .context("In connect_secureclock: Trying to connect to genuine secure clock service.")
-        .or_else(|e| {
-            match e.root_cause().downcast_ref::<Error>() {
-                Some(Error::BinderTransaction(StatusCode::NAME_NOT_FOUND)) => {
-                    // This is a no-op if it was called before.
-                    keystore2_km_compat::add_keymint_device_service();
+fn connect_secureclock() -> Result<Strong<dyn ISecureClock>> {
+    let secureclock_instances =
+        get_aidl_instances("android.hardware.security.secureclock", 1, "ISecureClock");
 
-                    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.",
-                            )?;
+    let secure_clock_available =
+        secureclock_instances.iter().any(|instance| *instance == "default");
 
-                    // 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.")
+    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)
                 }
-                _ => Err(e),
-            }
-        })?;
+                e => e,
+            })
+            .context("In connect_secureclock: Trying to get Legacy wrapper.")
+    }?;
 
-    Ok(Asp::new(secureclock.as_binder()))
+    Ok(secureclock)
 }
 
 /// Get the timestamp service that verifies auth token timeliness towards security levels with
 /// different clocks.
-pub fn get_timestamp_service() -> Result<Asp> {
+pub fn get_timestamp_service() -> Result<Strong<dyn ISecureClock>> {
     let mut ts_device = TIME_STAMP_DEVICE.lock().unwrap();
     if let Some(dev) = &*ts_device {
         Ok(dev.clone())
@@ -297,19 +364,31 @@
 static REMOTE_PROVISIONING_HAL_SERVICE_NAME: &str =
     "android.hardware.security.keymint.IRemotelyProvisionedComponent";
 
-fn connect_remotely_provisioned_component(security_level: &SecurityLevel) -> Result<Asp> {
+fn connect_remotely_provisioned_component(
+    security_level: &SecurityLevel,
+) -> Result<Strong<dyn IRemotelyProvisionedComponent>> {
+    let remotely_prov_instances =
+        get_aidl_instances("android.hardware.security.keymint", 1, "IRemotelyProvisionedComponent");
+
     let service_name = match *security_level {
         SecurityLevel::TRUSTED_ENVIRONMENT => {
-            format!("{}/default", REMOTE_PROVISIONING_HAL_SERVICE_NAME)
+            if remotely_prov_instances.iter().any(|instance| *instance == "default") {
+                Some(format!("{}/default", REMOTE_PROVISIONING_HAL_SERVICE_NAME))
+            } else {
+                None
+            }
         }
-        SecurityLevel::STRONGBOX => format!("{}/strongbox", REMOTE_PROVISIONING_HAL_SERVICE_NAME),
-        _ => {
-            // Given the integration of IRemotelyProvisionedComponent with KeyMint, it is reasonable
-            // to return HARDWARE_TYPE_UNAVAILABLE as a Km error if it cannot be found.
-            return Err(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
-                .context("In connect_remotely_provisioned_component.");
+        SecurityLevel::STRONGBOX => {
+            if remotely_prov_instances.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))
@@ -318,14 +397,16 @@
                 " RemotelyProvisionedComponent service."
             ))
             .map_err(|e| e)?;
-    Ok(Asp::new(rem_prov_hal.as_binder()))
+    Ok(rem_prov_hal)
 }
 
 /// 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> {
+pub fn get_remotely_provisioned_component(
+    security_level: &SecurityLevel,
+) -> Result<Strong<dyn IRemotelyProvisionedComponent>> {
     let mut devices_map = REMOTELY_PROVISIONED_COMPONENT_DEVICES.lock().unwrap();
-    if let Some(dev) = devices_map.dev_by_sec_level(&security_level) {
+    if let Some(dev) = devices_map.dev_by_sec_level(security_level) {
         Ok(dev)
     } else {
         let dev = connect_remotely_provisioned_component(security_level)
diff --git a/keystore2/src/id_rotation.rs b/keystore2/src/id_rotation.rs
new file mode 100644
index 0000000..e3992d8
--- /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
index 117dea8..771d609 100644
--- a/keystore2/src/key_parameter.rs
+++ b/keystore2/src/key_parameter.rs
@@ -92,7 +92,7 @@
 
 use std::convert::TryInto;
 
-use crate::db_utils::SqlField;
+use crate::database::utils::SqlField;
 use crate::error::Error as KeystoreError;
 use crate::error::ResponseCode;
 
@@ -599,9 +599,9 @@
         ], [$($in)*]
     }};
     (@into $enum_name:ident, [$($out:tt)*], []) => {
-        impl Into<KmKeyParameter> for $enum_name {
-            fn into(self) -> KmKeyParameter {
-                match self {
+        impl From<$enum_name> for KmKeyParameter {
+            fn from(x: $enum_name) -> Self {
+                match x {
                     $($out)*
                 }
             }
@@ -776,7 +776,7 @@
 
 implement_key_parameter_value! {
 /// KeyParameterValue holds a value corresponding to one of the Tags defined in
-/// the AIDL spec at hardware/interfaces/keymint
+/// the AIDL spec at hardware/interfaces/security/keymint
 #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
 pub enum KeyParameterValue {
     /// Associated with Tag:INVALID
@@ -825,6 +825,9 @@
     /// When deleted, the key is guaranteed to be permanently deleted and unusable
     #[key_param(tag = ROLLBACK_RESISTANCE, field = BoolValue)]
     RollbackResistance,
+    /// The Key shall only be used during the early boot stage
+    #[key_param(tag = EARLY_BOOT_ONLY, field = BoolValue)]
+    EarlyBootOnly,
     /// The date and time at which the key becomes active
     #[key_param(tag = ACTIVE_DATETIME, field = DateTime)]
     ActiveDateTime(i64),
@@ -965,6 +968,9 @@
     /// 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),
 }
 }
 
@@ -1384,11 +1390,11 @@
             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(
+        KeyParameter::new_from_sql(
             Tag(row.get(0)?),
             &SqlField::new(1, row),
             SecurityLevel(row.get(2)?),
-        )?)
+        )
     }
 }
 
diff --git a/keystore2/src/keystore2_main.rs b/keystore2/src/keystore2_main.rs
index 9dc59a2..abab4b6 100644
--- a/keystore2/src/keystore2_main.rs
+++ b/keystore2/src/keystore2_main.rs
@@ -14,20 +14,27 @@
 
 //! This crate implements the Keystore 2.0 service entry point.
 
-use keystore2::apc::ApcManager;
-use keystore2::authorization::AuthorizationManager;
+use keystore2::entropy;
 use keystore2::globals::ENFORCEMENTS;
+use keystore2::maintenance::Maintenance;
+use keystore2::metrics::Metrics;
+use keystore2::metrics_store;
 use keystore2::remote_provisioning::RemoteProvisioningService;
 use keystore2::service::KeystoreService;
-use keystore2::user_manager::UserManager;
+use keystore2::{apc::ApcManager, shared_secret_negotiation};
+use keystore2::{authorization::AuthorizationManager, id_rotation::IdRotationState};
+use legacykeystore::LegacyKeystore;
 use log::{error, info};
-use std::{panic, path::Path, sync::mpsc::channel};
+use rusqlite::trace as sqlite_trace;
+use std::{os::raw::c_int, panic, path::Path, sync::mpsc::channel};
 
-static KS2_SERVICE_NAME: &str = "android.system.keystore2";
+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 METRICS_SERVICE_NAME: &str = "android.security.metrics";
 static REMOTE_PROVISIONING_SERVICE_NAME: &str = "android.security.remoteprovisioning";
-static USER_MANAGER_SERVICE_NAME: &str = "android.security.usermanager";
+static USER_MANAGER_SERVICE_NAME: &str = "android.security.maintenance";
+static LEGACY_KEYSTORE_SERVICE_NAME: &str = "android.security.legacykeystore";
 
 /// Keystore 2.0 takes one argument which is a path indicating its designated working directory.
 fn main() {
@@ -43,32 +50,44 @@
     // 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?");
 
+    // This must happen early before any other sqlite operations.
+    log::info!("Setting up sqlite logging for keystore2");
+    fn sqlite_log_handler(err: c_int, message: &str) {
+        log::error!("[SQLITE3] {}: {}", err, message);
+    }
+    unsafe { sqlite_trace::config_log(Some(sqlite_log_handler)) }
+        .expect("Error setting sqlite log callback.");
+
+    // Write/update keystore.crash_count system property.
+    metrics_store::update_keystore_crash_sysprop();
+
     // 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).
-    if let Some(dir) = args.next() {
-        *keystore2::globals::DB_PATH.lock().expect("Could not lock DB_PATH.") =
-            Path::new(&dir).to_path_buf();
+    let id_rotation_state = if let Some(dir) = args.next() {
+        let db_path = Path::new(&dir);
+        *keystore2::globals::DB_PATH.write().expect("Could not lock DB_PATH.") =
+            db_path.to_path_buf();
+        IdRotationState::new(db_path)
     } else {
-        panic!("Must specify a working directory.");
-    }
+        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().unwrap_or_else(|e| {
+    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| {
@@ -91,15 +110,26 @@
             panic!("Failed to register service {} because of {:?}.", AUTHORIZATION_SERVICE_NAME, e);
         });
 
-    let usermanager_service = UserManager::new_native_binder().unwrap_or_else(|e| {
+    let (delete_listener, legacykeystore) = LegacyKeystore::new_native_binder(
+        &keystore2::globals::DB_PATH.read().expect("Could not get DB_PATH."),
+    );
+
+    let maintenance_service = Maintenance::new_native_binder(delete_listener).unwrap_or_else(|e| {
         panic!("Failed to create service {} because of {:?}.", USER_MANAGER_SERVICE_NAME, e);
     });
-    binder::add_service(USER_MANAGER_SERVICE_NAME, usermanager_service.as_binder()).unwrap_or_else(
+    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);
         },
     );
 
+    let metrics_service = Metrics::new_native_binder().unwrap_or_else(|e| {
+        panic!("Failed to create service {} because of {:?}.", METRICS_SERVICE_NAME, e);
+    });
+    binder::add_service(METRICS_SERVICE_NAME, metrics_service.as_binder()).unwrap_or_else(|e| {
+        panic!("Failed to register service {} because of {:?}.", METRICS_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() {
@@ -114,6 +144,16 @@
             );
         });
     }
+
+    binder::add_service(LEGACY_KEYSTORE_SERVICE_NAME, legacykeystore.as_binder()).unwrap_or_else(
+        |e| {
+            panic!(
+                "Failed to register service {} because of {:?}.",
+                LEGACY_KEYSTORE_SERVICE_NAME, e
+            );
+        },
+    );
+
     info!("Successfully registered Keystore 2.0 service.");
 
     info!("Joining thread pool now.");
diff --git a/keystore2/src/km_compat/Android.bp b/keystore2/src/km_compat/Android.bp
index 6b635ff..32406ae 100644
--- a/keystore2/src/km_compat/Android.bp
+++ b/keystore2/src/km_compat/Android.bp
@@ -57,16 +57,17 @@
         "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",
+        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
+        "android.hardware.security.sharedsecret-V1-ndk",
+        "android.security.compat-ndk",
+        "android.system.keystore2-V1-ndk",
         "libbase",
         "libbinder_ndk",
         "libcrypto",
         "libhidlbase",
         "libkeymaster4_1support",
+        "libkeymint",
         "libkeymint_support",
         "libkeystore2_crypto",
         "libutils",
@@ -77,10 +78,10 @@
     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",
+        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
+        "android.hardware.security.sharedsecret-V1-ndk",
+        "android.security.compat-ndk",
         "libbinder_ndk",
         "libcrypto",
         "libkm_compat",
@@ -106,11 +107,11 @@
         "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",
+        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
+        "android.hardware.security.sharedsecret-V1-ndk",
+        "android.security.compat-ndk",
+        "android.system.keystore2-V1-ndk",
         "libbase",
         "libbinder_ndk",
         "libcrypto",
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index b25cb0c..40ca554 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -17,9 +17,11 @@
 #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>
@@ -35,7 +37,9 @@
 #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;
@@ -104,7 +108,6 @@
     case Tag::EC_CURVE:
     case Tag::RSA_PUBLIC_EXPONENT:
     case Tag::RSA_OAEP_MGF_DIGEST:
-    case Tag::BLOB_USAGE_REQUIREMENTS:
     case Tag::BOOTLOADER_ONLY:
     case Tag::ROLLBACK_RESISTANCE:
     case Tag::EARLY_BOOT_ONLY:
@@ -134,6 +137,92 @@
     }
 }
 
+// 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);
+}
+
+// Removes 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;
+}
+
+// Inspects the given blob for prefixes.
+// Returns the blob stripped of the prefix if present. The boolean argument is true if the blob was
+// a software blob.
+std::pair<std::vector<uint8_t>, bool>
+dissectPrefixedKeyBlob(const std::vector<uint8_t>& prefixedBlob) {
+    auto [hasPrefix, isSoftware] = prefixedKeyBlobParsePrefix(prefixedBlob);
+    if (!hasPrefix) {
+        // Not actually prefixed, blob was probably persisted to disk prior to the
+        // prefixing code being introduced.
+        return {prefixedBlob, false};
+    }
+    return {std::vector<uint8_t>(prefixedBlob.begin() + kKeyBlobPrefixSize, prefixedBlob.end()),
+            isSoftware};
+}
+
 /*
  * 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
@@ -141,6 +230,8 @@
  */
 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:
@@ -213,54 +304,67 @@
 static std::vector<KeyCharacteristics>
 processLegacyCharacteristics(KeyMintSecurityLevel securityLevel,
                              const std::vector<KeyParameter>& genParams,
-                             const V4_0_KeyCharacteristics& legacyKc) {
+                             const V4_0_KeyCharacteristics& legacyKc, bool kmEnforcedOnly = false) {
 
-    KeyCharacteristics keystoreEnforced{KeyMintSecurityLevel::KEYSTORE,
-                                        convertKeyParametersFromLegacy(legacyKc.softwareEnforced)};
+    KeyCharacteristics kmEnforced{securityLevel, convertKeyParametersFromLegacy(
+                                                     securityLevel == KeyMintSecurityLevel::SOFTWARE
+                                                         ? legacyKc.softwareEnforced
+                                                         : legacyKc.hardwareEnforced)};
+
+    if (securityLevel == KeyMintSecurityLevel::SOFTWARE && legacyKc.hardwareEnforced.size() > 0) {
+        LOG(WARNING) << "Unexpected hardware enforced parameters.";
+    }
+
+    if (kmEnforcedOnly) {
+        return {kmEnforced};
+    }
+
+    KeyCharacteristics keystoreEnforced{KeyMintSecurityLevel::KEYSTORE, {}};
+
+    if (securityLevel != KeyMintSecurityLevel::SOFTWARE) {
+        // Don't include these tags on software backends, else they'd end up duplicated
+        // across both the keystore-enforced and software keymaster-enforced tags.
+        keystoreEnforced.authorizations = 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));
+    keystoreEnforced.authorizations.insert(keystoreEnforced.authorizations.end(),
+                                           std::begin(unsupported_requested),
+                                           std::end(unsupported_requested));
 
-    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};
+    return {kmEnforced, keystoreEnforced};
 }
 
 static V4_0_KeyFormat convertKeyFormatToLegacy(const KeyFormat& kf) {
     return static_cast<V4_0_KeyFormat>(kf);
 }
 
-static V4_0_HardwareAuthToken convertAuthTokenToLegacy(const HardwareAuthToken& at) {
+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.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;
+            at->authenticatorType);
+    legacyAt.timestamp = at->timestamp.milliSeconds;
+    legacyAt.mac = at->mac;
     return legacyAt;
 }
 
-static V4_0_VerificationToken convertTimestampTokenToLegacy(const TimeStampToken& tst) {
+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;
+    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;
+    legacyVt.mac = tst->mac;
     return legacyVt;
 }
 
@@ -309,20 +413,13 @@
 // KeyMintDevice implementation
 
 ScopedAStatus KeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* _aidl_return) {
-    // TODO: What do I do about the version number?  Is it the version of the device I get?
-    auto result = mDevice->getHardwareInfo([&](auto securityLevel, const auto& keymasterName,
-                                               const auto& keymasterAuthorName) {
-        securityLevel_ =
-            static_cast<::aidl::android::hardware::security::keymint::SecurityLevel>(securityLevel);
-
-        _aidl_return->securityLevel = securityLevel_;
-        _aidl_return->keyMintName = keymasterName;
-        _aidl_return->keyMintAuthorName = keymasterAuthorName;
-    });
-    if (!result.isOk()) {
-        LOG(ERROR) << __func__ << " transaction failed. " << result.description();
-        return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
-    }
+    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();
 }
 
@@ -335,17 +432,39 @@
     return convertErrorCode(result);
 }
 
-ScopedAStatus
-KeyMintDevice::generateKey(const std::vector<KeyParameter>& inKeyParams,
-                           const std::optional<AttestationKey>& /* in_attestationKey */,
-                           KeyCreationResult* out_creationResult) {
+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 = keyBlob;
+            out_creationResult->keyBlob = keyBlobPrefix(keyBlob, false);
             out_creationResult->keyCharacteristics =
                 processLegacyCharacteristics(securityLevel_, inKeyParams, keyCharacteristics);
         });
@@ -381,7 +500,8 @@
                                      [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
                                          const V4_0_KeyCharacteristics& keyCharacteristics) {
                                          errorCode = convert(error);
-                                         out_creationResult->keyBlob = keyBlob;
+                                         out_creationResult->keyBlob =
+                                             keyBlobPrefix(keyBlob, false);
                                          out_creationResult->keyCharacteristics =
                                              processLegacyCharacteristics(
                                                  securityLevel_, inKeyParams, keyCharacteristics);
@@ -408,20 +528,28 @@
 
 ScopedAStatus
 KeyMintDevice::importWrappedKey(const std::vector<uint8_t>& in_inWrappedKeyData,
-                                const std::vector<uint8_t>& in_inWrappingKeyBlob,  //
+                                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, in_inWrappingKeyBlob, in_inMaskingKey, legacyUnwrappingParams,
+        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 = keyBlob;
+            out_creationResult->keyBlob = keyBlobPrefix(keyBlob, false);
             out_creationResult->keyCharacteristics =
                 processLegacyCharacteristics(securityLevel_, {}, keyCharacteristics);
         });
@@ -437,11 +565,12 @@
                                         std::vector<uint8_t>* _aidl_return) {
     auto legacyUpgradeParams = convertKeyParametersToLegacy(in_inUpgradeParams);
     V4_0_ErrorCode errorCode;
+
     auto result =
-        mDevice->upgradeKey(in_inKeyBlobToUpgrade, legacyUpgradeParams,
+        mDevice->upgradeKey(prefixedKeyBlobRemovePrefix(in_inKeyBlobToUpgrade), legacyUpgradeParams,
                             [&](V4_0_ErrorCode error, const hidl_vec<uint8_t>& upgradedKeyBlob) {
                                 errorCode = error;
-                                *_aidl_return = upgradedKeyBlob;
+                                *_aidl_return = keyBlobPrefix(upgradedKeyBlob, false);
                             });
     if (!result.isOk()) {
         LOG(ERROR) << __func__ << " transaction failed. " << result.description();
@@ -450,8 +579,13 @@
     return convertErrorCode(errorCode);
 }
 
-ScopedAStatus KeyMintDevice::deleteKey(const std::vector<uint8_t>& in_inKeyBlob) {
-    auto result = mDevice->deleteKey(in_inKeyBlob);
+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);
@@ -475,13 +609,20 @@
 }
 
 ScopedAStatus KeyMintDevice::begin(KeyPurpose in_inPurpose,
-                                   const std::vector<uint8_t>& in_inKeyBlob,
+                                   const std::vector<uint8_t>& prefixedKeyBlob,
                                    const std::vector<KeyParameter>& in_inParams,
-                                   const HardwareAuthToken& in_inAuthToken,
+                                   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);
@@ -530,81 +671,155 @@
     }
 }
 
-ScopedAStatus KeyMintOperation::update(const std::optional<KeyParameterArray>& in_inParams,
-                                       const std::optional<std::vector<uint8_t>>& in_input,
-                                       const std::optional<HardwareAuthToken>& in_inAuthToken,
-                                       const std::optional<TimeStampToken>& in_inTimeStampToken,
-                                       std::optional<KeyParameterArray>* out_outParams,
-                                       std::optional<ByteArray>* out_output,
-                                       int32_t* _aidl_return) {
-    std::vector<V4_0_KeyParameter> legacyParams;
-    if (in_inParams.has_value()) {
-        legacyParams = convertKeyParametersToLegacy(in_inParams.value().params);
+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);
     }
-    auto input = in_input.value_or(std::vector<uint8_t>());
-    V4_0_HardwareAuthToken authToken;
-    if (in_inAuthToken.has_value()) {
-        authToken = convertAuthTokenToLegacy(in_inAuthToken.value());
+
+    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);
     }
-    V4_0_VerificationToken verificationToken;
-    if (in_inTimeStampToken.has_value()) {
-        verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value());
+    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>& prefixedKeyBlob, const std::vector<uint8_t>& appId,
+    const std::vector<uint8_t>& appData, std::vector<KeyCharacteristics>* keyCharacteristics) {
+    auto [strippedKeyBlob, isSoftware] = dissectPrefixedKeyBlob(prefixedKeyBlob);
+    if (isSoftware) {
+        return softKeyMintDevice_->getKeyCharacteristics(strippedKeyBlob, appId, appData,
+                                                         keyCharacteristics);
+    } else {
+        KMV1::ErrorCode km_error;
+        auto ret = mDevice->getKeyCharacteristics(
+            strippedKeyBlob, appId, appData,
+            [&](V4_0_ErrorCode errorCode, const V4_0_KeyCharacteristics& v40KeyCharacteristics) {
+                km_error = convert(errorCode);
+                *keyCharacteristics =
+                    processLegacyCharacteristics(securityLevel_, {} /* getParams */,
+                                                 v40KeyCharacteristics, true /* kmEnforcedOnly */);
+            });
+
+        if (!ret.isOk()) {
+            LOG(ERROR) << __func__ << " getKeyCharacteristics failed: " << ret.description();
+            return convertErrorCode(KMV1::ErrorCode::UNKNOWN_ERROR);
+        }
+        if (km_error != KMV1::ErrorCode::OK) {
+            LOG(ERROR) << __func__
+                       << " getKeyCharacteristics failed with code: " << toString(km_error);
+        }
+
+        return convertErrorCode(km_error);
     }
+}
+
+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, legacyParams, input, authToken, verificationToken,
-        [&](V4_0_ErrorCode error, uint32_t inputConsumed,
-            const hidl_vec<V4_0_KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
-            errorCode = convert(error);
-            out_outParams->emplace();
-            out_outParams->value().params = convertKeyParametersFromLegacy(outParams);
-            out_output->emplace();
-            out_output->value().data = output;
-            *_aidl_return = inputConsumed;
-        });
+        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();
-    }
+    if (errorCode != KMV1::ErrorCode::OK) mOperationSlot.freeSlot();
+
     return convertErrorCode(errorCode);
 }
 
-ScopedAStatus KeyMintOperation::finish(const std::optional<KeyParameterArray>& in_inParams,
-                                       const std::optional<std::vector<uint8_t>>& in_input,
-                                       const std::optional<std::vector<uint8_t>>& in_inSignature,
-                                       const std::optional<HardwareAuthToken>& in_authToken,
-                                       const std::optional<TimeStampToken>& in_inTimeStampToken,
-                                       std::optional<KeyParameterArray>* out_outParams,
-                                       std::vector<uint8_t>* _aidl_return) {
-    KMV1::ErrorCode errorCode;
-    std::vector<V4_0_KeyParameter> legacyParams;
-    if (in_inParams.has_value()) {
-        legacyParams = convertKeyParametersToLegacy(in_inParams.value().params);
+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_inSignature.value_or(std::vector<uint8_t>());
-    V4_0_HardwareAuthToken authToken;
-    if (in_authToken.has_value()) {
-        authToken = convertAuthTokenToLegacy(in_authToken.value());
+    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));
     }
-    V4_0_VerificationToken verificationToken;
-    if (in_inTimeStampToken.has_value()) {
-        verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value());
-    }
+
+    KMV1::ErrorCode errorCode;
     auto result = mDevice->finish(
-        mOperationHandle, legacyParams, input, signature, authToken, verificationToken,
-        [&](V4_0_ErrorCode error, const hidl_vec<V4_0_KeyParameter>& outParams,
-            const hidl_vec<uint8_t>& output) {
+        mOperationHandle, inParams, input, signature, authToken, verificationToken,
+        [&](V4_0_ErrorCode error, auto /* outParams */, const hidl_vec<uint8_t>& output) {
             errorCode = convert(error);
-            out_outParams->emplace();
-            out_outParams->value().params = convertKeyParametersFromLegacy(outParams);
-            *_aidl_return = output;
+            *out_output = output;
         });
+
     mOperationSlot.freeSlot();
     if (!result.isOk()) {
         LOG(ERROR) << __func__ << " transaction failed. " << result.description();
@@ -841,7 +1056,8 @@
 
 std::optional<KMV1::ErrorCode>
 KeyMintDevice::signCertificate(const std::vector<KeyParameter>& keyParams,
-                               const std::vector<uint8_t>& keyBlob, X509* cert) {
+                               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)) {
@@ -876,23 +1092,20 @@
                 kps.push_back(KMV1::makeKeyParameter(KMV1::TAG_PADDING, origPadding));
             }
             BeginResult beginResult;
-            auto error = begin(KeyPurpose::SIGN, keyBlob, kps, HardwareAuthToken(), &beginResult);
+            auto error =
+                begin(KeyPurpose::SIGN, prefixedKeyBlob, kps, HardwareAuthToken(), &beginResult);
             if (!error.isOk()) {
                 errorCode = toErrorCode(error);
                 return std::vector<uint8_t>();
             }
-            std::optional<KeyParameterArray> outParams;
-            std::optional<ByteArray> outByte;
-            int32_t status;
-            error = beginResult.operation->update(std::nullopt, dataVec, std::nullopt, std::nullopt,
-                                                  &outParams, &outByte, &status);
-            if (!error.isOk()) {
-                errorCode = toErrorCode(error);
-                return std::vector<uint8_t>();
-            }
+
             std::vector<uint8_t> result;
-            error = beginResult.operation->finish(std::nullopt, std::nullopt, std::nullopt,
-                                                  std::nullopt, std::nullopt, &outParams, &result);
+            error = beginResult.operation->finish(dataVec,                     //
+                                                  {} /* signature */,          //
+                                                  {} /* authToken */,          //
+                                                  {} /* timestampToken */,     //
+                                                  {} /* confirmationToken */,  //
+                                                  &result);
             if (!error.isOk()) {
                 errorCode = toErrorCode(error);
                 return std::vector<uint8_t>();
@@ -913,7 +1126,9 @@
 
 std::variant<std::vector<Certificate>, KMV1::ErrorCode>
 KeyMintDevice::getCertificate(const std::vector<KeyParameter>& keyParams,
-                              const std::vector<uint8_t>& keyBlob) {
+                              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) {
@@ -1011,14 +1226,14 @@
 // Copied from system/security/keystore/include/keystore/keymaster_types.h.
 
 // Changing this namespace alias will change the keymaster version.
-namespace keymaster = ::android::hardware::keymaster::V4_1;
+namespace keymasterNs = ::android::hardware::keymaster::V4_1;
 
-using keymaster::SecurityLevel;
+using keymasterNs::SecurityLevel;
 
 // Copied from system/security/keystore/KeyStore.h.
 
 using ::android::sp;
-using keymaster::support::Keymaster;
+using keymasterNs::support::Keymaster;
 
 template <typename T, size_t count> class Devices : public std::array<T, count> {
   public:
@@ -1043,8 +1258,8 @@
 // Copied from system/security/keystore/keystore_main.cpp.
 
 using ::android::hardware::hidl_string;
-using keymaster::support::Keymaster3;
-using keymaster::support::Keymaster4;
+using keymasterNs::support::Keymaster3;
+using keymasterNs::support::Keymaster4;
 
 template <typename Wrapper>
 KeymasterDevices enumerateKeymasterDevices(IServiceManager* serviceManager) {
@@ -1099,7 +1314,7 @@
     CHECK(serviceManager.get()) << "Failed to get ServiceManager";
     auto result = enumerateKeymasterDevices<Keymaster4>(serviceManager.get());
     auto softKeymaster = result[SecurityLevel::SOFTWARE];
-    if (!result[SecurityLevel::TRUSTED_ENVIRONMENT]) {
+    if ((!result[SecurityLevel::TRUSTED_ENVIRONMENT]) && (!result[SecurityLevel::STRONGBOX])) {
         result = enumerateKeymasterDevices<Keymaster3>(serviceManager.get());
     }
     if (softKeymaster) result[SecurityLevel::SOFTWARE] = softKeymaster;
@@ -1126,6 +1341,8 @@
     } else {
         setNumFreeSlots(15);
     }
+
+    softKeyMintDevice_.reset(CreateKeyMintDevice(KeyMintSecurityLevel::SOFTWARE));
 }
 
 sp<Keymaster> getDevice(KeyMintSecurityLevel securityLevel) {
@@ -1181,8 +1398,7 @@
         if (!device) {
             return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
         }
-        bool inserted = false;
-        std::tie(i, inserted) = mDeviceCache.insert({in_securityLevel, std::move(device)});
+        i = mDeviceCache.insert(i, {in_securityLevel, std::move(device)});
     }
     *_aidl_return = i->second;
     return ScopedAStatus::ok();
@@ -1190,19 +1406,20 @@
 
 ScopedAStatus KeystoreCompatService::getSharedSecret(KeyMintSecurityLevel in_securityLevel,
                                                      std::shared_ptr<ISharedSecret>* _aidl_return) {
-    if (!mSharedSecret) {
+    auto i = mSharedSecretCache.find(in_securityLevel);
+    if (i == mSharedSecretCache.end()) {
         auto secret = SharedSecret::createSharedSecret(in_securityLevel);
         if (!secret) {
             return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
         }
-        mSharedSecret = std::move(secret);
+        i = mSharedSecretCache.insert(i, {in_securityLevel, std::move(secret)});
     }
-    *_aidl_return = mSharedSecret;
+    *_aidl_return = i->second;
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus KeystoreCompatService::getSecureClock(std::shared_ptr<ISecureClock>* _aidl_return) {
-    if (!mSharedSecret) {
+    if (!mSecureClock) {
         // The legacy verification service was always provided by the TEE variant.
         auto clock = SecureClock::createSecureClock(KeyMintSecurityLevel::TRUSTED_ENVIRONMENT);
         if (!clock) {
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index 57a7bbd..2d892da 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -30,7 +30,6 @@
 
 using ::aidl::android::hardware::security::keymint::AttestationKey;
 using ::aidl::android::hardware::security::keymint::BeginResult;
-using ::aidl::android::hardware::security::keymint::ByteArray;
 using ::aidl::android::hardware::security::keymint::Certificate;
 using ::aidl::android::hardware::security::keymint::HardwareAuthToken;
 using ::aidl::android::hardware::security::keymint::KeyCharacteristics;
@@ -38,7 +37,6 @@
 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::KeyParameterArray;
 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;
@@ -111,14 +109,22 @@
     ScopedAStatus destroyAttestationIds() override;
     ScopedAStatus begin(KeyPurpose in_inPurpose, const std::vector<uint8_t>& in_inKeyBlob,
                         const std::vector<KeyParameter>& in_inParams,
-                        const HardwareAuthToken& in_inAuthToken,
+                        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);
 
@@ -128,6 +134,9 @@
     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 {
@@ -142,19 +151,22 @@
         : mDevice(device), mOperationHandle(operationHandle), mOperationSlot(slots, isActive) {}
     ~KeyMintOperation();
 
-    ScopedAStatus update(const std::optional<KeyParameterArray>& in_inParams,
-                         const std::optional<std::vector<uint8_t>>& in_input,
-                         const std::optional<HardwareAuthToken>& in_inAuthToken,
-                         const std::optional<TimeStampToken>& in_inTimestampToken,
-                         std::optional<KeyParameterArray>* out_outParams,
-                         std::optional<ByteArray>* out_output, int32_t* _aidl_return);
-    ScopedAStatus finish(const std::optional<KeyParameterArray>& in_inParams,
-                         const std::optional<std::vector<uint8_t>>& in_input,
-                         const std::optional<std::vector<uint8_t>>& in_inSignature,
-                         const std::optional<HardwareAuthToken>& in_authToken,
-                         const std::optional<TimeStampToken>& in_inTimestampToken,
-                         std::optional<KeyParameterArray>* out_outParams,
-                         std::vector<uint8_t>* _aidl_return);
+    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();
 };
 
@@ -185,7 +197,7 @@
 class KeystoreCompatService : public BnKeystoreCompatService {
   private:
     std::unordered_map<KeyMintSecurityLevel, std::shared_ptr<IKeyMintDevice>> mDeviceCache;
-    std::shared_ptr<ISharedSecret> mSharedSecret;
+    std::unordered_map<KeyMintSecurityLevel, std::shared_ptr<ISharedSecret>> mSharedSecretCache;
     std::shared_ptr<ISecureClock> mSecureClock;
 
   public:
diff --git a/keystore2/src/km_compat/km_compat_type_conversion.h b/keystore2/src/km_compat/km_compat_type_conversion.h
index b36b78a..de09477 100644
--- a/keystore2/src/km_compat/km_compat_type_conversion.h
+++ b/keystore2/src/km_compat/km_compat_type_conversion.h
@@ -503,9 +503,6 @@
             return V4_0::makeKeyParameter(V4_0::TAG_INCLUDE_UNIQUE_ID, v->get());
         }
         break;
-    case KMV1::Tag::BLOB_USAGE_REQUIREMENTS:
-        // This tag has been removed. Mapped on invalid.
-        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());
@@ -665,13 +662,19 @@
         }
         break;
     case KMV1::Tag::ATTESTATION_ID_SERIAL:
-        // TODO This tag is missing from 4.0 keymaster_tags.h
+        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:
-        // TODO This tag is missing from 4.0 keymaster_tags.h
+        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:
-        // TODO This tag is missing from 4.0 keymaster_tags.h
+        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)) {
@@ -740,6 +743,9 @@
     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};
 }
@@ -968,13 +974,19 @@
         }
         break;
     case V4_0::Tag::ATTESTATION_ID_SERIAL:
-        // TODO This tag is missing from 4.0 keymaster_tags.h
+        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:
-        // TODO This tag is missing from 4.0 keymaster_tags.h
+        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:
-        // TODO This tag is missing from 4.0 keymaster_tags.h
+        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 =
diff --git a/keystore2/src/km_compat/lib.rs b/keystore2/src/km_compat/lib.rs
index 22ddc31..8d7310b 100644
--- a/keystore2/src/km_compat/lib.rs
+++ b/keystore2/src/km_compat/lib.rs
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// TODO: Once this is stable, remove this and document everything public.
-#![allow(missing_docs)]
+//! 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() }
 }
@@ -29,10 +30,10 @@
     use super::*;
     use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
         Algorithm::Algorithm, BeginResult::BeginResult, BlockMode::BlockMode, Digest::Digest,
-        ErrorCode::ErrorCode, HardwareAuthToken::HardwareAuthToken, IKeyMintDevice::IKeyMintDevice,
-        KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat, KeyParameter::KeyParameter,
-        KeyParameterArray::KeyParameterArray, KeyParameterValue::KeyParameterValue,
-        KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
+        ErrorCode::ErrorCode, IKeyMintDevice::IKeyMintDevice, KeyCreationResult::KeyCreationResult,
+        KeyFormat::KeyFormat, KeyOrigin::KeyOrigin, 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;
@@ -259,7 +260,7 @@
         if let Some(mut extras) = extra_params {
             kps.append(&mut extras);
         }
-        let result = legacy.begin(purpose, &blob, &kps, &HardwareAuthToken::default());
+        let result = legacy.begin(purpose, blob, &kps, None);
         assert!(result.is_ok(), "{:?}", result);
         result.unwrap()
     }
@@ -283,41 +284,53 @@
 
         let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
         let operation = begin_result.operation.unwrap();
-        let params = KeyParameterArray {
-            params: vec![KeyParameter {
-                tag: Tag::ASSOCIATED_DATA,
-                value: KeyParameterValue::Blob(b"foobar".to_vec()),
-            }],
-        };
+
+        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 mut out_params = None;
-        let result =
-            operation.finish(Some(&params), Some(&message), None, None, None, &mut out_params);
+        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());
-        assert!(out_params.is_some());
 
         let begin_result =
             begin(legacy.as_ref(), &blob, KeyPurpose::DECRYPT, Some(begin_result.params));
+
         let operation = begin_result.operation.unwrap();
-        let mut out_params = None;
-        let mut output = None;
+
+        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(
-            Some(&params),
-            Some(&ciphertext),
-            None,
-            None,
-            &mut out_params,
-            &mut output,
+            &ciphertext,
+            None, /* authToken */
+            None, /* timestampToken */
         );
         assert!(result.is_ok(), "{:?}", result);
-        assert_eq!(result.unwrap(), message.len() as i32);
-        assert!(output.is_some());
-        assert_eq!(output.unwrap().data, message.to_vec());
-        let result = operation.finish(Some(&params), None, None, None, None, &mut out_params);
+        assert_eq!(result.unwrap(), message);
+        let result = operation.finish(
+            None, /* input */
+            None, /* signature */
+            None, /* authToken */
+            None, /* timestampToken */
+            None, /* confirmationToken */
+        );
         assert!(result.is_ok(), "{:?}", result);
-        assert!(out_params.is_some());
     }
 
     #[test]
@@ -363,4 +376,85 @@
         assert!(result.is_ok(), "{:?}", result);
         assert_ne!(result.unwrap().len(), 0);
     }
+
+    #[test]
+    fn test_get_key_characteristics() {
+        let legacy = get_device_or_skip_test!();
+        let hw_info = legacy.getHardwareInfo().expect("GetHardwareInfo");
+
+        let blob = generate_rsa_key(legacy.as_ref(), false, false);
+        let characteristics =
+            legacy.getKeyCharacteristics(&blob, &[], &[]).expect("GetKeyCharacteristics.");
+
+        assert!(characteristics.iter().any(|kc| kc.securityLevel == hw_info.securityLevel));
+        let sec_level_enforced = &characteristics
+            .iter()
+            .find(|kc| kc.securityLevel == hw_info.securityLevel)
+            .expect("There should be characteristics matching the device's security level.")
+            .authorizations;
+
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter {
+                tag: Tag::PURPOSE,
+                value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN)
+            }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter {
+                tag: Tag::PADDING,
+                value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS)
+            }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter {
+                tag: Tag::ALGORITHM,
+                value: KeyParameterValue::Algorithm(Algorithm::RSA)
+            }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter {
+                tag: Tag::RSA_PUBLIC_EXPONENT,
+                value: KeyParameterValue::LongInteger(65537)
+            }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter {
+                tag: Tag::ORIGIN,
+                value: KeyParameterValue::Origin(KeyOrigin::GENERATED)
+            }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter { tag: Tag::OS_VERSION, value: KeyParameterValue::Integer(_) }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter { tag: Tag::OS_PATCHLEVEL, value: KeyParameterValue::Integer(_) }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter { tag: Tag::VENDOR_PATCHLEVEL, value: KeyParameterValue::Integer(_) }
+        )));
+        assert!(sec_level_enforced.iter().any(|kp| matches!(
+            kp,
+            KeyParameter { tag: Tag::BOOT_PATCHLEVEL, value: KeyParameterValue::Integer(_) }
+        )));
+    }
 }
diff --git a/keystore2/src/km_compat/slot_test.cpp b/keystore2/src/km_compat/slot_test.cpp
index 37e7b36..43f3bc6 100644
--- a/keystore2/src/km_compat/slot_test.cpp
+++ b/keystore2/src/km_compat/slot_test.cpp
@@ -24,7 +24,6 @@
 
 using ::aidl::android::hardware::security::keymint::Algorithm;
 using ::aidl::android::hardware::security::keymint::BlockMode;
-using ::aidl::android::hardware::security::keymint::ByteArray;
 using ::aidl::android::hardware::security::keymint::Certificate;
 using ::aidl::android::hardware::security::keymint::Digest;
 using ::aidl::android::hardware::security::keymint::ErrorCode;
@@ -100,18 +99,19 @@
     // Calling finish should free up a slot.
     auto last = operations.back();
     operations.pop_back();
-    std::optional<KeyParameterArray> kpa;
     std::vector<uint8_t> byteVec;
-    auto status = last->finish(std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
-                               &kpa, &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, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
-                          &kpa, &byteVec);
+    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());
@@ -130,8 +130,9 @@
     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, std::nullopt, std::nullopt, std::nullopt, std::nullopt,
-                          &kpa, &byteVec);
+    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());
diff --git a/keystore2/src/legacy_blob.rs b/keystore2/src/legacy_blob.rs
index b51f644..7454cca 100644
--- a/keystore2/src/legacy_blob.rs
+++ b/keystore2/src/legacy_blob.rs
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#![allow(dead_code)]
-
 //! This module implements methods to load legacy keystore key blob files.
 
 use crate::{
@@ -26,7 +24,7 @@
     SecurityLevel::SecurityLevel, Tag::Tag, TagType::TagType,
 };
 use anyhow::{Context, Result};
-use keystore2_crypto::{aes_gcm_decrypt, derive_key_from_password, ZVec};
+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::{
@@ -206,7 +204,7 @@
 }
 
 impl LegacyBlobLoader {
-    const IV_SIZE: usize = keystore2_crypto::IV_LENGTH;
+    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;
 
@@ -216,7 +214,7 @@
     // flags (1 Byte)
     // info (1 Byte)
     // initialization_vector (16 Bytes)
-    // integrity (MD5 digest or gcb tag) (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;
 
@@ -227,7 +225,7 @@
     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;
+    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.
@@ -418,14 +416,14 @@
             BlobValue::Encrypted { iv, tag, data } => Ok(Blob {
                 flags: blob.flags,
                 value: BlobValue::Decrypted(
-                    decrypt(&data, &iv, &tag, None, None)
+                    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))
+                    decrypt(data, iv, tag, Some(salt), Some(*key_size))
                         .context("In new_from_stream_decrypt_with.")?,
                 ),
             }),
@@ -484,7 +482,7 @@
         let element_size =
             read_ne_u32(stream).context("In read_key_parameters: While reading element size.")?;
 
-        let elements_buffer = stream
+        let mut element_stream = stream
             .get(0..element_size as usize)
             .ok_or(KsError::Rc(ResponseCode::VALUE_CORRUPTED))
             .context("In read_key_parameters: While reading elements buffer.")?;
@@ -492,8 +490,6 @@
         // 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.")?);
@@ -603,6 +599,15 @@
     //  * USRCERT was used for public certificates of USRPKEY entries. But KeyChain also
     //            used this for user installed certificates without private key material.
 
+    const KNOWN_KEYSTORE_PREFIXES: &'static [&'static str] =
+        &["USRPKEY_", "USRSKEY_", "USRCERT_", "CACERT_"];
+
+    fn is_keystore_alias(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.
+        Self::KNOWN_KEYSTORE_PREFIXES.iter().any(|prefix| encoded_alias.starts_with(prefix))
+    }
+
     fn read_km_blob_file(&self, uid: u32, alias: &str) -> Result<Option<(Blob, String)>> {
         let mut iter = ["USRPKEY", "USRSKEY"].iter();
 
@@ -634,8 +639,138 @@
         Ok(Some(Self::new_from_stream(&mut file).context("In read_generic_blob.")?))
     }
 
+    /// Read a legacy keystore entry blob.
+    pub fn read_legacy_keystore_entry(&self, uid: u32, alias: &str) -> Result<Option<Vec<u8>>> {
+        let path = match self.make_legacy_keystore_entry_filename(uid, alias) {
+            Some(path) => path,
+            None => return Ok(None),
+        };
+
+        let blob = Self::read_generic_blob(&path)
+            .context("In read_legacy_keystore_entry: Failed to read blob.")?;
+
+        Ok(blob.and_then(|blob| match blob.value {
+            BlobValue::Generic(blob) => Some(blob),
+            _ => {
+                log::info!("Unexpected legacy keystore entry blob type. Ignoring");
+                None
+            }
+        }))
+    }
+
+    /// Remove a legacy keystore entry by the name alias with owner uid.
+    pub fn remove_legacy_keystore_entry(&self, uid: u32, alias: &str) -> Result<()> {
+        let path = match self.make_legacy_keystore_entry_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_legacy_keystore_entry."),
+            }
+        }
+
+        let user_id = uid_to_android_user(uid);
+        self.remove_user_dir_if_empty(user_id)
+            .context("In remove_legacy_keystore_entry: Trying to remove empty user dir.")
+    }
+
+    /// List all entries belonging to the given uid.
+    pub fn list_legacy_keystore_entries_for_uid(&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!(
+                        concat!(
+                            "In list_legacy_keystore_entries_for_uid: ,",
+                            "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_legacy_keystore_entries_for_uid: 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_keystore_alias(encoded_alias) {
+                    result.push(Self::decode_alias(encoded_alias).context(
+                        "In list_legacy_keystore_entries_for_uid: Trying to decode alias.",
+                    )?)
+                }
+            }
+        }
+        Ok(result)
+    }
+
+    fn extract_legacy_alias(encoded_alias: &str) -> Option<String> {
+        if !Self::is_keystore_alias(encoded_alias) {
+            Self::decode_alias(encoded_alias).ok()
+        } else {
+            None
+        }
+    }
+
+    /// Lists all keystore entries belonging to the given user. Returns a map of UIDs
+    /// to sets of decoded aliases. Only returns entries that do not begin with
+    /// KNOWN_KEYSTORE_PREFIXES.
+    pub fn list_legacy_keystore_entries_for_user(
+        &self,
+        user_id: u32,
+    ) -> Result<HashMap<u32, HashSet<String>>> {
+        let user_entries = self
+            .list_user(user_id)
+            .context("In list_legacy_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_legacy_alias(&v[sep_pos + 1..]) {
+                            let entry = acc.entry(uid).or_default();
+                            entry.insert(alias);
+                        }
+                    }
+                }
+                acc
+            });
+        Ok(result)
+    }
+
+    /// This function constructs the legacy blob file name which has the form:
+    /// user_<android user id>/<uid>_<alias>. Legacy blob file names must not use
+    /// known keystore prefixes.
+    fn make_legacy_keystore_entry_filename(&self, uid: u32, alias: &str) -> Option<PathBuf> {
+        // Legacy entries must not use known keystore prefixes.
+        if Self::is_keystore_alias(alias) {
+            log::warn!(
+                "Known keystore prefixes cannot be used with legacy keystore -> ignoring request."
+            );
+            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>_<alias>.
+    /// 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));
@@ -696,12 +831,12 @@
             .is_none())
     }
 
-    fn extract_alias(encoded_alias: &str) -> Option<String> {
+    fn extract_keystore_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_"] {
+        for prefix in Self::KNOWN_KEYSTORE_PREFIXES {
             if let Some(alias) = encoded_alias.strip_prefix(prefix) {
-                return Self::decode_alias(&alias).ok();
+                return Self::decode_alias(alias).ok();
             }
         }
         None
@@ -711,10 +846,18 @@
     /// 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 =
-            Self::with_retry_interrupted(|| fs::read_dir(path.as_path())).with_context(|| {
-                format!("In list_user: Failed to open legacy blob database. {:?}", path)
-            })?;
+        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();
@@ -739,7 +882,7 @@
             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..]) {
+                        if let Some(alias) = Self::extract_keystore_alias(&v[sep_pos + 1..]) {
                             let entry = acc.entry(uid).or_default();
                             entry.insert(alias);
                         }
@@ -767,7 +910,7 @@
                     return None;
                 }
                 let encoded_alias = &v[uid_str.len()..];
-                Self::extract_alias(encoded_alias)
+                Self::extract_keystore_alias(encoded_alias)
             })
             .collect();
 
@@ -838,18 +981,24 @@
 
         if something_was_deleted {
             let user_id = uid_to_android_user(uid);
-            if self
-                .is_empty_user(user_id)
-                .context("In remove_keystore_entry: 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();
-            }
+            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,
@@ -869,8 +1018,7 @@
                             let decrypted = match key_manager
                                 .get_per_boot_key_by_user_id(uid_to_android_user(uid))
                             {
-                                Some(key) => aes_gcm_decrypt(data, iv, tag, &(key.get_key()))
-                                    .context(
+                                Some(key) => key.aes_gcm_decrypt(data, iv, tag).context(
                                     "In load_by_uid_alias: while trying to decrypt legacy blob.",
                                 )?,
                                 None => {
@@ -940,22 +1088,29 @@
     }
 
     /// Load and decrypt legacy super key blob.
-    pub fn load_super_key(&self, user_id: u32, pw: &[u8]) -> Result<Option<ZVec>> {
+    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 {
-                    value: BlobValue::PwEncrypted { iv, tag, data, salt, key_size }, ..
-                } => {
-                    let key = derive_key_from_password(pw, 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)
+                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(
@@ -1038,7 +1193,7 @@
             let encoded = LegacyBlobLoader::encode_alias(&alias_str);
             let decoded = match LegacyBlobLoader::decode_alias(&encoded) {
                 Ok(d) => d,
-                Err(_) => panic!(format!("random_alias: {:x?}\nencoded {}", random_alias, encoded)),
+                Err(_) => panic!("random_alias: {:x?}\nencoded {}", random_alias, encoded),
             };
             assert_eq!(random_alias.to_vec(), decoded.bytes().collect::<Vec<u8>>());
         }
@@ -1185,7 +1340,7 @@
             CACERT_NON_AUTHBOUND,
         )?;
 
-        let key_manager = crate::super_key::SuperKeyManager::new();
+        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());
 
@@ -1198,7 +1353,7 @@
             Some(&error::Error::Rc(ResponseCode::LOCKED))
         );
 
-        key_manager.unlock_user_key(&mut db, 0, PASSWORD, &legacy_blob_loader)?;
+        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))?
@@ -1250,4 +1405,24 @@
 
         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_legacy_keystore_entries_on_non_existing_user() -> Result<()> {
+        let temp_dir = TempDir::new("list_legacy_keystore_entries_on_non_existing_user")?;
+        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+        assert!(legacy_blob_loader.list_legacy_keystore_entries_for_user(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
index aa99162..14bd40c 100644
--- a/keystore2/src/legacy_blob/test/legacy_blob_test_vectors.rs
+++ b/keystore2/src/legacy_blob/test/legacy_blob_test_vectors.rs
@@ -741,7 +741,7 @@
     0xab, 0xae, 0x24, 0xe2, 0x44, 0x35, 0x16, 0x8d, 0x55, 0x3c, 0xe4,
 ];
 
-pub static DECRYPTED_USRPKEY_AUTHBOUND: &[u8] = &[
+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,
diff --git a/keystore2/src/legacy_migrator.rs b/keystore2/src/legacy_migrator.rs
index 1ae8719..65f4b0b 100644
--- a/keystore2/src/legacy_migrator.rs
+++ b/keystore2/src/legacy_migrator.rs
@@ -14,24 +14,26 @@
 
 //! This module acts as a bridge between the legacy key database and the keystore2 database.
 
-use crate::database::{
-    BlobMetaData, BlobMetaEntry, CertificateInfo, DateTime, EncryptedBy, KeyMetaData, KeyMetaEntry,
-    KeystoreDB, Uuid, KEYSTORE_UUID,
-};
-use crate::error::Error;
 use crate::key_parameter::KeyParameterValue;
 use crate::legacy_blob::BlobValue;
-use crate::utils::uid_to_android_user;
+use crate::utils::{uid_to_android_user, watchdog as wd};
 use crate::{async_task::AsyncTask, legacy_blob::LegacyBlobLoader};
+use crate::{database::KeyType, error::Error};
+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::ZVec;
+use keystore2_crypto::{Password, ZVec};
 use std::collections::{HashMap, HashSet};
-use std::convert::TryInto;
 use std::sync::atomic::{AtomicU8, Ordering};
 use std::sync::mpsc::channel;
 use std::sync::{Arc, Mutex};
@@ -194,6 +196,8 @@
 
     /// 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,
@@ -288,6 +292,8 @@
     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),
@@ -334,23 +340,22 @@
     pub fn with_try_migrate_super_key<F, T>(
         &self,
         user_id: u32,
-        pw: &[u8],
+        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: ZVec = pw
-            .try_into()
-            .context("In with_try_migrate_super_key: copying the password into a zvec.")?;
+        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)
+            migrator_state.check_and_migrate_super_key(user_id, &pw)
         });
 
         if let Some(result) = result {
@@ -365,6 +370,8 @@
     /// 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,
@@ -386,6 +393,8 @@
         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)
@@ -421,7 +430,7 @@
             .context("In list_uid: Trying to list legacy entries.")
     }
 
-    /// This is a key migration request that can run in the migrator thread. This should
+    /// 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(|| {
@@ -454,7 +463,7 @@
 
                         let super_key_id = match self
                             .db
-                            .load_super_key(user_id)
+                            .load_super_key(&USER_SUPER_KEY, user_id)
                             .context("In check_and_migrate: Failed to load super key")?
                         {
                             Some((_, entry)) => entry.id(),
@@ -514,6 +523,7 @@
                 self.db
                     .store_new_key(
                         &key,
+                        KeyType::Client,
                         &params,
                         &(&blob, &blob_metadata),
                         &CertificateInfo::new(user_cert, ca_cert),
@@ -526,7 +536,7 @@
             None => {
                 if let Some(ca_cert) = ca_cert {
                     self.db
-                        .store_new_certificate(&key, &ca_cert, &KEYSTORE_UUID)
+                        .store_new_certificate(&key, KeyType::Client, &ca_cert, &KEYSTORE_UUID)
                         .context("In check_and_migrate: Failed to insert new certificate.")?;
                     Ok(())
                 } else {
@@ -550,24 +560,32 @@
         }
     }
 
-    fn check_and_migrate_super_key(&mut self, user_id: u32, pw: ZVec) -> Result<()> {
+    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)
+            .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)
+                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, &(&blob, &blob_metadata)).context(concat!(
-                "In check_and_migrate_super_key: ",
-                "Trying to insert legacy super_key into the database."
-            ))?;
+            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(())
@@ -606,7 +624,7 @@
 
         let super_key_id = self
             .db
-            .load_super_key(user_id)
+            .load_super_key(&USER_SUPER_KEY, user_id)
             .context("In bulk_delete: Failed to load super key")?
             .map(|(_, entry)| entry.id());
 
@@ -706,8 +724,8 @@
 
     fn deref(&self) -> &Self::Target {
         match self {
-            Self::Vec(v) => &v,
-            Self::ZVec(v) => &v,
+            Self::Vec(v) => v,
+            Self::ZVec(v) => v,
         }
     }
 }
diff --git a/keystore2/src/lib.rs b/keystore2/src/lib.rs
index 358fce8..8b629b1 100644
--- a/keystore2/src/lib.rs
+++ b/keystore2/src/lib.rs
@@ -16,24 +16,37 @@
 #![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 metrics_store;
 pub mod operation;
 pub mod permission;
+pub mod raw_device;
 pub mod remote_provisioning;
 pub mod security_level;
 pub mod service;
-pub mod user_manager;
+pub mod shared_secret_negotiation;
+pub mod try_insert;
 pub mod utils;
 
-mod async_task;
-mod db_utils;
+mod attestation_key_utils;
+mod audit_log;
 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..7ce9042
--- /dev/null
+++ b/keystore2/src/maintenance.rs
@@ -0,0 +1,315 @@
+// 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, 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::KeyDescriptor::KeyDescriptor;
+use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
+use anyhow::{Context, Result};
+use keystore2_crypto::Password;
+
+/// Reexport Domain for the benefit of DeleteListener
+pub use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
+
+/// The Maintenance module takes a delete listener argument which observes user and namespace
+/// deletion events.
+pub trait DeleteListener {
+    /// Called by the maintenance module when an app/namespace is deleted.
+    fn delete_namespace(&self, domain: Domain, namespace: i64) -> Result<()>;
+    /// Called by the maintenance module when a user is deleted.
+    fn delete_user(&self, user_id: u32) -> Result<()>;
+}
+
+/// This struct is defined to implement the aforementioned AIDL interface.
+pub struct Maintenance {
+    delete_listener: Box<dyn DeleteListener + Send + Sync + 'static>,
+}
+
+impl Maintenance {
+    /// Create a new instance of Keystore Maintenance service.
+    pub fn new_native_binder(
+        delete_listener: Box<dyn DeleteListener + Send + Sync + 'static>,
+    ) -> Result<Strong<dyn IKeystoreMaintenance>> {
+        Ok(BnKeystoreMaintenance::new_binder(
+            Self { delete_listener },
+            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(&self, 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.")?;
+        self.delete_listener
+            .delete_user(user_id as u32)
+            .context("In add_or_remove_user: While invoking the delete listener.")
+    }
+
+    fn clear_namespace(&self, 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.")?;
+        self.delete_listener
+            .delete_namespace(domain, nspace)
+            .context("In clear_namespace: While invoking the delete listener.")
+    }
+
+    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 call_with_watchdog<F>(sec_level: SecurityLevel, name: &'static str, op: &F) -> Result<()>
+    where
+        F: Fn(Strong<dyn IKeyMintDevice>) -> binder::public_api::Result<()>,
+    {
+        let (km_dev, _, _) = get_keymint_device(&sec_level)
+            .context("In call_with_watchdog: getting keymint device")?;
+
+        let _wp = wd::watch_millis_with("In call_with_watchdog", 500, move || {
+            format!("Seclevel: {:?} Op: {}", sec_level, name)
+        });
+        map_km_error(op(km_dev)).with_context(|| format!("In keymint device: calling {}", name))?;
+        Ok(())
+    }
+
+    fn call_on_all_security_levels<F>(name: &'static str, op: F) -> Result<()>
+    where
+        F: Fn(Strong<dyn IKeyMintDevice>) -> binder::public_api::Result<()>,
+    {
+        let sec_levels = [
+            (SecurityLevel::TRUSTED_ENVIRONMENT, "TRUSTED_ENVIRONMENT"),
+            (SecurityLevel::STRONGBOX, "STRONGBOX"),
+        ];
+        sec_levels.iter().fold(Ok(()), move |result, (sec_level, sec_level_string)| {
+            let curr_result = Maintenance::call_with_watchdog(*sec_level, name, &op);
+            match curr_result {
+                Ok(()) => log::info!(
+                    "Call to {} succeeded for security level {}.",
+                    name,
+                    &sec_level_string
+                ),
+                Err(ref e) => log::error!(
+                    "Call to {} failed for security level {}: {}.",
+                    name,
+                    &sec_level_string,
+                    e
+                ),
+            }
+            result.and(curr_result)
+        })
+    }
+
+    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);
+        }
+        Maintenance::call_on_all_security_levels("earlyBootEnded", |dev| dev.earlyBootEnded())
+    }
+
+    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()));
+        Ok(())
+    }
+
+    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)
+            })
+        })
+    }
+
+    fn delete_all_keys() -> Result<()> {
+        // Security critical permission check. This statement must return on fail.
+        check_keystore_permission(KeystorePerm::delete_all_keys())
+            .context("In delete_all_keys. Checking permission")?;
+        log::info!("In delete_all_keys.");
+
+        Maintenance::call_on_all_security_levels("deleteAllKeys", |dev| dev.deleteAllKeys())
+    }
+}
+
+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)
+    }
+
+    fn deleteAllKeys(&self) -> BinderResult<()> {
+        let _wp = wd::watch_millis("IKeystoreMaintenance::deleteAllKeys", 500);
+        map_or_log_err(Self::delete_all_keys(), Ok)
+    }
+}
diff --git a/keystore2/src/metrics.rs b/keystore2/src/metrics.rs
new file mode 100644
index 0000000..42295b7
--- /dev/null
+++ b/keystore2/src/metrics.rs
@@ -0,0 +1,56 @@
+// 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 IKeystoreMetrics AIDL interface, which exposes the API method for the
+//! proxy in the system server to pull the aggregated metrics in keystore.
+use crate::error::map_or_log_err;
+use crate::metrics_store::METRICS_STORE;
+use crate::permission::KeystorePerm;
+use crate::utils::{check_keystore_permission, watchdog as wd};
+use android_security_metrics::aidl::android::security::metrics::{
+    AtomID::AtomID,
+    IKeystoreMetrics::{BnKeystoreMetrics, IKeystoreMetrics},
+    KeystoreAtom::KeystoreAtom,
+};
+use android_security_metrics::binder::{BinderFeatures, Interface, Result as BinderResult, Strong};
+use anyhow::{Context, Result};
+
+/// This struct is defined to implement IKeystoreMetrics AIDL interface.
+pub struct Metrics;
+
+impl Metrics {
+    /// Create a new instance of Keystore Metrics service.
+    pub fn new_native_binder() -> Result<Strong<dyn IKeystoreMetrics>> {
+        Ok(BnKeystoreMetrics::new_binder(
+            Self,
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        ))
+    }
+
+    fn pull_metrics(&self, atom_id: AtomID) -> Result<Vec<KeystoreAtom>> {
+        // Check permission. Function should return if this failed. Therefore having '?' at the end
+        // is very important.
+        check_keystore_permission(KeystorePerm::pull_metrics()).context("In pull_metrics.")?;
+        METRICS_STORE.get_atoms(atom_id)
+    }
+}
+
+impl Interface for Metrics {}
+
+impl IKeystoreMetrics for Metrics {
+    fn pullMetrics(&self, atom_id: AtomID) -> BinderResult<Vec<KeystoreAtom>> {
+        let _wp = wd::watch_millis("IKeystoreMetrics::pullMetrics", 500);
+        map_or_log_err(self.pull_metrics(atom_id), Ok)
+    }
+}
diff --git a/keystore2/src/metrics_store.rs b/keystore2/src/metrics_store.rs
new file mode 100644
index 0000000..741d65e
--- /dev/null
+++ b/keystore2/src/metrics_store.rs
@@ -0,0 +1,724 @@
+// 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 is the metrics store module of keystore. It does the following tasks:
+//! 1. Processes the data about keystore events asynchronously, and
+//!    stores them in an in-memory store.
+//! 2. Returns the collected metrics when requested by the statsd proxy.
+
+use crate::error::get_error_code;
+use crate::globals::DB;
+use crate::key_parameter::KeyParameterValue as KsKeyParamValue;
+use crate::operation::Outcome;
+use crate::remote_provisioning::get_pool_status;
+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 android_security_metrics::aidl::android::security::metrics::{
+    Algorithm::Algorithm as MetricsAlgorithm, AtomID::AtomID, CrashStats::CrashStats,
+    EcCurve::EcCurve as MetricsEcCurve,
+    HardwareAuthenticatorType::HardwareAuthenticatorType as MetricsHardwareAuthenticatorType,
+    KeyCreationWithAuthInfo::KeyCreationWithAuthInfo,
+    KeyCreationWithGeneralInfo::KeyCreationWithGeneralInfo,
+    KeyCreationWithPurposeAndModesInfo::KeyCreationWithPurposeAndModesInfo,
+    KeyOperationWithGeneralInfo::KeyOperationWithGeneralInfo,
+    KeyOperationWithPurposeAndModesInfo::KeyOperationWithPurposeAndModesInfo,
+    KeyOrigin::KeyOrigin as MetricsKeyOrigin, Keystore2AtomWithOverflow::Keystore2AtomWithOverflow,
+    KeystoreAtom::KeystoreAtom, KeystoreAtomPayload::KeystoreAtomPayload,
+    Outcome::Outcome as MetricsOutcome, Purpose::Purpose as MetricsPurpose,
+    RkpError::RkpError as MetricsRkpError, RkpErrorStats::RkpErrorStats,
+    RkpPoolStats::RkpPoolStats, SecurityLevel::SecurityLevel as MetricsSecurityLevel,
+    Storage::Storage as MetricsStorage,
+};
+use anyhow::{Context, Result};
+use lazy_static::lazy_static;
+use rustutils::system_properties::PropertyWatcherError;
+use std::collections::HashMap;
+use std::sync::Mutex;
+use std::time::{Duration, SystemTime, UNIX_EPOCH};
+
+// Note: Crash events are recorded at keystore restarts, based on the assumption that keystore only
+// gets restarted after a crash, during a boot cycle.
+const KEYSTORE_CRASH_COUNT_PROPERTY: &str = "keystore.crash_count";
+
+lazy_static! {
+    /// Singleton for MetricsStore.
+    pub static ref METRICS_STORE: MetricsStore = Default::default();
+}
+
+/// MetricsStore stores the <atom object, count> as <key, value> in the inner hash map,
+/// indexed by the atom id, in the outer hash map.
+/// There can be different atom objects with the same atom id based on the values assigned to the
+/// fields of the atom objects. When an atom object with a particular combination of field values is
+/// inserted, we first check if that atom object is in the inner hash map. If one exists, count
+/// is inceremented. Otherwise, the atom object is inserted with count = 1. Note that count field
+/// of the atom object itself is set to 0 while the object is stored in the hash map. When the atom
+/// objects are queried by the atom id, the corresponding atom objects are retrieved, cloned, and
+/// the count field of the cloned objects is set to the corresponding value field in the inner hash
+/// map before the query result is returned.
+#[derive(Default)]
+pub struct MetricsStore {
+    metrics_store: Mutex<HashMap<AtomID, HashMap<KeystoreAtomPayload, i32>>>,
+}
+
+impl MetricsStore {
+    /// There are some atoms whose maximum cardinality exceeds the cardinality limits tolerated
+    /// by statsd. Statsd tolerates cardinality between 200-300. Therefore, the in-memory storage
+    /// limit for a single atom is set to 250. If the number of atom objects created for a
+    /// particular atom exceeds this limit, an overflow atom object is created to track the ID of
+    /// such atoms.
+    const SINGLE_ATOM_STORE_MAX_SIZE: usize = 250;
+
+    /// Return a vector of atom objects with the given atom ID, if one exists in the metrics_store.
+    /// If any atom object does not exist in the metrics_store for the given atom ID, return an
+    /// empty vector.
+    pub fn get_atoms(&self, atom_id: AtomID) -> Result<Vec<KeystoreAtom>> {
+        // StorageStats is an original pulled atom (i.e. not a pushed atom converted to a
+        // pulledd atom). Therefore, it is handled separately.
+        if AtomID::STORAGE_STATS == atom_id {
+            return pull_storage_stats();
+        }
+
+        // Process and return RKP pool stats.
+        if AtomID::RKP_POOL_STATS == atom_id {
+            return pull_attestation_pool_stats();
+        }
+
+        // Process keystore crash stats.
+        if AtomID::CRASH_STATS == atom_id {
+            return Ok(vec![KeystoreAtom {
+                payload: KeystoreAtomPayload::CrashStats(CrashStats {
+                    count_of_crash_events: read_keystore_crash_count()?,
+                }),
+                ..Default::default()
+            }]);
+        }
+
+        // It is safe to call unwrap here since the lock can not be poisoned based on its usage
+        // in this module and the lock is not acquired in the same thread before.
+        let metrics_store_guard = self.metrics_store.lock().unwrap();
+        metrics_store_guard.get(&atom_id).map_or(Ok(Vec::<KeystoreAtom>::new()), |atom_count_map| {
+            Ok(atom_count_map
+                .iter()
+                .map(|(atom, count)| KeystoreAtom { payload: atom.clone(), count: *count })
+                .collect())
+        })
+    }
+
+    /// Insert an atom object to the metrics_store indexed by the atom ID.
+    fn insert_atom(&self, atom_id: AtomID, atom: KeystoreAtomPayload) {
+        // It is ok to unwrap here since the mutex cannot be poisoned according to the way it is
+        // used in this module. And the lock is not acquired by this thread before.
+        let mut metrics_store_guard = self.metrics_store.lock().unwrap();
+        let atom_count_map = metrics_store_guard.entry(atom_id).or_insert_with(HashMap::new);
+        if atom_count_map.len() < MetricsStore::SINGLE_ATOM_STORE_MAX_SIZE {
+            let atom_count = atom_count_map.entry(atom).or_insert(0);
+            *atom_count += 1;
+        } else {
+            // Insert an overflow atom
+            let overflow_atom_count_map = metrics_store_guard
+                .entry(AtomID::KEYSTORE2_ATOM_WITH_OVERFLOW)
+                .or_insert_with(HashMap::new);
+
+            if overflow_atom_count_map.len() < MetricsStore::SINGLE_ATOM_STORE_MAX_SIZE {
+                let overflow_atom = Keystore2AtomWithOverflow { atom_id };
+                let atom_count = overflow_atom_count_map
+                    .entry(KeystoreAtomPayload::Keystore2AtomWithOverflow(overflow_atom))
+                    .or_insert(0);
+                *atom_count += 1;
+            } else {
+                // This is a rare case, if at all.
+                log::error!("In insert_atom: Maximum storage limit reached for overflow atom.")
+            }
+        }
+    }
+}
+
+/// Log key creation events to be sent to statsd.
+pub fn log_key_creation_event_stats<U>(
+    sec_level: SecurityLevel,
+    key_params: &[KeyParameter],
+    result: &Result<U>,
+) {
+    let (
+        key_creation_with_general_info,
+        key_creation_with_auth_info,
+        key_creation_with_purpose_and_modes_info,
+    ) = process_key_creation_event_stats(sec_level, key_params, result);
+
+    METRICS_STORE
+        .insert_atom(AtomID::KEY_CREATION_WITH_GENERAL_INFO, key_creation_with_general_info);
+    METRICS_STORE.insert_atom(AtomID::KEY_CREATION_WITH_AUTH_INFO, key_creation_with_auth_info);
+    METRICS_STORE.insert_atom(
+        AtomID::KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO,
+        key_creation_with_purpose_and_modes_info,
+    );
+}
+
+// Process the statistics related to key creations and return the three atom objects related to key
+// creations: i) KeyCreationWithGeneralInfo ii) KeyCreationWithAuthInfo
+// iii) KeyCreationWithPurposeAndModesInfo
+fn process_key_creation_event_stats<U>(
+    sec_level: SecurityLevel,
+    key_params: &[KeyParameter],
+    result: &Result<U>,
+) -> (KeystoreAtomPayload, KeystoreAtomPayload, KeystoreAtomPayload) {
+    // In the default atom objects, 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 defaults 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.
+    let mut key_creation_with_general_info = KeyCreationWithGeneralInfo {
+        algorithm: MetricsAlgorithm::ALGORITHM_UNSPECIFIED,
+        key_size: -1,
+        ec_curve: MetricsEcCurve::EC_CURVE_UNSPECIFIED,
+        key_origin: MetricsKeyOrigin::ORIGIN_UNSPECIFIED,
+        error_code: 1,
+        // Default for bool is false (for attestation_requested field).
+        ..Default::default()
+    };
+
+    let mut key_creation_with_auth_info = KeyCreationWithAuthInfo {
+        user_auth_type: MetricsHardwareAuthenticatorType::AUTH_TYPE_UNSPECIFIED,
+        log10_auth_key_timeout_seconds: -1,
+        security_level: MetricsSecurityLevel::SECURITY_LEVEL_UNSPECIFIED,
+    };
+
+    let mut key_creation_with_purpose_and_modes_info = KeyCreationWithPurposeAndModesInfo {
+        algorithm: MetricsAlgorithm::ALGORITHM_UNSPECIFIED,
+        // Default for i32 is 0 (for the remaining bitmap fields).
+        ..Default::default()
+    };
+
+    if let Err(ref e) = result {
+        key_creation_with_general_info.error_code = get_error_code(e);
+    }
+
+    key_creation_with_auth_info.security_level = process_security_level(sec_level);
+
+    for key_param in key_params.iter().map(KsKeyParamValue::from) {
+        match key_param {
+            KsKeyParamValue::Algorithm(a) => {
+                let algorithm = match a {
+                    Algorithm::RSA => MetricsAlgorithm::RSA,
+                    Algorithm::EC => MetricsAlgorithm::EC,
+                    Algorithm::AES => MetricsAlgorithm::AES,
+                    Algorithm::TRIPLE_DES => MetricsAlgorithm::TRIPLE_DES,
+                    Algorithm::HMAC => MetricsAlgorithm::HMAC,
+                    _ => MetricsAlgorithm::ALGORITHM_UNSPECIFIED,
+                };
+                key_creation_with_general_info.algorithm = algorithm;
+                key_creation_with_purpose_and_modes_info.algorithm = algorithm;
+            }
+            KsKeyParamValue::KeySize(s) => {
+                key_creation_with_general_info.key_size = s;
+            }
+            KsKeyParamValue::KeyOrigin(o) => {
+                key_creation_with_general_info.key_origin = match o {
+                    KeyOrigin::GENERATED => MetricsKeyOrigin::GENERATED,
+                    KeyOrigin::DERIVED => MetricsKeyOrigin::DERIVED,
+                    KeyOrigin::IMPORTED => MetricsKeyOrigin::IMPORTED,
+                    KeyOrigin::RESERVED => MetricsKeyOrigin::RESERVED,
+                    KeyOrigin::SECURELY_IMPORTED => MetricsKeyOrigin::SECURELY_IMPORTED,
+                    _ => MetricsKeyOrigin::ORIGIN_UNSPECIFIED,
+                }
+            }
+            KsKeyParamValue::HardwareAuthenticatorType(a) => {
+                key_creation_with_auth_info.user_auth_type = match a {
+                    HardwareAuthenticatorType::NONE => MetricsHardwareAuthenticatorType::NONE,
+                    HardwareAuthenticatorType::PASSWORD => {
+                        MetricsHardwareAuthenticatorType::PASSWORD
+                    }
+                    HardwareAuthenticatorType::FINGERPRINT => {
+                        MetricsHardwareAuthenticatorType::FINGERPRINT
+                    }
+                    HardwareAuthenticatorType::ANY => MetricsHardwareAuthenticatorType::ANY,
+                    _ => MetricsHardwareAuthenticatorType::AUTH_TYPE_UNSPECIFIED,
+                }
+            }
+            KsKeyParamValue::AuthTimeout(t) => {
+                key_creation_with_auth_info.log10_auth_key_timeout_seconds =
+                    f32::log10(t as f32) as i32;
+            }
+            KsKeyParamValue::PaddingMode(p) => {
+                compute_padding_mode_bitmap(
+                    &mut key_creation_with_purpose_and_modes_info.padding_mode_bitmap,
+                    p,
+                );
+            }
+            KsKeyParamValue::Digest(d) => {
+                // key_creation_with_purpose_and_modes_info.digest_bitmap =
+                compute_digest_bitmap(
+                    &mut key_creation_with_purpose_and_modes_info.digest_bitmap,
+                    d,
+                );
+            }
+            KsKeyParamValue::BlockMode(b) => {
+                compute_block_mode_bitmap(
+                    &mut key_creation_with_purpose_and_modes_info.block_mode_bitmap,
+                    b,
+                );
+            }
+            KsKeyParamValue::KeyPurpose(k) => {
+                compute_purpose_bitmap(
+                    &mut key_creation_with_purpose_and_modes_info.purpose_bitmap,
+                    k,
+                );
+            }
+            KsKeyParamValue::EcCurve(e) => {
+                key_creation_with_general_info.ec_curve = match e {
+                    EcCurve::P_224 => MetricsEcCurve::P_224,
+                    EcCurve::P_256 => MetricsEcCurve::P_256,
+                    EcCurve::P_384 => MetricsEcCurve::P_384,
+                    EcCurve::P_521 => MetricsEcCurve::P_521,
+                    _ => MetricsEcCurve::EC_CURVE_UNSPECIFIED,
+                }
+            }
+            KsKeyParamValue::AttestationChallenge(_) => {
+                key_creation_with_general_info.attestation_requested = true;
+            }
+            _ => {}
+        }
+    }
+    if key_creation_with_general_info.algorithm == MetricsAlgorithm::EC {
+        // Do not record key sizes if Algorithm = EC, in order to reduce cardinality.
+        key_creation_with_general_info.key_size = -1;
+    }
+
+    (
+        KeystoreAtomPayload::KeyCreationWithGeneralInfo(key_creation_with_general_info),
+        KeystoreAtomPayload::KeyCreationWithAuthInfo(key_creation_with_auth_info),
+        KeystoreAtomPayload::KeyCreationWithPurposeAndModesInfo(
+            key_creation_with_purpose_and_modes_info,
+        ),
+    )
+}
+
+/// Log key operation events to be sent to statsd.
+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_with_general_info, key_operation_with_purpose_and_modes_info) =
+        process_key_operation_event_stats(
+            sec_level,
+            key_purpose,
+            op_params,
+            op_outcome,
+            key_upgraded,
+        );
+    METRICS_STORE
+        .insert_atom(AtomID::KEY_OPERATION_WITH_GENERAL_INFO, key_operation_with_general_info);
+    METRICS_STORE.insert_atom(
+        AtomID::KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO,
+        key_operation_with_purpose_and_modes_info,
+    );
+}
+
+// Process the statistics related to key operations and return the two atom objects related to key
+// operations: i) KeyOperationWithGeneralInfo ii) KeyOperationWithPurposeAndModesInfo
+fn process_key_operation_event_stats(
+    sec_level: SecurityLevel,
+    key_purpose: KeyPurpose,
+    op_params: &[KeyParameter],
+    op_outcome: &Outcome,
+    key_upgraded: bool,
+) -> (KeystoreAtomPayload, KeystoreAtomPayload) {
+    let mut key_operation_with_general_info = KeyOperationWithGeneralInfo {
+        outcome: MetricsOutcome::OUTCOME_UNSPECIFIED,
+        error_code: 1,
+        security_level: MetricsSecurityLevel::SECURITY_LEVEL_UNSPECIFIED,
+        // Default for bool is false (for key_upgraded field).
+        ..Default::default()
+    };
+
+    let mut key_operation_with_purpose_and_modes_info = KeyOperationWithPurposeAndModesInfo {
+        purpose: MetricsPurpose::KEY_PURPOSE_UNSPECIFIED,
+        // Default for i32 is 0 (for the remaining bitmap fields).
+        ..Default::default()
+    };
+
+    key_operation_with_general_info.security_level = process_security_level(sec_level);
+
+    key_operation_with_general_info.key_upgraded = key_upgraded;
+
+    key_operation_with_purpose_and_modes_info.purpose = match key_purpose {
+        KeyPurpose::ENCRYPT => MetricsPurpose::ENCRYPT,
+        KeyPurpose::DECRYPT => MetricsPurpose::DECRYPT,
+        KeyPurpose::SIGN => MetricsPurpose::SIGN,
+        KeyPurpose::VERIFY => MetricsPurpose::VERIFY,
+        KeyPurpose::WRAP_KEY => MetricsPurpose::WRAP_KEY,
+        KeyPurpose::AGREE_KEY => MetricsPurpose::AGREE_KEY,
+        KeyPurpose::ATTEST_KEY => MetricsPurpose::ATTEST_KEY,
+        _ => MetricsPurpose::KEY_PURPOSE_UNSPECIFIED,
+    };
+
+    key_operation_with_general_info.outcome = match op_outcome {
+        Outcome::Unknown | Outcome::Dropped => MetricsOutcome::DROPPED,
+        Outcome::Success => MetricsOutcome::SUCCESS,
+        Outcome::Abort => MetricsOutcome::ABORT,
+        Outcome::Pruned => MetricsOutcome::PRUNED,
+        Outcome::ErrorCode(e) => {
+            key_operation_with_general_info.error_code = e.0;
+            MetricsOutcome::ERROR
+        }
+    };
+
+    for key_param in op_params.iter().map(KsKeyParamValue::from) {
+        match key_param {
+            KsKeyParamValue::PaddingMode(p) => {
+                compute_padding_mode_bitmap(
+                    &mut key_operation_with_purpose_and_modes_info.padding_mode_bitmap,
+                    p,
+                );
+            }
+            KsKeyParamValue::Digest(d) => {
+                compute_digest_bitmap(
+                    &mut key_operation_with_purpose_and_modes_info.digest_bitmap,
+                    d,
+                );
+            }
+            KsKeyParamValue::BlockMode(b) => {
+                compute_block_mode_bitmap(
+                    &mut key_operation_with_purpose_and_modes_info.block_mode_bitmap,
+                    b,
+                );
+            }
+            _ => {}
+        }
+    }
+
+    (
+        KeystoreAtomPayload::KeyOperationWithGeneralInfo(key_operation_with_general_info),
+        KeystoreAtomPayload::KeyOperationWithPurposeAndModesInfo(
+            key_operation_with_purpose_and_modes_info,
+        ),
+    )
+}
+
+fn process_security_level(sec_level: SecurityLevel) -> MetricsSecurityLevel {
+    match sec_level {
+        SecurityLevel::SOFTWARE => MetricsSecurityLevel::SECURITY_LEVEL_SOFTWARE,
+        SecurityLevel::TRUSTED_ENVIRONMENT => {
+            MetricsSecurityLevel::SECURITY_LEVEL_TRUSTED_ENVIRONMENT
+        }
+        SecurityLevel::STRONGBOX => MetricsSecurityLevel::SECURITY_LEVEL_STRONGBOX,
+        SecurityLevel::KEYSTORE => MetricsSecurityLevel::SECURITY_LEVEL_KEYSTORE,
+        _ => MetricsSecurityLevel::SECURITY_LEVEL_UNSPECIFIED,
+    }
+}
+
+fn compute_padding_mode_bitmap(padding_mode_bitmap: &mut i32, padding_mode: PaddingMode) {
+    match padding_mode {
+        PaddingMode::NONE => {
+            *padding_mode_bitmap |= 1 << PaddingModeBitPosition::NONE_BIT_POSITION as i32;
+        }
+        PaddingMode::RSA_OAEP => {
+            *padding_mode_bitmap |= 1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS as i32;
+        }
+        PaddingMode::RSA_PSS => {
+            *padding_mode_bitmap |= 1 << PaddingModeBitPosition::RSA_PSS_BIT_POS as i32;
+        }
+        PaddingMode::RSA_PKCS1_1_5_ENCRYPT => {
+            *padding_mode_bitmap |=
+                1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS as i32;
+        }
+        PaddingMode::RSA_PKCS1_1_5_SIGN => {
+            *padding_mode_bitmap |= 1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS as i32;
+        }
+        PaddingMode::PKCS7 => {
+            *padding_mode_bitmap |= 1 << PaddingModeBitPosition::PKCS7_BIT_POS as i32;
+        }
+        _ => {}
+    }
+}
+
+fn compute_digest_bitmap(digest_bitmap: &mut i32, digest: Digest) {
+    match digest {
+        Digest::NONE => {
+            *digest_bitmap |= 1 << DigestBitPosition::NONE_BIT_POSITION as i32;
+        }
+        Digest::MD5 => {
+            *digest_bitmap |= 1 << DigestBitPosition::MD5_BIT_POS as i32;
+        }
+        Digest::SHA1 => {
+            *digest_bitmap |= 1 << DigestBitPosition::SHA_1_BIT_POS as i32;
+        }
+        Digest::SHA_2_224 => {
+            *digest_bitmap |= 1 << DigestBitPosition::SHA_2_224_BIT_POS as i32;
+        }
+        Digest::SHA_2_256 => {
+            *digest_bitmap |= 1 << DigestBitPosition::SHA_2_256_BIT_POS as i32;
+        }
+        Digest::SHA_2_384 => {
+            *digest_bitmap |= 1 << DigestBitPosition::SHA_2_384_BIT_POS as i32;
+        }
+        Digest::SHA_2_512 => {
+            *digest_bitmap |= 1 << DigestBitPosition::SHA_2_512_BIT_POS as i32;
+        }
+        _ => {}
+    }
+}
+
+fn compute_block_mode_bitmap(block_mode_bitmap: &mut i32, block_mode: BlockMode) {
+    match block_mode {
+        BlockMode::ECB => {
+            *block_mode_bitmap |= 1 << BlockModeBitPosition::ECB_BIT_POS as i32;
+        }
+        BlockMode::CBC => {
+            *block_mode_bitmap |= 1 << BlockModeBitPosition::CBC_BIT_POS as i32;
+        }
+        BlockMode::CTR => {
+            *block_mode_bitmap |= 1 << BlockModeBitPosition::CTR_BIT_POS as i32;
+        }
+        BlockMode::GCM => {
+            *block_mode_bitmap |= 1 << BlockModeBitPosition::GCM_BIT_POS as i32;
+        }
+        _ => {}
+    }
+}
+
+fn compute_purpose_bitmap(purpose_bitmap: &mut i32, purpose: KeyPurpose) {
+    match purpose {
+        KeyPurpose::ENCRYPT => {
+            *purpose_bitmap |= 1 << KeyPurposeBitPosition::ENCRYPT_BIT_POS as i32;
+        }
+        KeyPurpose::DECRYPT => {
+            *purpose_bitmap |= 1 << KeyPurposeBitPosition::DECRYPT_BIT_POS as i32;
+        }
+        KeyPurpose::SIGN => {
+            *purpose_bitmap |= 1 << KeyPurposeBitPosition::SIGN_BIT_POS as i32;
+        }
+        KeyPurpose::VERIFY => {
+            *purpose_bitmap |= 1 << KeyPurposeBitPosition::VERIFY_BIT_POS as i32;
+        }
+        KeyPurpose::WRAP_KEY => {
+            *purpose_bitmap |= 1 << KeyPurposeBitPosition::WRAP_KEY_BIT_POS as i32;
+        }
+        KeyPurpose::AGREE_KEY => {
+            *purpose_bitmap |= 1 << KeyPurposeBitPosition::AGREE_KEY_BIT_POS as i32;
+        }
+        KeyPurpose::ATTEST_KEY => {
+            *purpose_bitmap |= 1 << KeyPurposeBitPosition::ATTEST_KEY_BIT_POS as i32;
+        }
+        _ => {}
+    }
+}
+
+fn pull_storage_stats() -> Result<Vec<KeystoreAtom>> {
+    let mut atom_vec: Vec<KeystoreAtom> = Vec::new();
+    let mut append = |stat| {
+        match stat {
+            Ok(s) => atom_vec.push(KeystoreAtom {
+                payload: KeystoreAtomPayload::StorageStats(s),
+                ..Default::default()
+            }),
+            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(MetricsStorage::DATABASE));
+        append(db.get_storage_stat(MetricsStorage::KEY_ENTRY));
+        append(db.get_storage_stat(MetricsStorage::KEY_ENTRY_ID_INDEX));
+        append(db.get_storage_stat(MetricsStorage::KEY_ENTRY_DOMAIN_NAMESPACE_INDEX));
+        append(db.get_storage_stat(MetricsStorage::BLOB_ENTRY));
+        append(db.get_storage_stat(MetricsStorage::BLOB_ENTRY_KEY_ENTRY_ID_INDEX));
+        append(db.get_storage_stat(MetricsStorage::KEY_PARAMETER));
+        append(db.get_storage_stat(MetricsStorage::KEY_PARAMETER_KEY_ENTRY_ID_INDEX));
+        append(db.get_storage_stat(MetricsStorage::KEY_METADATA));
+        append(db.get_storage_stat(MetricsStorage::KEY_METADATA_KEY_ENTRY_ID_INDEX));
+        append(db.get_storage_stat(MetricsStorage::GRANT));
+        append(db.get_storage_stat(MetricsStorage::AUTH_TOKEN));
+        append(db.get_storage_stat(MetricsStorage::BLOB_METADATA));
+        append(db.get_storage_stat(MetricsStorage::BLOB_METADATA_BLOB_ENTRY_ID_INDEX));
+    });
+    Ok(atom_vec)
+}
+
+fn pull_attestation_pool_stats() -> Result<Vec<KeystoreAtom>> {
+    let mut atoms = Vec::<KeystoreAtom>::new();
+    for sec_level in &[SecurityLevel::TRUSTED_ENVIRONMENT, SecurityLevel::STRONGBOX] {
+        let expired_by = SystemTime::now()
+            .duration_since(UNIX_EPOCH)
+            .unwrap_or_else(|_| Duration::new(0, 0))
+            .as_secs() as i64;
+
+        let result = get_pool_status(expired_by, *sec_level);
+
+        if let Ok(pool_status) = result {
+            let rkp_pool_stats = RkpPoolStats {
+                security_level: process_security_level(*sec_level),
+                expiring: pool_status.expiring,
+                unassigned: pool_status.unassigned,
+                attested: pool_status.attested,
+                total: pool_status.total,
+            };
+            atoms.push(KeystoreAtom {
+                payload: KeystoreAtomPayload::RkpPoolStats(rkp_pool_stats),
+                ..Default::default()
+            });
+        } else {
+            log::error!(
+                concat!(
+                    "In pull_attestation_pool_stats: Failed to retrieve pool status",
+                    " for security level: {:?}"
+                ),
+                sec_level
+            );
+        }
+    }
+    Ok(atoms)
+}
+
+/// Log error events related to Remote Key Provisioning (RKP).
+pub fn log_rkp_error_stats(rkp_error: MetricsRkpError) {
+    let rkp_error_stats = KeystoreAtomPayload::RkpErrorStats(RkpErrorStats { rkpError: rkp_error });
+    METRICS_STORE.insert_atom(AtomID::RKP_ERROR_STATS, rkp_error_stats);
+}
+
+/// This function tries to read and update the system property: keystore.crash_count.
+/// If the property is absent, it sets the property with value 0. If the property is present, it
+/// increments the value. This helps tracking keystore crashes internally.
+pub fn update_keystore_crash_sysprop() {
+    let crash_count = read_keystore_crash_count();
+    let new_count = match crash_count {
+        Ok(count) => count + 1,
+        Err(error) => {
+            // If the property is absent, this is the first start up during the boot.
+            // Proceed to write the system property with value 0. Otherwise, log and return.
+            if !matches!(
+                error.root_cause().downcast_ref::<PropertyWatcherError>(),
+                Some(PropertyWatcherError::SystemPropertyAbsent)
+            ) {
+                log::warn!(
+                    concat!(
+                        "In update_keystore_crash_sysprop: ",
+                        "Failed to read the existing system property due to: {:?}.",
+                        "Therefore, keystore crashes will not be logged."
+                    ),
+                    error
+                );
+                return;
+            }
+            0
+        }
+    };
+
+    if let Err(e) =
+        rustutils::system_properties::write(KEYSTORE_CRASH_COUNT_PROPERTY, &new_count.to_string())
+    {
+        log::error!(
+            concat!(
+                "In update_keystore_crash_sysprop:: ",
+                "Failed to write the system property due to error: {:?}"
+            ),
+            e
+        );
+    }
+}
+
+/// Read the system property: keystore.crash_count.
+pub fn read_keystore_crash_count() -> Result<i32> {
+    rustutils::system_properties::read("keystore.crash_count")
+        .context("In read_keystore_crash_count: Failed read property.")?
+        .parse::<i32>()
+        .map_err(std::convert::Into::into)
+}
+
+/// 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)]
+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)]
+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
index c98a76b..7e08f4e 100644
--- a/keystore2/src/operation.rs
+++ b/keystore2/src/operation.rs
@@ -126,18 +126,18 @@
 //! Either way, we have to revaluate the pruning scores.
 
 use crate::enforcements::AuthInfo;
-use crate::error::{map_km_error, map_or_log_err, Error, ErrorCode, ResponseCode};
-use crate::utils::Asp;
+use crate::error::{map_err_with, map_km_error, map_or_log_err, Error, ErrorCode, ResponseCode};
+use crate::metrics_store::log_key_operation_event_stats;
+use crate::utils::watchdog as wd;
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
-    ByteArray::ByteArray, IKeyMintOperation::IKeyMintOperation,
-    KeyParameter::KeyParameter as KmParam, KeyParameterArray::KeyParameterArray,
-    KeyParameterValue::KeyParameterValue as KmParamValue, Tag::Tag,
+    IKeyMintOperation::IKeyMintOperation, KeyParameter::KeyParameter, KeyPurpose::KeyPurpose,
+    SecurityLevel::SecurityLevel,
 };
+use android_hardware_security_keymint::binder::{BinderFeatures, Strong};
 use android_system_keystore2::aidl::android::system::keystore2::{
     IKeystoreOperation::BnKeystoreOperation, IKeystoreOperation::IKeystoreOperation,
 };
 use anyhow::{anyhow, Context, Result};
-use binder::IBinder;
 use std::{
     collections::HashMap,
     sync::{Arc, Mutex, MutexGuard, Weak},
@@ -149,12 +149,18 @@
 /// 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)]
-enum Outcome {
+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),
 }
 
@@ -164,17 +170,41 @@
 pub struct Operation {
     // The index of this operation in the OperationDb.
     index: usize,
-    km_op: Asp,
+    km_op: Strong<dyn IKeyMintOperation>,
     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`.
@@ -187,14 +217,18 @@
         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()),
+            km_op,
             last_usage: Mutex::new(Instant::now()),
             outcome: Mutex::new(Outcome::Unknown),
             owner,
             auth_info: Mutex::new(auth_info),
+            forced,
+            logging_info,
         }
     }
 
@@ -220,6 +254,7 @@
             last_usage: *self.last_usage.lock().expect("In get_pruning_info."),
             owner: self.owner,
             index: self.index,
+            forced: self.forced,
         })
     }
 
@@ -247,17 +282,10 @@
         }
         *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()) {
+        if let Err(e) = map_km_error(self.km_op.abort()) {
             log::error!("In prune: KeyMint::abort failed with {:?}.", e);
         }
 
@@ -325,19 +353,6 @@
         Self::check_input_length(aad_input).context("In update_aad")?;
         self.touch();
 
-        let params = KeyParameterArray {
-            params: vec![KmParam {
-                tag: Tag::ASSOCIATED_DATA,
-                value: KmParamValue::Blob(aad_input.into()),
-            }],
-        };
-
-        let mut out_params: Option<KeyParameterArray> = None;
-        let mut output: Option<ByteArray> = None;
-
-        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()
@@ -345,17 +360,10 @@
             .before_update()
             .context("In update_aad: Trying to get auth tokens.")?;
 
-        self.update_outcome(
-            &mut *outcome,
-            map_km_error(km_op.update(
-                Some(&params),
-                None,
-                hat.as_ref(),
-                tst.as_ref(),
-                &mut out_params,
-                &mut output,
-            )),
-        )
+        self.update_outcome(&mut *outcome, {
+            let _wp = wd::watch_millis("Operation::update_aad: calling updateAad", 500);
+            map_km_error(self.km_op.updateAad(aad_input, hat.as_ref(), tst.as_ref()))
+        })
         .context("In update_aad: KeyMint::update failed.")?;
 
         Ok(())
@@ -368,11 +376,6 @@
         Self::check_input_length(input).context("In update")?;
         self.touch();
 
-        let mut out_params: Option<KeyParameterArray> = None;
-
-        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()
@@ -380,39 +383,17 @@
             .before_update()
             .context("In update: Trying to get auth tokens.")?;
 
-        let mut result: Option<Vec<u8>> = None;
-        let mut consumed = 0usize;
-        loop {
-            let mut output: Option<ByteArray> = None;
-            consumed += self
-                .update_outcome(
-                    &mut *outcome,
-                    map_km_error(km_op.update(
-                        None,
-                        Some(&input[consumed..]),
-                        hat.as_ref(),
-                        tst.as_ref(),
-                        &mut out_params,
-                        &mut output,
-                    )),
-                )
-                .context("In update: KeyMint::update failed.")? as usize;
+        let output = self
+            .update_outcome(&mut *outcome, {
+                let _wp = wd::watch_millis("Operation::update: calling update", 500);
+                map_km_error(self.km_op.update(input, hat.as_ref(), tst.as_ref()))
+            })
+            .context("In update: KeyMint::update failed.")?;
 
-            match (output, &mut result) {
-                (Some(blob), None) => {
-                    if !blob.data.is_empty() {
-                        result = Some(blob.data)
-                    }
-                }
-                (Some(mut blob), Some(ref mut result)) => {
-                    result.append(&mut blob.data);
-                }
-                (None, _) => {}
-            }
-
-            if consumed == input.len() {
-                return Ok(result);
-            }
+        if output.is_empty() {
+            Ok(None)
+        } else {
+            Ok(Some(output))
         }
     }
 
@@ -425,11 +406,6 @@
         }
         self.touch();
 
-        let mut out_params: Option<KeyParameterArray> = None;
-
-        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()
@@ -437,25 +413,17 @@
             .before_finish()
             .context("In finish: Trying to get auth tokens.")?;
 
-        let in_params = confirmation_token.map(|token| KeyParameterArray {
-            params: vec![KmParam {
-                tag: Tag::CONFIRMATION_TOKEN,
-                value: KmParamValue::Blob(token),
-            }],
-        });
-
         let output = self
-            .update_outcome(
-                &mut *outcome,
-                map_km_error(km_op.finish(
-                    in_params.as_ref(),
+            .update_outcome(&mut *outcome, {
+                let _wp = wd::watch_millis("Operation::finish: calling finish", 500);
+                map_km_error(self.km_op.finish(
                     input,
                     signature,
                     hat.as_ref(),
                     tst.as_ref(),
-                    &mut out_params,
-                )),
-            )
+                    confirmation_token.as_deref(),
+                ))
+            })
             .context("In finish: KeyMint::finish failed.")?;
 
         self.auth_info.lock().unwrap().after_finish().context("In finish.")?;
@@ -476,16 +444,26 @@
     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.")?;
 
-        map_km_error(km_op.abort()).context("In abort: KeyMint::abort failed.")
+        {
+            let _wp = wd::watch_millis("Operation::abort: calling abort", 500);
+            map_km_error(self.km_op.abort()).context("In abort: KeyMint::abort failed.")
+        }
     }
 }
 
 impl Drop for Operation {
     fn drop(&mut self) {
-        if let Ok(Outcome::Unknown) = self.outcome.get_mut() {
+        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) {
@@ -518,6 +496,8 @@
         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.");
@@ -530,12 +510,26 @@
             s.upgrade().is_none()
         }) {
             Some(free_slot) => {
-                let new_op = Arc::new(Operation::new(index - 1, km_op, owner, auth_info));
+                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));
+                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
             }
@@ -618,7 +612,7 @@
     /// ## 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) -> Result<(), Error> {
+    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
@@ -643,7 +637,8 @@
                     }
                 });
 
-            let caller_malus = 1u64 + *owners.entry(caller).or_default();
+            // 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
@@ -657,7 +652,7 @@
             let mut oldest_caller_op: Option<CandidateInfo> = None;
             let candidate = pruning_info.iter().fold(
                 None,
-                |acc: Option<CandidateInfo>, &PruningInfo { last_usage, owner, index }| {
+                |acc: Option<CandidateInfo>, &PruningInfo { last_usage, owner, index, forced }| {
                     // Compute the age of the current operation.
                     let age = now
                         .checked_duration_since(last_usage)
@@ -677,12 +672,17 @@
                     }
 
                     // Compute the malus of the current operation.
-                    // Expect safety: Every owner in pruning_info was counted in
-                    // the owners map. So this unwrap cannot panic.
-                    let malus = *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;
+                    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.
@@ -768,16 +768,16 @@
 
 impl KeystoreOperation {
     /// Creates a new operation instance wrapped in a
-    /// BnKeystoreOperation proxy object. It also
-    /// calls `IBinder::set_requesting_sid` on the new interface, because
+    /// 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> {
-        let result =
-            BnKeystoreOperation::new_binder(Self { operation: Mutex::new(Some(operation)) });
-        result.as_binder().set_requesting_sid(true);
-        result
+        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.
@@ -822,6 +822,7 @@
 
 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"),
@@ -832,6 +833,7 @@
     }
 
     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"),
@@ -845,6 +847,7 @@
         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"),
@@ -855,11 +858,22 @@
     }
 
     fn abort(&self) -> binder::public_api::Result<()> {
-        map_or_log_err(
+        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
index 576ac3f..4392acf 100644
--- a/keystore2/src/permission.rs
+++ b/keystore2/src/permission.rs
@@ -149,16 +149,16 @@
             }
         }
 
-        impl Into<$aidl_name> for $name {
-            fn into(self) -> $aidl_name {
-                self.0
+        impl From<$name> for $aidl_name {
+            fn from(p: $name) -> $aidl_name {
+                p.0
             }
         }
 
         impl $name {
             /// Returns a string representation of the permission as required by
             /// `selinux::check_access`.
-            pub fn to_selinux(&self) -> &'static str {
+            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),)*
@@ -193,6 +193,7 @@
     /// ```
     #[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;
@@ -256,16 +257,16 @@
             }
         }
 
-        impl Into<i32> for $name {
-            fn into(self) -> i32 {
-                self as i32
+        impl From<$name> for i32 {
+            fn from(p: $name) -> i32 {
+                p as i32
             }
         }
 
         impl $name {
             /// Returns a string representation of the permission as required by
             /// `selinux::check_access`.
-            pub fn to_selinux(&self) -> &'static str {
+            pub fn to_selinux(self) -> &'static str {
                 match self {
                     Self::$def_name => stringify!($def_selinux_name),
                     $(Self::$element_name => stringify!($selinux_name),)*
@@ -291,7 +292,7 @@
         AddAuth = 1,    selinux name: add_auth;
         /// Checked when an app is uninstalled or wiped.
         ClearNs = 2,    selinux name: clear_ns;
-        /// Checked when Keystore 2.0 gets locked.
+        /// 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.
@@ -308,6 +309,16 @@
         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;
+        /// Checked when IkeystoreMetrics::pullMetris is called.
+        PullMetrics = 0x2000, selinux name: pull_metrics;
+        /// Checked when IKeystoreMaintenance::deleteAllKeys is called.
+        DeleteAllKeys = 0x4000, selinux name: delete_all_keys;
     }
 );
 
@@ -582,6 +593,7 @@
         KeyPerm::rebind(),
         KeyPerm::update(),
         KeyPerm::use_(),
+        KeyPerm::convert_storage_key_to_ephemeral(),
     ];
 
     const SYSTEM_SERVER_PERMISSIONS_NO_GRANT: KeyPermSet = key_perm_set![
@@ -605,6 +617,7 @@
         KeyPerm::rebind(),
         KeyPerm::update(),
         KeyPerm::use_(),
+        KeyPerm::convert_storage_key_to_ephemeral(),
     ];
 
     const UNPRIV_PERMS: KeyPermSet = key_perm_set![
@@ -673,7 +686,7 @@
         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_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::get_state()));
+        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()));
@@ -841,23 +854,19 @@
             blob: None,
         };
 
+        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());
+
         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,
diff --git a/keystore2/src/raw_device.rs b/keystore2/src/raw_device.rs
new file mode 100644
index 0000000..991535f
--- /dev/null
+++ b/keystore2/src/raw_device.rs
@@ -0,0 +1,333 @@
+// 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, ErrorCode},
+    globals::get_keymint_device,
+    super_key::KeyBlob,
+    utils::{key_characteristics_to_internal, watchdog as wd, AID_KEYSTORE},
+};
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    HardwareAuthToken::HardwareAuthToken, IKeyMintDevice::IKeyMintDevice,
+    IKeyMintOperation::IKeyMintOperation, KeyCharacteristics::KeyCharacteristics,
+    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 {
+    km_dev: Strong<dyn IKeyMintDevice>,
+    km_uuid: Uuid,
+    version: i32,
+    security_level: SecurityLevel,
+}
+
+impl KeyMintDevice {
+    /// Version number of KeyMasterDevice@V4_0
+    pub const KEY_MASTER_V4_0: i32 = 40;
+    /// Version number of KeyMasterDevice@V4_1
+    pub const KEY_MASTER_V4_1: i32 = 41;
+    /// Version number of KeyMintDevice@V1
+    pub const KEY_MINT_V1: i32 = 100;
+
+    /// Get a [`KeyMintDevice`] for the given [`SecurityLevel`]
+    pub fn get(security_level: SecurityLevel) -> Result<KeyMintDevice> {
+        let (km_dev, hw_info, km_uuid) = get_keymint_device(&security_level)
+            .context("In KeyMintDevice::get: get_keymint_device failed")?;
+
+        Ok(KeyMintDevice {
+            km_dev,
+            km_uuid,
+            version: hw_info.versionNumber,
+            security_level: hw_info.securityLevel,
+        })
+    }
+
+    /// Get a [`KeyMintDevice`] for the given [`SecurityLevel`], return
+    /// [`None`] if the error `HARDWARE_TYPE_UNAVAILABLE` is returned
+    pub fn get_or_none(security_level: SecurityLevel) -> Result<Option<KeyMintDevice>> {
+        KeyMintDevice::get(security_level).map(Some).or_else(|e| {
+            match e.root_cause().downcast_ref::<Error>() {
+                Some(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)) => Ok(None),
+                _ => Err(e),
+            }
+        })
+    }
+
+    /// Returns the version of the underlying KeyMint/KeyMaster device.
+    pub fn version(&self) -> i32 {
+        self.version
+    }
+
+    /// Returns the self advertised security level of the KeyMint device.
+    /// This may differ from the requested security level if the best security level
+    /// on the device is Software.
+    pub fn security_level(&self) -> SecurityLevel {
+        self.security_level
+    }
+
+    /// Create a KM key and store in the database.
+    pub fn create_and_store_key<F>(
+        &self,
+        db: &mut KeystoreDB,
+        key_desc: &KeyDescriptor,
+        key_type: KeyType,
+        creator: F,
+    ) -> Result<()>
+    where
+        F: FnOnce(&Strong<dyn IKeyMintDevice>) -> Result<KeyCreationResult, binder::Status>,
+    {
+        let creation_result = map_km_error(creator(&self.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_type,
+            &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.
+    fn lookup_from_desc(
+        db: &mut KeystoreDB,
+        key_desc: &KeyDescriptor,
+        key_type: KeyType,
+    ) -> Result<(KeyIdGuard, KeyEntry)> {
+        db.load_key_entry(key_desc, key_type, 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.
+    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<F>(
+        &self,
+        db: &mut KeystoreDB,
+        key_desc: &KeyDescriptor,
+        key_type: KeyType,
+        params: &[KeyParameter],
+        validate_characteristics: F,
+    ) -> Result<(KeyIdGuard, KeyBlob)>
+    where
+        F: FnOnce(&[KeyCharacteristics]) -> bool,
+    {
+        // 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, key_type))
+            .context("In lookup_or_generate_key: first lookup failed")?;
+
+        if let Some((key_id_guard, mut key_entry)) = lookup {
+            // If the key is associated with a different km instance
+            // or if there is no blob metadata for some reason the key entry
+            // is considered corrupted and needs to be replaced with a new one.
+            let key_blob = key_entry.take_key_blob_info().and_then(|(key_blob, blob_metadata)| {
+                if Some(&self.km_uuid) == blob_metadata.km_uuid() {
+                    Some(key_blob)
+                } else {
+                    None
+                }
+            });
+
+            if let Some(key_blob_vec) = key_blob {
+                let (key_characteristics, key_blob) = self
+                    .upgrade_keyblob_if_required_with(
+                        db,
+                        &key_id_guard,
+                        KeyBlob::NonSensitive(key_blob_vec),
+                        |key_blob| {
+                            map_km_error({
+                                let _wp = wd::watch_millis(
+                                    concat!(
+                                        "In KeyMintDevice::lookup_or_generate_key: ",
+                                        "calling getKeyCharacteristics."
+                                    ),
+                                    500,
+                                );
+                                self.km_dev.getKeyCharacteristics(key_blob, &[], &[])
+                            })
+                        },
+                    )
+                    .context("In lookup_or_generate_key: calling getKeyCharacteristics")?;
+
+                if validate_characteristics(&key_characteristics) {
+                    return Ok((key_id_guard, key_blob));
+                }
+
+                // If this point is reached the existing key is considered outdated or corrupted
+                // in some way. It will be replaced with a new key below.
+            };
+        }
+
+        self.create_and_store_key(db, key_desc, key_type, |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, key_type)
+            .and_then(|(key_id_guard, mut key_entry)| {
+                Ok((
+                    key_id_guard,
+                    key_entry
+                        .take_key_blob_info()
+                        .ok_or(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+                        .map(|(key_blob, _)| KeyBlob::NonSensitive(key_blob))
+                        .context("Missing key blob info.")?,
+                ))
+            })
+            .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<'a, T, F>(
+        &self,
+        db: &mut KeystoreDB,
+        key_id_guard: &KeyIdGuard,
+        key_blob: KeyBlob<'a>,
+        f: F,
+    ) -> Result<(T, KeyBlob<'a>)>
+    where
+        F: Fn(&[u8]) -> Result<T, Error>,
+    {
+        match f(&key_blob) {
+            Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
+                let upgraded_blob = map_km_error({
+                    let _wp = wd::watch_millis(
+                        "In KeyMintDevice::upgrade_keyblob_if_required_with: calling upgradeKey.",
+                        500,
+                    );
+                    self.km_dev.upgradeKey(&key_blob, &[])
+                })
+                .context("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(
+                        "In upgrade_keyblob_if_required_with: Closure failed after upgrade",
+                    )?,
+                    KeyBlob::NonSensitive(upgraded_blob),
+                ))
+            }
+            result => Ok((
+                result.context("In upgrade_keyblob_if_required_with: Closure failed")?,
+                key_blob,
+            )),
+        }
+    }
+
+    /// 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_blob: &[u8],
+        purpose: KeyPurpose,
+        operation_parameters: &[KeyParameter],
+        auth_token: Option<&HardwareAuthToken>,
+        input: &[u8],
+    ) -> Result<Vec<u8>> {
+        let key_blob = KeyBlob::Ref(key_blob);
+
+        let (begin_result, _) = self
+            .upgrade_keyblob_if_required_with(db, key_id_guard, key_blob, |blob| {
+                map_km_error({
+                    let _wp = wd::watch_millis("In use_key_in_one_step: calling: begin", 500);
+                    self.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
index d606b6a..a19462b 100644
--- a/keystore2/src/remote_provisioning.rs
+++ b/keystore2/src/remote_provisioning.rs
@@ -22,24 +22,204 @@
 use std::collections::HashMap;
 
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
-    IRemotelyProvisionedComponent::IRemotelyProvisionedComponent, MacedPublicKey::MacedPublicKey,
-    ProtectedData::ProtectedData, SecurityLevel::SecurityLevel,
+    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,
+    IRemoteProvisioning::IRemoteProvisioning, ImplInfo::ImplInfo,
 };
-use android_security_remoteprovisioning::binder::Strong;
+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::error::{self, map_or_log_err, map_rem_prov_error};
+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::Asp;
+use crate::metrics_store::log_rkp_error_stats;
+use crate::utils::watchdog as wd;
+use android_security_metrics::aidl::android::security::metrics::RkpError::RkpError as MetricsRkpError;
 
+/// 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) {
+                Err(e) => {
+                    log::error!(
+                        concat!(
+                            "In get_remote_provisioning_key_and_certs: Failed to get ",
+                            "attestation key. {:?}"
+                        ),
+                        e
+                    );
+                    log_rkp_error_stats(MetricsRkpError::FALL_BACK_DURING_HYBRID);
+                    Ok(None)
+                }
+                Ok(v) => match v {
+                    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>,
+    device_by_sec_level: HashMap<SecurityLevel, Strong<dyn IRemotelyProvisionedComponent>>,
+    curve_by_sec_level: HashMap<SecurityLevel, i32>,
 }
 
 impl RemoteProvisioningService {
@@ -48,7 +228,7 @@
         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.")
+            Ok(dev.clone())
         } else {
             Err(error::Error::sys()).context(concat!(
                 "In get_dev_by_sec_level: Remote instance for requested security level",
@@ -62,31 +242,23 @@
         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.curve_by_sec_level.insert(
+            SecurityLevel::TRUSTED_ENVIRONMENT,
+            dev.getHardwareInfo()
+                .context("In new_native_binder: Failed to get hardware info for the TEE.")?
+                .supportedEekCurve,
+        );
         result.device_by_sec_level.insert(SecurityLevel::TRUSTED_ENVIRONMENT, dev);
         if let Ok(dev) = get_remotely_provisioned_component(&SecurityLevel::STRONGBOX) {
+            result.curve_by_sec_level.insert(
+                SecurityLevel::STRONGBOX,
+                dev.getHardwareInfo()
+                    .context("In new_native_binder: Failed to get hardware info for StrongBox.")?
+                    .supportedEekCurve,
+            );
             result.device_by_sec_level.insert(SecurityLevel::STRONGBOX, dev);
         }
-        Ok(BnRemoteProvisioning::new_binder(result))
-    }
-
-    /// 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)?)
-        })
+        Ok(BnRemoteProvisioning::new_binder(result, BinderFeatures::default()))
     }
 
     /// Generates a CBOR blob which will be assembled by the calling code into a larger
@@ -97,6 +269,7 @@
     /// 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,
@@ -105,6 +278,7 @@
         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)?;
@@ -116,17 +290,39 @@
                 .map(|key| MacedPublicKey { macedKey: key.to_vec() })
                 .collect())
         })?;
-        let mut mac = Vec::<u8>::with_capacity(32);
-        map_rem_prov_error(dev.generateCertificateRequest(
+        let mut mac = map_rem_prov_error(dev.generateCertificateRequest(
             test_mode,
             &keys_to_sign,
             eek,
             challenge,
-            &mut mac,
+            device_info,
             protected_data,
         ))
         .context("In generate_csr: Failed to generate csr")?;
-        Ok(mac)
+        // 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.
+        let mut cose_mac_0: Vec<u8> = vec![
+            (0b100_00000 | (keys_to_sign.len() + 1)) as u8,
+            0b010_11000, // mac
+            (mac.len() as u8),
+        ];
+        cose_mac_0.append(&mut mac);
+        // If this is a test mode key, there is an extra 6 bytes added as an additional entry in
+        // the COSE_Key struct to denote that.
+        let test_mode_entry_shift = if test_mode { 0 } else { 6 };
+        let byte_dist_mac0_payload = 8;
+        let cose_key_size = 83 - test_mode_entry_shift;
+        for maced_public_key in keys_to_sign {
+            if maced_public_key.macedKey.len() > cose_key_size + byte_dist_mac0_payload {
+                cose_mac_0.extend_from_slice(
+                    &maced_public_key.macedKey
+                        [byte_dist_mac0_payload..cose_key_size + byte_dist_mac0_payload],
+                );
+            }
+        }
+        Ok(cose_mac_0)
     }
 
     /// Provisions a certificate chain for a key whose CSR was included in generate_csr. The
@@ -145,13 +341,13 @@
         DB.with::<_, Result<()>>(|db| {
             let mut db = db.borrow_mut();
             let (_, _, uuid) = get_keymint_device(&sec_level)?;
-            Ok(db.store_signed_attestation_certificate_chain(
+            db.store_signed_attestation_certificate_chain(
                 public_key,
                 batch_cert,
                 certs, /* DER encoded certificate chain */
                 expiration_date,
                 &uuid,
-            )?)
+            )
         })
     }
 
@@ -180,15 +376,44 @@
         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)?)
+            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())
+    pub fn get_implementation_info(&self) -> Result<Vec<ImplInfo>> {
+        Ok(self
+            .curve_by_sec_level
+            .iter()
+            .map(|(sec_level, curve)| ImplInfo { secLevel: *sec_level, supportedCurve: *curve })
+            .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();
+            db.delete_all_attestation_keys()
+        })
+    }
+}
+
+/// 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(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()?;
+        db.get_attestation_pool_status(expired_by, &uuid)
+    })
 }
 
 impl binder::Interface for RemoteProvisioningService {}
@@ -201,7 +426,8 @@
         expired_by: i64,
         sec_level: SecurityLevel,
     ) -> binder::public_api::Result<AttestationPoolStatus> {
-        map_or_log_err(self.get_pool_status(expired_by, sec_level), Ok)
+        let _wp = wd::watch_millis("IRemoteProvisioning::getPoolStatus", 500);
+        map_or_log_err(get_pool_status(expired_by, sec_level), Ok)
     }
 
     fn generateCsr(
@@ -212,9 +438,19 @@
         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),
+            self.generate_csr(
+                test_mode,
+                num_csr,
+                eek,
+                challenge,
+                sec_level,
+                protected_data,
+                device_info,
+            ),
             Ok,
         )
     }
@@ -227,6 +463,7 @@
         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,
@@ -238,10 +475,17 @@
         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>> {
-        map_or_log_err(self.get_security_levels(), Ok)
+    fn getImplementationInfo(&self) -> binder::public_api::Result<Vec<ImplInfo>> {
+        let _wp = wd::watch_millis("IRemoteProvisioning::getSecurityLevels", 500);
+        map_or_log_err(self.get_implementation_info(), 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
index 5e1ce84..74aba3c 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -12,11 +12,35 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#![allow(unused_variables)]
-
 //! This crate implements the IKeystoreSecurityLevel interface.
 
-use crate::globals::get_keymint_device;
+use crate::attestation_key_utils::{get_attest_key_info, AttestationKeyInfo};
+use crate::audit_log::{
+    log_key_deleted, log_key_generated, log_key_imported, log_key_integrity_violation,
+};
+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_store::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,
+};
+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,
@@ -24,45 +48,25 @@
     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, IKeystoreOperation::IKeystoreOperation,
-    IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
+    Domain::Domain, EphemeralStorageKeyResponse::EphemeralStorageKeyResponse,
+    IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
     IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
     KeyMetadata::KeyMetadata, KeyParameters::KeyParameters,
 };
-
-use crate::database::{CertificateInfo, KeyIdGuard};
-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::super_key::{KeyBlob, SuperKeyManager};
-use crate::utils::{check_key_permission, uid_to_android_user, Asp};
-use crate::{
-    database::{
-        BlobMetaData, BlobMetaEntry, DateTime, KeyEntry, KeyEntryLoadBits, KeyMetaData,
-        KeyMetaEntry, KeyType, SubComponentType, Uuid,
-    },
-    operation::KeystoreOperation,
-    operation::OperationDb,
-    permission::KeyPerm,
-};
-use crate::{
-    error::{self, map_km_error, map_or_log_err, Error, ErrorCode},
-    utils::key_characteristics_to_internal,
-};
 use anyhow::{anyhow, Context, Result};
-use binder::{IBinder, Strong, ThreadState};
-use keystore2_crypto::parse_issuer_subject_from_certificate;
 
 /// Implementation of the IKeystoreSecurityLevel Interface.
 pub struct KeystoreSecurityLevel {
     security_level: SecurityLevel,
-    keymint: Asp,
-    #[allow(dead_code)]
+    keymint: Strong<dyn IKeyMintDevice>,
     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.
@@ -74,25 +78,35 @@
 
 impl KeystoreSecurityLevel {
     /// Creates a new security level instance wrapped in a
-    /// BnKeystoreSecurityLevel proxy object. It also
-    /// calls `IBinder::set_requesting_sid` on the new interface, because
+    /// 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(),
-        });
-        result.as_binder().set_requesting_sid(true);
+        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,
@@ -131,36 +145,38 @@
             SecurityLevel::SOFTWARE,
         ));
 
-        let (key_blob, mut blob_metadata) = DB
-            .with(|db| {
-                SUPER_KEY.handle_super_encryption_on_key_init(
-                    &mut db.borrow_mut(),
-                    &LEGACY_MIGRATOR,
-                    &(key.domain),
-                    &key_parameters,
-                    flags,
-                    user_id,
-                    &key_blob,
-                )
-            })
-            .context("In store_new_key. Failed to handle super encryption.")?;
-
         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), ..Default::default() }
-            }
+            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 mut db = db.borrow_mut();
                     let key_id = db
                         .store_new_key(
                             &key,
+                            KeyType::Client,
                             &key_parameters,
                             &(&key_blob, &blob_metadata),
                             &cert_info,
@@ -202,6 +218,11 @@
             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,
@@ -220,13 +241,19 @@
             _ => {
                 let (key_id_guard, mut key_entry) = DB
                     .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
-                        LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+                        LEGACY_MIGRATOR.with_try_migrate(key, caller_uid, || {
                             db.borrow_mut().load_key_entry(
-                                &key,
+                                key,
                                 KeyType::Client,
                                 KeyEntryLoadBits::KM,
                                 caller_uid,
-                                |k, av| check_key_permission(KeyPerm::use_(), k, &av),
+                                |k, av| {
+                                    check_key_permission(KeyPerm::use_(), k, &av)?;
+                                    if forced {
+                                        check_key_permission(KeyPerm::req_forced_op(), k, &av)?;
+                                    }
+                                    Ok(())
+                                },
                             )
                         })
                     })
@@ -258,48 +285,61 @@
             },
         )?;
 
+        // 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(),
-                // TODO b/178222844 Replace this with the configuration returned by
-                //      KeyMintDevice::getHardwareInfo.
-                //      For now we assume that strongbox implementations need secure timestamps.
-                self.security_level == SecurityLevel::STRONGBOX,
+                self.hw_info.timestampTokenRequired,
             )
             .context("In create_operation.")?;
 
-        let immediate_hat = immediate_hat.unwrap_or_default();
-
-        let user_id = uid_to_android_user(caller_uid);
-
         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,
+                &*self.keymint,
                 key_id_guard,
-                &(&km_blob, &blob_metadata),
-                &operation_parameters,
+                &km_blob,
+                &blob_metadata,
+                operation_parameters,
                 |blob| loop {
-                    match map_km_error(km_dev.begin(
-                        purpose,
-                        blob,
-                        &operation_parameters,
-                        &immediate_hat,
-                    )) {
+                    match map_km_error({
+                        let _wp = self.watch_millis(
+                            "In KeystoreSecurityLevel::create_operation: calling begin",
+                            500,
+                        );
+                        self.keymint.begin(
+                            purpose,
+                            blob,
+                            operation_parameters,
+                            immediate_hat.as_ref(),
+                        )
+                    }) {
                         Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
-                            self.operation_db.prune(caller_uid)?;
+                            self.operation_db.prune(caller_uid, forced)?;
                             continue;
                         }
+                        v @ Err(Error::Km(ErrorCode::INVALID_KEY_BLOB)) => {
+                            if let Some((key_id, _)) = key_properties {
+                                if let Ok(Some(key)) =
+                                    DB.with(|db| db.borrow_mut().load_key_descriptor(key_id))
+                                {
+                                    log_key_integrity_violation(&key);
+                                } else {
+                                    log::error!("Failed to load key descriptor for audit log");
+                                }
+                            }
+                            return v;
+                        }
                         v => return v,
                     }
                 },
@@ -308,11 +348,22 @@
 
         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)
-            },
-            None => return Err(Error::sys()).context("In create_operation: Begin operation returned successfully, but did not return a valid 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> =
@@ -328,10 +379,15 @@
                 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,
@@ -339,9 +395,19 @@
         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 = keystore2_aaid::get_aaid(uid).map_err(|e| {
-                anyhow!(format!("In add_certificate_parameters: get_aaid returned status {}.", e))
-            })?;
+            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),
@@ -351,7 +417,24 @@
         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 for device unique attestation."
+                "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."
             ))?;
         }
 
@@ -384,7 +467,7 @@
         attest_key_descriptor: Option<&KeyDescriptor>,
         params: &[KeyParameter],
         flags: i32,
-        entropy: &[u8],
+        _entropy: &[u8],
     ) -> Result<KeyMetadata> {
         if key.domain != Domain::BLOB && key.alias.is_none() {
             return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
@@ -403,84 +486,100 @@
         };
 
         // 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 attest_key = match attest_key_descriptor {
-            None => None,
-            Some(key) => Some(
-                self.get_attest_key(key, caller_uid)
-                    .context("In generate_key: Trying to load attest key")?,
-            ),
+        let 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)
+        let params = self
+            .add_certificate_parameters(caller_uid, params, &key)
             .context("In generate_key: Trying to get aaid.")?;
 
-        let km_dev: Strong<dyn IKeyMintDevice> = self.keymint.get_interface()?;
-        map_km_error(km_dev.addRngEntropy(entropy))
-            .context("In generate_key: Trying to add entropy.")?;
-        let creation_result = map_km_error(km_dev.generateKey(&params, attest_key.as_ref()))
-            .context("In generate_key: While generating Key")?;
+        let creation_result = match attestation_key_info {
+            Some(AttestationKeyInfo::UserGenerated {
+                key_id_guard,
+                blob,
+                blob_metadata,
+                issuer_subject,
+            }) => self
+                .upgrade_keyblob_if_required_with(
+                    &*self.keymint,
+                    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.
+                            );
+                            self.keymint.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.
+                    );
+                    self.keymint.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.
+                );
+                self.keymint.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 get_attest_key(&self, key: &KeyDescriptor, caller_uid: u32) -> Result<AttestationKey> {
-        let (km_blob, cert) = self
-            .load_attest_key_blob_and_cert(&key, caller_uid)
-            .context("In get_attest_key: Failed to load blob and cert")?;
-
-        let issuer_subject: Vec<u8> = parse_issuer_subject_from_certificate(&cert)
-            .context("In get_attest_key: Failed to parse subject from certificate.")?;
-
-        Ok(AttestationKey {
-            keyBlob: km_blob.to_vec(),
-            attestKeyParams: [].to_vec(),
-            issuerSubjectName: issuer_subject,
-        })
-    }
-
-    fn load_attest_key_blob_and_cert(
-        &self,
-        key: &KeyDescriptor,
-        caller_uid: u32,
-    ) -> Result<(Vec<u8>, Vec<u8>)> {
-        match key.domain {
-            Domain::BLOB => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
-                "In load_attest_key_blob_and_cert: Domain::BLOB attestation keys not supported",
-            ),
-            _ => {
-                let (key_id_guard, mut key_entry) = DB
-                    .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
-                        db.borrow_mut().load_key_entry(
-                            &key,
-                            KeyType::Client,
-                            KeyEntryLoadBits::BOTH,
-                            caller_uid,
-                            |k, av| check_key_permission(KeyPerm::use_(), k, &av),
-                        )
-                    })
-                    .context("In load_attest_key_blob_and_cert: Failed to load key.")?;
-
-                let (blob, _) =
-                    key_entry.take_key_blob_info().ok_or_else(Error::sys).context(concat!(
-                        "In load_attest_key_blob_and_cert: Successfully loaded key entry,",
-                        " but KM blob was missing."
-                    ))?;
-                let cert = key_entry.take_cert().ok_or_else(Error::sys).context(concat!(
-                    "In load_attest_key_blob_and_cert: Successfully loaded key entry,",
-                    " but cert was missing."
-                ))?;
-                Ok((blob, cert))
-            }
-        }
-    }
-
     fn import_key(
         &self,
         key: &KeyDescriptor,
-        attestation_key: Option<&KeyDescriptor>,
+        _attestation_key: Option<&KeyDescriptor>,
         params: &[KeyParameter],
         flags: i32,
         key_data: &[u8],
@@ -504,7 +603,8 @@
         // 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)
+        let params = self
+            .add_certificate_parameters(caller_uid, params, &key)
             .context("In import_key: Trying to get aaid.")?;
 
         let format = params
@@ -523,11 +623,13 @@
             })
             .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(km_dev.importKey(&params, format, key_data, None /* attestKey */))
-                .context("In import_key: Trying to call importKey")?;
+        let km_dev = &self.keymint;
+        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.")
@@ -589,7 +691,7 @@
             .with(|db| {
                 LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
                     db.borrow_mut().load_key_entry(
-                        &wrapping_key,
+                        wrapping_key,
                         KeyType::Client,
                         KeyEntryLoadBits::KM,
                         caller_uid,
@@ -631,19 +733,23 @@
 
         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,
+                &*self.keymint,
                 Some(wrapping_key_id_guard),
-                &(&wrapping_key_blob, &wrapping_blob_metadata),
+                &wrapping_key_blob,
+                &wrapping_blob_metadata,
                 &[],
                 |wrapping_blob| {
-                    let creation_result = map_km_error(km_dev.importWrappedKey(
+                    let _wp = self.watch_millis(
+                        "In KeystoreSecurityLevel::import_wrapped_key: calling importWrappedKey.",
+                        500,
+                    );
+                    let creation_result = map_km_error(self.keymint.importWrappedKey(
                         wrapped_data,
                         wrapping_blob,
                         masking_key,
-                        &params,
+                        params,
                         pw_sid,
                         fp_sid,
                     ))?;
@@ -656,48 +762,71 @@
             .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>,
-        blob_info: &(&KeyBlob, &BlobMetaData),
+        key_blob: &KeyBlob,
+        blob_metadata: &BlobMetaData,
         params: &[KeyParameter],
         f: F,
     ) -> Result<(T, Option<Vec<u8>>)>
     where
         F: Fn(&[u8]) -> Result<T, Error>,
     {
-        match f(blob_info.0) {
+        match f(key_blob) {
             Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
-                let upgraded_blob = map_km_error(km_dev.upgradeKey(blob_info.0, params))
-                    .context("In upgrade_keyblob_if_required_with: Upgrade failed.")?;
+                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.")?;
 
-                let (upgraded_blob_to_be_stored, blob_metadata) =
-                    SuperKeyManager::reencrypt_on_upgrade_if_required(blob_info.0, &upgraded_blob)
-                        .context(
-                        "In upgrade_keyblob_if_required_with: Failed to handle super encryption.",
+                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",
                     )?;
-
-                let mut blob_metadata = blob_metadata.unwrap_or_else(BlobMetaData::new);
-                if let Some(uuid) = blob_info.1.km_uuid() {
-                    blob_metadata.add(BlobMetaEntry::KmUuid(*uuid));
                 }
 
-                key_id_guard.map_or(Ok(()), |key_id_guard| {
-                    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(&blob_metadata),
-                        )
-                    })
-                    .context(concat!(
-                        "In upgrade_keyblob_if_required_with: ",
-                        "Failed to insert upgraded blob into the database.",
-                    ))
-                })?;
                 match f(&upgraded_blob) {
                     Ok(v) => Ok((v, Some(upgraded_blob))),
                     Err(e) => Err(e).context(concat!(
@@ -706,10 +835,114 @@
                     )),
                 }
             }
-            Err(e) => {
-                Err(e).context("In upgrade_keyblob_if_required_with: Failed perform operation.")
+            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.")
             }
-            Ok(v) => Ok((v, None)),
+        }
+    }
+
+    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 = &self.keymint;
+        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(&upgraded_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 = &self.keymint;
+        {
+            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")
         }
     }
 }
@@ -723,6 +956,7 @@
         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(
@@ -733,7 +967,13 @@
         flags: i32,
         entropy: &[u8],
     ) -> binder::public_api::Result<KeyMetadata> {
-        map_or_log_err(self.generate_key(key, attestation_key, params, flags, entropy), Ok)
+        // 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,
@@ -743,7 +983,11 @@
         flags: i32,
         key_data: &[u8],
     ) -> binder::public_api::Result<KeyMetadata> {
-        map_or_log_err(self.import_key(key, attestation_key, params, flags, key_data), Ok)
+        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,
@@ -753,9 +997,24 @@
         params: &[KeyParameter],
         authenticators: &[AuthenticatorSpec],
     ) -> binder::public_api::Result<KeyMetadata> {
-        map_or_log_err(
-            self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
-            Ok,
-        )
+        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
index 3a4bf82..b35fe36 100644
--- a/keystore2/src/service.rs
+++ b/keystore2/src/service.rs
@@ -12,20 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// TODO remove when fully implemented.
-#![allow(unused_variables)]
-
 //! 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::error::{self, map_or_log_err, ErrorCode};
+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, Asp,
+    key_parameters_to_authorizations, watchdog as wd,
 };
 use crate::{
     database::Uuid,
@@ -36,41 +33,48 @@
     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 binder::{IBinder, Strong, ThreadState};
 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>,
+    i_sec_level_by_uuid: HashMap<Uuid, Strong<dyn IKeystoreSecurityLevel>>,
     uuid_by_sec_level: HashMap<SecurityLevel, Uuid>,
 }
 
 impl KeystoreService {
     /// Create a new instance of the Keystore 2.0 service.
-    pub fn new_native_binder() -> Result<Strong<dyn IKeystoreService>> {
+    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)
-                .context(concat!(
-                    "In KeystoreService::new_native_binder: ",
-                    "Trying to construct mandatory security level TEE."
-                ))
-                .map(|(dev, uuid)| (Asp::new(dev.as_binder()), uuid))?;
+        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."
+        ))?;
         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)
-            .map(|(dev, uuid)| (Asp::new(dev.as_binder()), uuid))
+        if let Ok((dev, uuid)) =
+            KeystoreSecurityLevel::new_native_binder(SecurityLevel::STRONGBOX, id_rotation_state)
         {
             result.i_sec_level_by_uuid.insert(uuid, dev);
             result.uuid_by_sec_level.insert(SecurityLevel::STRONGBOX, uuid);
@@ -85,9 +89,10 @@
                 "In KeystoreService::new_native_binder: Trying to initialize the legacy migrator.",
             )?;
 
-        let result = BnKeystoreService::new_binder(result);
-        result.as_binder().set_requesting_sid(true);
-        Ok(result)
+        Ok(BnKeystoreService::new_binder(
+            result,
+            BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
+        ))
     }
 
     fn uuid_to_sec_level(&self, uuid: &Uuid) -> SecurityLevel {
@@ -100,7 +105,7 @@
 
     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.")
+            Ok(dev.clone())
         } else {
             Err(error::Error::sys())
                 .context("In get_i_sec_level_by_uuid: KeyMint instance for key not found.")
@@ -116,7 +121,7 @@
             .get(&sec_level)
             .and_then(|uuid| self.i_sec_level_by_uuid.get(uuid))
         {
-            dev.get_interface().context("In get_security_level.")
+            Ok(dev.clone())
         } else {
             Err(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
                 .context("In get_security_level: No such security level.")
@@ -127,9 +132,9 @@
         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, || {
+                LEGACY_MIGRATOR.with_try_migrate(key, caller_uid, || {
                     db.borrow_mut().load_key_entry(
-                        &key,
+                        key,
                         KeyType::Client,
                         KeyEntryLoadBits::PUBLIC,
                         caller_uid,
@@ -178,9 +183,9 @@
     ) -> Result<()> {
         let caller_uid = ThreadState::get_calling_uid();
         DB.with::<_, Result<()>>(|db| {
-            let entry = match LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+            let entry = match LEGACY_MIGRATOR.with_try_migrate(key, caller_uid, || {
                 db.borrow_mut().load_key_entry(
-                    &key,
+                    key,
                     KeyType::Client,
                     KeyEntryLoadBits::NONE,
                     caller_uid,
@@ -199,7 +204,7 @@
             .context("Failed to load key entry.")?;
 
             let mut db = db.borrow_mut();
-            if let Some((key_id_guard, key_entry)) = entry {
+            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.")?;
 
@@ -234,8 +239,13 @@
             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.")?;
+            db.store_new_certificate(
+                &key,
+                KeyType::Client,
+                certificate_chain.unwrap(),
+                &KEYSTORE_UUID,
+            )
+            .context("Failed to insert new certificate.")?;
             Ok(())
         })
         .context("In update_subcomponent.")
@@ -284,7 +294,7 @@
             &mut DB
                 .with(|db| {
                     let mut db = db.borrow_mut();
-                    db.list(k.domain, k.nspace)
+                    db.list(k.domain, k.nspace, KeyType::Client)
                 })
                 .context("In list_entries: Trying to list keystore database.")?,
         );
@@ -297,8 +307,8 @@
     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| {
+            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.")
                 })
             })
@@ -315,9 +325,9 @@
     ) -> Result<KeyDescriptor> {
         let caller_uid = ThreadState::get_calling_uid();
         DB.with(|db| {
-            LEGACY_MIGRATOR.with_try_migrate(&key, caller_uid, || {
+            LEGACY_MIGRATOR.with_try_migrate(key, caller_uid, || {
                 db.borrow_mut().grant(
-                    &key,
+                    key,
                     caller_uid,
                     grantee_uid as u32,
                     access_vector,
@@ -330,7 +340,7 @@
 
     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| {
+            db.borrow_mut().ungrant(key, ThreadState::get_calling_uid(), grantee_uid as u32, |k| {
                 check_key_permission(KeyPerm::grant(), k, &None)
             })
         })
@@ -347,9 +357,13 @@
         &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(
@@ -358,6 +372,7 @@
         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(
@@ -365,10 +380,14 @@
         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<()> {
-        map_or_log_err(self.delete_key(key), Ok)
+        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,
@@ -376,9 +395,11 @@
         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..1862f73
--- /dev/null
+++ b/keystore2/src/shared_secret_negotiation.rs
@@ -0,0 +1,280 @@
+// 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::Result;
+use keystore2_vintf::{get_aidl_instances, get_hidl_instances};
+use std::fmt::{self, Display, Formatter};
+use std::time::Duration;
+
+/// 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>> {
+    // 4.1 implementation always also register as 4.0. So only the highest version of each
+    // "default" and "strongbox" makes the cut.
+    let mut legacy_default_found: bool = false;
+    let mut legacy_strongbox_found: bool = false;
+    Ok([(4, 1), (4, 0)]
+        .iter()
+        .map(|(ma, mi)| {
+            get_hidl_instances(KEYMASTER_PACKAGE_NAME, *ma, *mi, KEYMASTER_INTERFACE_NAME)
+                .into_iter()
+                .filter_map(|name| {
+                    filter_map_legacy_km_instances(name, (*ma, *mi)).and_then(|sp| {
+                        if let SharedSecretParticipant::Hidl { is_strongbox: true, .. } = &sp {
+                            if !legacy_strongbox_found {
+                                legacy_strongbox_found = true;
+                                return Some(sp);
+                            }
+                        } else if !legacy_default_found {
+                            legacy_default_found = true;
+                            return Some(sp);
+                        }
+                        None
+                    })
+                })
+                .collect::<Vec<SharedSecretParticipant>>()
+        })
+        .into_iter()
+        .flatten()
+        .chain({
+            get_aidl_instances(SHARED_SECRET_PACKAGE_NAME, 1, SHARED_SECRET_INTERFACE_NAME)
+                .into_iter()
+                .map(SharedSecretParticipant::Aidl)
+                .collect::<Vec<_>>()
+                .into_iter()
+        })
+        .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(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(Duration::from_millis(1000));
+            }
+            Ok(params) => break params,
+        }
+    };
+
+    params.sort_unstable();
+
+    // Phase 2: Send the sorted sharing parameters to all participants.
+    let negotiation_result = 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 }),
+        }
+    });
+
+    if let Err(e) = negotiation_result {
+        log::error!("In negotiate_shared_secret: {:?}.", e);
+        if let SharedSecretError::Checksum(_) = e {
+            log::error!(concat!(
+                "This means that this device is NOT PROVISIONED CORRECTLY.\n",
+                "User authorization and other security functions will not work\n",
+                "as expected. Please contact your OEM for instructions.",
+            ));
+        }
+    }
+}
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
index 5ee685a..a1e4c48 100644
--- a/keystore2/src/super_key.rs
+++ b/keystore2/src/super_key.rs
@@ -12,29 +12,228 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#![allow(dead_code)]
-
 use crate::{
-    database::BlobMetaData, database::BlobMetaEntry, database::EncryptedBy, database::KeyEntry,
-    database::KeyType, database::KeystoreDB, enforcements::Enforcements, error::Error,
-    error::ResponseCode, key_parameter::KeyParameter, legacy_blob::LegacyBlobLoader,
+    boot_level_keys::{get_level_zero_key, BootLevelKeyCache},
+    database::BlobMetaData,
+    database::BlobMetaEntry,
+    database::EncryptedBy,
+    database::KeyEntry,
+    database::KeyType,
+    database::{KeyEntryLoadBits, 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,
+    utils::AID_KEYSTORE,
 };
-use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
+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, derive_key_from_password, generate_aes256_key, generate_salt,
-    ZVec, AES_256_KEY_LENGTH,
+    aes_gcm_decrypt, aes_gcm_encrypt, generate_aes256_key, generate_salt, Password, ZVec,
+    AES_256_KEY_LENGTH,
 };
-use std::ops::Deref;
+use rustutils::system_properties::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-521
+    EcdhP521,
+}
+
+/// 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_P521_KEY: SuperKeyType = SuperKeyType {
+    alias: "USER_SCREEN_LOCK_BOUND_P521_KEY",
+    algorithm: SuperEncryptionAlgorithm::EcdhP521,
+};
+
+/// 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 {
+            metadata.max_boot_level().map(|boot_level| SuperKeyIdentifier::BootLevel(*boot_level))
+        }
+    }
+
+    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_blob = key_entry
+            .key_blob_info()
+            .as_ref()
+            .map(|(key_blob, _)| KeyBlob::Ref(key_blob))
+            .ok_or(Error::Rc(ResponseCode::KEY_NOT_FOUND))
+            .context("In LockedKey::decrypt: Missing key blob info.")?;
+        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_blob,
+            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
@@ -42,34 +241,36 @@
     /// 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<SuperKey>,
+    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.
-    /// TODO the life cycle is not fully implemented at this time.
-    screen_lock: Option<Arc<ZVec>>,
-}
-
-#[derive(Default, Clone)]
-pub struct SuperKey {
-    key: Arc<ZVec>,
-    // id of the super key in the database.
-    id: i64,
-}
-
-impl SuperKey {
-    pub fn get_key(&self) -> &Arc<ZVec> {
-        &self.key
-    }
-
-    pub fn get_id(&self) -> i64 {
-        self.id
-    }
+    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<ZVec>>,
+    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)]
@@ -78,22 +279,66 @@
 }
 
 impl SuperKeyManager {
-    pub fn new() -> Self {
-        Self { data: Mutex::new(Default::default()) }
+    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(())
     }
 
-    pub fn forget_screen_lock_key_for_user(&self, user: UserId) {
-        let mut data = self.data.lock().unwrap();
-        if let Some(usk) = data.user_keys.get_mut(&user) {
-            usk.screen_lock = None;
+    /// 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 forget_screen_lock_keys(&self) {
-        let mut data = self.data.lock().unwrap();
-        for (_, usk) in data.user_keys.iter_mut() {
-            usk.screen_lock = None;
-        }
+    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) {
@@ -101,25 +346,39 @@
         data.user_keys.remove(&user);
     }
 
-    pub fn forget_all_keys(&self) {
+    fn install_per_boot_key_for_user(&self, user: UserId, super_key: Arc<SuperKey>) -> Result<()> {
         let mut data = self.data.lock().unwrap();
-        data.user_keys.clear();
-        data.key_index.clear();
-    }
-
-    fn install_per_boot_key_for_user(&self, user: UserId, super_key: SuperKey) {
-        let mut data = self.data.lock().unwrap();
-        data.key_index.insert(super_key.id, Arc::downgrade(&(super_key.key)));
+        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 get_key(&self, key_id: &i64) -> Option<Arc<ZVec>> {
-        self.data.lock().unwrap().key_index.get(key_id).and_then(|k| k.upgrade())
+    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: u32) -> Option<SuperKey> {
+    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).map(|e| e.per_boot.clone()).flatten()
+        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.
@@ -130,14 +389,14 @@
         &self,
         db: &mut KeystoreDB,
         user: UserId,
-        pw: &[u8],
+        pw: &Password,
         legacy_blob_loader: &LegacyBlobLoader,
     ) -> Result<()> {
         let (_, entry) = db
             .get_or_create_key_with(
                 Domain::APP,
                 user as u64 as i64,
-                KeystoreDB::USER_SUPER_KEY_ALIAS,
+                USER_SUPER_KEY.alias,
                 crate::database::KEYSTORE_UUID,
                 || {
                     // For backward compatibility we need to check if there is a super key present.
@@ -162,42 +421,74 @@
             )
             .context("In unlock_user_key: Failed to get key id.")?;
 
-        self.populate_cache_from_super_key_blob(user, entry, pw).context("In unlock_user_key.")?;
+        self.populate_cache_from_super_key_blob(user, USER_SUPER_KEY.algorithm, entry, pw)
+            .context("In unlock_user_key.")?;
         Ok(())
     }
 
-    /// Unwraps an encrypted key blob given metadata identifying the encryption key.
-    /// The function queries `metadata.encrypted_by()` to determine the encryption key.
-    /// It then check if the required key is memory resident, and if so decrypts the
-    /// blob.
-    pub fn unwrap_key<'a>(&self, blob: &'a [u8], metadata: &BlobMetaData) -> Result<KeyBlob<'a>> {
-        match metadata.encrypted_by() {
-            Some(EncryptedBy::KeyId(key_id)) => match self.get_key(key_id) {
-                Some(key) => Ok(KeyBlob::Sensitive(
-                    Self::unwrap_key_with_key(blob, metadata, &key).context("In unwrap_key.")?,
-                    SuperKey { key: key.clone(), id: *key_id },
-                )),
-                None => Err(Error::Rc(ResponseCode::LOCKED))
-                    .context("In unwrap_key: Key is not usable until the user entered their LSKF."),
-            },
-            _ => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
-                .context("In unwrap_key: Cannot determined wrapping key."),
-        }
+    /// 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: &[u8]) -> Result<ZVec> {
-        match (metadata.iv(), metadata.aead_tag()) {
-            (Some(iv), Some(tag)) => aes_gcm_decrypt(blob, iv, tag, key)
-                .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(),
-            )),
+    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::EcdhP521 => {
+                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(),
+                        ))
+                    }
+                }
+            }
         }
     }
 
@@ -205,15 +496,10 @@
     pub fn super_key_exists_in_db_for_user(
         db: &mut KeystoreDB,
         legacy_migrator: &LegacyMigrator,
-        user_id: u32,
+        user_id: UserId,
     ) -> Result<bool> {
         let key_in_db = db
-            .key_exists(
-                Domain::APP,
-                user_id as u64 as i64,
-                KeystoreDB::USER_SUPER_KEY_ALIAS,
-                KeyType::Super,
-            )
+            .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 {
@@ -232,17 +518,18 @@
         &self,
         db: &mut KeystoreDB,
         legacy_migrator: &LegacyMigrator,
-        user_id: u32,
-        pw: &[u8],
+        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(user_id))
+            .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, entry, pw)
+                    .populate_cache_from_super_key_blob(user_id, alias.algorithm, entry, pw)
                     .context("In check_and_unlock_super_key.")?;
                 Ok(UserState::LskfUnlocked(super_key))
             }
@@ -260,8 +547,8 @@
         &self,
         db: &mut KeystoreDB,
         legacy_migrator: &LegacyMigrator,
-        user_id: u32,
-        pw: Option<&[u8]>,
+        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(
@@ -279,11 +566,22 @@
                 .context("In check_and_initialize_super_key.")?;
 
             let key_entry = db
-                .store_super_key(user_id, &(&encrypted_super_key, &blob_metadata))
+                .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, key_entry, pw)
+                .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 {
@@ -294,19 +592,26 @@
     //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: u32,
+        user_id: UserId,
+        algorithm: SuperEncryptionAlgorithm,
         entry: KeyEntry,
-        pw: &[u8],
-    ) -> Result<SuperKey> {
-        let super_key = Self::extract_super_key_from_key_entry(entry, pw).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());
+        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(entry: KeyEntry, pw: &[u8]) -> Result<SuperKey> {
+    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(),
@@ -315,9 +620,10 @@
                 metadata.aead_tag(),
             ) {
                 (Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag)) => {
-                    let key = derive_key_from_password(pw, Some(salt), AES_256_KEY_LENGTH).context(
-                    "In extract_super_key_from_key_entry: Failed to generate key from password.",
-                )?;
+                    // 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.",
@@ -327,16 +633,21 @@
                     return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
                         concat!(
                         "In extract_super_key_from_key_entry: Super key has incomplete metadata.",
-                        "Present: encrypted_by: {}, salt: {}, iv: {}, aead_tag: {}."
+                        "encrypted_by: {:?}; Present: salt: {}, iv: {}, aead_tag: {}."
                     ),
-                        enc_by.is_some(),
+                        enc_by,
                         salt.is_some(),
                         iv.is_some(),
                         tag.is_some()
                     ));
                 }
             };
-            Ok(SuperKey { key: Arc::new(key), id: entry.id() })
+            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.")
@@ -344,9 +655,13 @@
     }
 
     /// 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: &[u8]) -> Result<(Vec<u8>, BlobMetaData)> {
+    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 = derive_key_from_password(pw, Some(&salt), AES_256_KEY_LENGTH)
+        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));
@@ -366,14 +681,14 @@
         &self,
         db: &mut KeystoreDB,
         legacy_migrator: &LegacyMigrator,
-        user_id: u32,
+        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_super_key(key_blob, &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 => {
@@ -387,22 +702,26 @@
     //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_super_key(
+    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_super_key: Failed to encrypt new super key.")?;
+            .context("In encrypt_with_aes_super_key: Failed to encrypt new super key.")?;
         metadata.add(BlobMetaEntry::Iv(iv));
         metadata.add(BlobMetaEntry::AeadTag(tag));
-        metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(super_key.id)));
+        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::clippy::too_many_arguments)]
+    #[allow(clippy::too_many_arguments)]
     pub fn handle_super_encryption_on_key_init(
         &self,
         db: &mut KeystoreDB,
@@ -410,63 +729,331 @@
         domain: &Domain,
         key_parameters: &[KeyParameter],
         flags: Option<i32>,
-        user_id: u32,
+        user_id: UserId,
         key_blob: &[u8],
     ) -> Result<(Vec<u8>, BlobMetaData)> {
-        match (*domain, Enforcements::super_encryption_required(key_parameters, flags)) {
-            (Domain::APP, true) => {
-                self.super_encrypt_on_key_init(db, legacy_migrator, user_id, &key_blob).context(
-                    "In handle_super_encryption_on_key_init.
-                         Failed to super encrypt the key.",
-                )
+        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_P521_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))
+                }
             }
-            _ => Ok((key_blob.to_vec(), BlobMetaData::new())),
-        }
-    }
-
-    /// 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,
-        key_blob: &'a [u8],
-    ) -> Result<KeyBlob<'a>> {
-        if Self::key_super_encrypted(&metadata) {
-            let unwrapped_key = self
-                .unwrap_key(key_blob, metadata)
-                .context("In unwrap_key_if_required. Error in unwrapping the key.")?;
-            Ok(unwrapped_key)
-        } else {
-            Ok(KeyBlob::Ref(key_blob))
+            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_on_upgrade_if_required<'a>(
+    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(_, super_key) => {
-                let (key, metadata) = Self::encrypt_with_super_key(key_after_upgrade, super_key)
-                    .context(concat!(
-                        "In reencrypt_on_upgrade_if_required. ",
-                        "Failed to re-super-encrypt key on key 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)),
         }
     }
 
-    // Helper function to decide if a key is super encrypted, given metadata.
-    fn key_super_encrypted(metadata: &BlobMetaData) -> bool {
-        if let Some(&EncryptedBy::KeyId(_)) = metadata.encrypted_by() {
-            return true;
+    /// 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::EcdhP521 => {
+                    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,
+            }))
         }
-        false
+    }
+
+    /// 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_P521_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,
+                        KeyType::Client, /* TODO Should be Super b/189470584 */
+                        |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) = db
+                .load_key_entry(
+                    &biometric.key_desc,
+                    KeyType::Client, // This should not be a Client key.
+                    KeyEntryLoadBits::KM,
+                    AID_KEYSTORE,
+                    |_, _| Ok(()),
+                )
+                .context("In try_unlock_user_with_biometric: load_key_entry failed")?;
+            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(())
     }
 }
 
@@ -475,7 +1062,7 @@
 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(SuperKey),
+    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.
@@ -490,7 +1077,7 @@
         db: &mut KeystoreDB,
         legacy_migrator: &LegacyMigrator,
         skm: &SuperKeyManager,
-        user_id: u32,
+        user_id: UserId,
     ) -> Result<UserState> {
         match skm.get_per_boot_key_by_user_id(user_id) {
             Some(super_key) => Ok(UserState::LskfUnlocked(super_key)),
@@ -513,8 +1100,8 @@
         db: &mut KeystoreDB,
         legacy_migrator: &LegacyMigrator,
         skm: &SuperKeyManager,
-        user_id: u32,
-        password: Option<&[u8]>,
+        user_id: UserId,
+        password: Option<&Password>,
     ) -> Result<UserState> {
         match skm.get_per_boot_key_by_user_id(user_id) {
             Some(super_key) => {
@@ -547,8 +1134,8 @@
         db: &mut KeystoreDB,
         legacy_migrator: &LegacyMigrator,
         skm: &SuperKeyManager,
-        user_id: u32,
-        password: &[u8],
+        user_id: UserId,
+        password: &Password,
     ) -> Result<UserState> {
         match skm.get_per_boot_key_by_user_id(user_id) {
             Some(super_key) => {
@@ -573,18 +1160,18 @@
         db: &mut KeystoreDB,
         skm: &SuperKeyManager,
         legacy_migrator: &LegacyMigrator,
-        user_id: u32,
+        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 as u32, keep_non_super_encrypted_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 as u32);
+        skm.forget_all_keys_for_user(user_id);
         Ok(())
     }
 }
@@ -595,19 +1182,39 @@
 /// `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(ZVec, SuperKey),
+    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::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/user_manager.rs b/keystore2/src/user_manager.rs
deleted file mode 100644
index 3c393c5..0000000
--- a/keystore2/src/user_manager.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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 IKeystoreUserManager AIDL interface.
-
-use crate::error::map_or_log_err;
-use crate::error::Error as KeystoreError;
-use crate::globals::{DB, LEGACY_MIGRATOR, SUPER_KEY};
-use crate::permission::KeystorePerm;
-use crate::super_key::UserState;
-use crate::utils::check_keystore_permission;
-use android_security_usermanager::aidl::android::security::usermanager::IKeystoreUserManager::{
-    BnKeystoreUserManager, IKeystoreUserManager,
-};
-use android_security_usermanager::binder::{Interface, Result as BinderResult};
-use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
-use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
-use anyhow::{Context, Result};
-use binder::{IBinder, Strong};
-
-/// This struct is defined to implement the aforementioned AIDL interface.
-/// As of now, it is an empty struct.
-pub struct UserManager;
-
-impl UserManager {
-    /// Create a new instance of Keystore User Manager service.
-    pub fn new_native_binder() -> Result<Strong<dyn IKeystoreUserManager>> {
-        let result = BnKeystoreUserManager::new_binder(Self);
-        result.as_binder().set_requesting_sid(true);
-        Ok(result)
-    }
-
-    fn on_user_password_changed(user_id: i32, password: Option<&[u8]>) -> 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.")?;
-
-        match DB
-            .with(|db| {
-                UserState::get_with_password_changed(
-                    &mut db.borrow_mut(),
-                    &LEGACY_MIGRATOR,
-                    &SUPER_KEY,
-                    user_id as u32,
-                    password,
-                )
-            })
-            .context("In on_user_password_changed.")?
-        {
-            UserState::LskfLocked => {
-                // Error - password can not be changed when the device is locked
-                Err(KeystoreError::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.")
-    }
-}
-
-impl Interface for UserManager {}
-
-impl IKeystoreUserManager for UserManager {
-    fn onUserPasswordChanged(&self, user_id: i32, password: Option<&[u8]>) -> BinderResult<()> {
-        map_or_log_err(Self::on_user_password_changed(user_id, password), Ok)
-    }
-
-    fn onUserAdded(&self, user_id: i32) -> BinderResult<()> {
-        map_or_log_err(Self::add_or_remove_user(user_id), Ok)
-    }
-
-    fn onUserRemoved(&self, user_id: i32) -> BinderResult<()> {
-        map_or_log_err(Self::add_or_remove_user(user_id), Ok)
-    }
-
-    fn clearNamespace(&self, domain: Domain, nspace: i64) -> BinderResult<()> {
-        map_or_log_err(Self::clear_namespace(domain, nspace), Ok)
-    }
-}
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
index 8e161b7..f6d92ee 100644
--- a/keystore2/src/utils.rs
+++ b/keystore2/src/utils.rs
@@ -15,12 +15,13 @@
 //! This module implements utility functions used by the Keystore 2.0 service
 //! implementation.
 
-use crate::error::Error;
+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,
+    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,
@@ -28,15 +29,13 @@
 use android_system_keystore2::aidl::android::system::keystore2::{
     Authorization::Authorization, KeyDescriptor::KeyDescriptor,
 };
-use anyhow::{anyhow, Context};
-use binder::{FromIBinder, SpIBinder, ThreadState};
+use anyhow::Context;
+use binder::{Strong, 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
@@ -44,7 +43,7 @@
 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(
+            calling_sid.ok_or_else(Error::sys).context(
                 "In check_keystore_permission: Cannot check permission without calling_sid.",
             )?,
             perm,
@@ -58,7 +57,7 @@
 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(
+            calling_sid.ok_or_else(Error::sys).context(
                 "In check_grant_permission: Cannot check permission without calling_sid.",
             )?,
             access_vec,
@@ -78,7 +77,7 @@
     ThreadState::with_calling_sid(|calling_sid| {
         permission::check_key_permission(
             ThreadState::get_calling_uid(),
-            &calling_sid
+            calling_sid
                 .ok_or_else(Error::sys)
                 .context("In check_key_permission: Cannot check permission without calling_sid.")?,
             perm,
@@ -88,36 +87,43 @@
     })
 }
 
-/// 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)))
-    }
+/// 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
+    )
 }
 
-impl Clone for Asp {
-    fn clone(&self) -> Self {
-        let lock = self.0.lock().unwrap();
-        Self(Mutex::new((*lock).clone()))
+/// 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: 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"
+        )),
     }
 }
 
@@ -145,19 +151,15 @@
     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 {
+/// This returns the current time (in milliseconds) 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_milliseconds() -> 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()
+    current_time.tv_sec as i64 * 1000 + (current_time.tv_nsec as i64 / 1_000_000)
 }
 
 /// Converts a response code as returned by the Android Protected Confirmation HIDL compatibility
@@ -186,10 +188,80 @@
 }
 
 /// AID offset for uid space partitioning.
-/// TODO: Replace with bindgen generated from libcutils. b/175619259
-pub const AID_USER_OFFSET: u32 = 100000;
+pub const AID_USER_OFFSET: u32 = rustutils::users::AID_USER_OFFSET;
+
+/// AID of the keystore process itself, used for keys that
+/// keystore generates for its own use.
+pub const AID_KEYSTORE: u32 = rustutils::users::AID_KEYSTORE;
 
 /// Extracts the android user from the given uid.
 pub fn uid_to_android_user(uid: u32) -> u32 {
-    uid / AID_USER_OFFSET
+    rustutils::users::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..34719aa
--- /dev/null
+++ b/keystore2/src/vintf/Android.bp
@@ -0,0 +1,73 @@
+// 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: [
+        "libcxx",
+    ],
+    shared_libs: [
+        "libvintf",
+    ],
+    static_libs: [
+        "libkeystore2_vintf_cpp",
+    ],
+}
+
+cc_library_static {
+    name: "libkeystore2_vintf_cpp",
+    srcs: ["vintf.cpp"],
+    generated_headers: ["cxx-bridge-header"],
+    generated_sources: ["vintf_bridge_code"],
+    shared_libs: [
+        "libvintf",
+    ],
+}
+
+genrule {
+    name: "vintf_bridge_code",
+    tools: ["cxxbridge"],
+    cmd: "$(location cxxbridge) $(in) >> $(out)",
+    srcs: ["lib.rs"],
+    out: ["vintf_cxx_generated.cc"],
+}
+
+rust_test {
+    name: "keystore2_vintf_test",
+    crate_name: "keystore2_vintf_test",
+    srcs: ["lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    rustlibs: [
+        "libcxx",
+    ],
+    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..89e18eb
--- /dev/null
+++ b/keystore2/src/vintf/lib.rs
@@ -0,0 +1,62 @@
+// 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.
+
+#[cxx::bridge]
+mod ffi {
+    unsafe extern "C++" {
+        include!("vintf.hpp");
+
+        /// Gets all HAL names.
+        /// Note that this is not a zero-cost shim: it will make copies of the strings.
+        fn get_hal_names() -> Vec<String>;
+
+        /// Gets all HAL names and versions.
+        /// Note that this is not a zero-cost shim: it will make copies of the strings.
+        fn get_hal_names_and_versions() -> Vec<String>;
+
+        /// 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.
+        fn get_hidl_instances(
+            package: &str,
+            major_version: usize,
+            minor_version: usize,
+            interface_name: &str,
+        ) -> Vec<String>;
+
+        /// 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.
+        fn get_aidl_instances(package: &str, version: usize, interface_name: &str) -> Vec<String>;
+    }
+}
+
+pub use ffi::*;
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+
+    #[test]
+    fn test() {
+        let names = get_hal_names();
+        assert_ne!(names.len(), 0);
+
+        let names_and_versions = get_hal_names_and_versions();
+        assert_ne!(names_and_versions.len(), 0);
+
+        assert!(names_and_versions.len() >= names.len());
+    }
+}
diff --git a/keystore2/src/vintf/vintf.cpp b/keystore2/src/vintf/vintf.cpp
new file mode 100644
index 0000000..00625bf
--- /dev/null
+++ b/keystore2/src/vintf/vintf.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 <algorithm>
+#include <vintf/HalManifest.h>
+#include <vintf/VintfObject.h>
+
+#include "rust/cxx.h"
+
+rust::Vec<rust::String> convert(const std::set<std::string>& names) {
+    rust::Vec<rust::String> result;
+    std::copy(names.begin(), names.end(), std::back_inserter(result));
+    return result;
+}
+
+rust::Vec<rust::String> get_hal_names() {
+    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getHalNames();
+    return convert(names);
+}
+
+rust::Vec<rust::String> get_hal_names_and_versions() {
+    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getHalNamesAndVersions();
+    return convert(names);
+}
+
+rust::Vec<rust::String> get_hidl_instances(rust::Str package, size_t major_version,
+                                           size_t minor_version, rust::Str interfaceName) {
+    android::vintf::Version version(major_version, minor_version);
+    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getHidlInstances(static_cast<std::string>(package), version,
+                                                  static_cast<std::string>(interfaceName));
+    return convert(names);
+}
+
+rust::Vec<rust::String> get_aidl_instances(rust::Str package, size_t version,
+                                           rust::Str interfaceName) {
+    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getAidlInstances(static_cast<std::string>(package), version,
+                                                  static_cast<std::string>(interfaceName));
+    return convert(names);
+}
diff --git a/keystore2/src/vintf/vintf.hpp b/keystore2/src/vintf/vintf.hpp
new file mode 100644
index 0000000..dbc88f0
--- /dev/null
+++ b/keystore2/src/vintf/vintf.hpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "rust/cxx.h"
+
+rust::Vec<rust::String> get_hal_names();
+rust::Vec<rust::String> get_hal_names_and_versions();
+rust::Vec<rust::String> get_hidl_instances(rust::Str package, size_t major_version,
+                                           size_t minor_version, rust::Str interfaceName);
+rust::Vec<rust::String> get_aidl_instances(rust::Str package, size_t version,
+                                           rust::Str interfaceName);
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/ondevice-signing/Android.bp b/ondevice-signing/Android.bp
index 5db19b7..efa0389 100644
--- a/ondevice-signing/Android.bp
+++ b/ondevice-signing/Android.bp
@@ -11,8 +11,6 @@
 // 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
@@ -23,10 +21,11 @@
     default_applicable_licenses: ["system_security_license"],
 }
 
+// List of clang-tidy checks that are reported as errors.
+// Please keep this list ordered lexicographically.
 tidy_errors = [
   "cert-err34-c",
   "google-default-arguments",
-  "google-explicit-constructor",
   "google-runtime-int",
   "google-runtime-member-string-references",
   "misc-move-const-arg",
@@ -85,27 +84,29 @@
   srcs: [
     "odsign_main.cpp",
     "CertUtils.cpp",
-    "Keymaster.cpp",
-    "KeymasterSigningKey.cpp",
+    "KeystoreKey.cpp",
+    "KeystoreHmacKey.cpp",
     "VerityUtils.cpp",
   ],
 
+  header_libs: ["odrefresh_headers"],
+
   static_libs: [
-    "libmini_keyctl_static", // TODO need static?
     "libc++fs",
+    "lib_odsign_proto",
+    "lib_compos_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-lite",
     "libutils",
   ],
 }
diff --git a/ondevice-signing/CertUtils.cpp b/ondevice-signing/CertUtils.cpp
index 6b24391..d67bea6 100644
--- a/ondevice-signing/CertUtils.cpp
+++ b/ondevice-signing/CertUtils.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "CertUtils.h"
+
 #include <android-base/logging.h>
 #include <android-base/result.h>
 
@@ -21,103 +23,285 @@
 #include <openssl/crypto.h>
 #include <openssl/pkcs7.h>
 #include <openssl/rsa.h>
+#include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
-#include <fcntl.h>
+#include <optional>
 #include <vector>
-const char kBasicConstraints[] = "CA:TRUE";
-const char kKeyUsage[] = "critical,keyCertSign,cRLSign,digitalSignature";
-const char kSubjectKeyIdentifier[] = "hash";
+
+#include "KeyConstants.h"
+
+// Common properties for all of our certificates.
 constexpr int kCertLifetimeSeconds = 10 * 365 * 24 * 60 * 60;
+const char* const kIssuerCountry = "US";
+const char* const kIssuerOrg = "Android";
 
-using android::base::Result;
-// using android::base::ErrnoError;
+using android::base::ErrnoError;
 using android::base::Error;
+using android::base::Result;
 
-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;
+static Result<bssl::UniquePtr<X509>> loadX509(const std::string& path) {
+    X509* rawCert;
+    auto f = fopen(path.c_str(), "re");
+    if (f == nullptr) {
+        return Error() << "Failed to open " << path;
+    }
+    if (!d2i_X509_fp(f, &rawCert)) {
+        fclose(f);
+        return Error() << "Unable to decode x509 cert at " << path;
+    }
+    bssl::UniquePtr<X509> cert(rawCert);
 
-    X509V3_set_ctx_nodb(&context);
+    fclose(f);
+    return cert;
+}
 
-    X509V3_set_ctx(&context, cert, cert, nullptr, nullptr, 0);
-    X509_EXTENSION* ex = X509V3_EXT_nconf_nid(nullptr, &context, nid, mutableValue.data());
+static X509V3_CTX makeContext(X509* issuer, X509* subject) {
+    X509V3_CTX context = {};
+    X509V3_set_ctx(&context, issuer, subject, nullptr, nullptr, 0);
+    return context;
+}
+
+static bool add_ext(X509V3_CTX* context, X509* cert, int nid, const char* value) {
+    bssl::UniquePtr<X509_EXTENSION> ex(X509V3_EXT_nconf_nid(nullptr, context, nid, value));
     if (!ex) {
         return false;
     }
 
-    X509_add_ext(cert, ex, -1);
-    X509_EXTENSION_free(ex);
+    X509_add_ext(cert, ex.get(), -1);
     return true;
 }
 
+static void addNameEntry(X509_NAME* name, const char* field, const char* value) {
+    X509_NAME_add_entry_by_txt(name, field, MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>(value), -1, -1, 0);
+}
+
+static Result<bssl::UniquePtr<RSA>> getRsaFromModulus(const std::vector<uint8_t>& publicKey) {
+    bssl::UniquePtr<BIGNUM> n(BN_new());
+    bssl::UniquePtr<BIGNUM> e(BN_new());
+    bssl::UniquePtr<RSA> rsaPubkey(RSA_new());
+    if (!n || !e || !rsaPubkey || !BN_bin2bn(publicKey.data(), publicKey.size(), n.get()) ||
+        !BN_set_word(e.get(), kRsaKeyExponent) ||
+        !RSA_set0_key(rsaPubkey.get(), n.get(), e.get(), /*d=*/nullptr)) {
+        return Error() << "Failed to create RSA key";
+    }
+    // RSA_set0_key takes ownership of |n| and |e| on success.
+    (void)n.release();
+    (void)e.release();
+
+    return rsaPubkey;
+}
+
+static Result<bssl::UniquePtr<RSA>>
+getRsaFromRsaPublicKey(const std::vector<uint8_t>& rsaPublicKey) {
+    auto derBytes = rsaPublicKey.data();
+    bssl::UniquePtr<RSA> rsaKey(d2i_RSAPublicKey(nullptr, &derBytes, rsaPublicKey.size()));
+    if (rsaKey.get() == nullptr) {
+        return Error() << "Failed to parse RsaPublicKey";
+    }
+    if (derBytes != rsaPublicKey.data() + rsaPublicKey.size()) {
+        return Error() << "Key has unexpected trailing data";
+    }
+
+    return rsaKey;
+}
+
+static Result<bssl::UniquePtr<EVP_PKEY>> modulusToRsaPkey(const std::vector<uint8_t>& publicKey) {
+    // "publicKey" corresponds to the raw public key bytes - need to create
+    // a new RSA key with the correct exponent.
+    auto rsaPubkey = getRsaFromModulus(publicKey);
+    if (!rsaPubkey.ok()) {
+        return rsaPubkey.error();
+    }
+
+    bssl::UniquePtr<EVP_PKEY> public_key(EVP_PKEY_new());
+    if (!EVP_PKEY_assign_RSA(public_key.get(), rsaPubkey->release())) {
+        return Error() << "Failed to assign key";
+    }
+    return public_key;
+}
+
+static Result<bssl::UniquePtr<EVP_PKEY>>
+rsaPublicKeyToRsaPkey(const std::vector<uint8_t>& rsaPublicKey) {
+    // rsaPublicKey contains both modulus and exponent, DER-encoded.
+    auto rsaKey = getRsaFromRsaPublicKey(rsaPublicKey);
+    if (!rsaKey.ok()) {
+        return rsaKey.error();
+    }
+
+    bssl::UniquePtr<EVP_PKEY> public_key(EVP_PKEY_new());
+    if (!EVP_PKEY_assign_RSA(public_key.get(), rsaKey->release())) {
+        return Error() << "Failed to assign key";
+    }
+    return public_key;
+}
+
+Result<void> verifySignature(const std::string& message, const std::string& signature,
+                             const std::vector<uint8_t>& publicKey) {
+    auto rsaKey = getRsaFromModulus(publicKey);
+    if (!rsaKey.ok()) {
+        return rsaKey.error();
+    }
+    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> verifyRsaPublicKeySignature(const std::string& message, const std::string& signature,
+                                         const std::vector<uint8_t>& rsaPublicKey) {
+    auto rsaKey = getRsaFromRsaPublicKey(rsaPublicKey);
+    if (!rsaKey.ok()) {
+        return rsaKey.error();
+    }
+
+    uint8_t hashBuf[SHA256_DIGEST_LENGTH];
+    SHA256(reinterpret_cast<const uint8_t*>(message.data()), message.size(), hashBuf);
+
+    bool success = RSA_verify(NID_sha256, hashBuf, sizeof(hashBuf),
+                              reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
+                              rsaKey->get());
+    if (!success) {
+        return Error() << "Failed to verify signature";
+    }
+    return {};
+}
+
+static Result<void> createCertificate(
+    const CertSubject& subject, EVP_PKEY* publicKey,
+    const std::function<android::base::Result<std::string>(const std::string&)>& signFunction,
+    const std::optional<std::string>& issuerCertPath, const std::string& path) {
+
+    // If an issuer cert is specified, we are signing someone else's key.
+    // Otherwise we are signing our key - a self-signed certificate.
+    bool selfSigned = !issuerCertPath;
+
+    bssl::UniquePtr<X509> x509(X509_new());
+    if (!x509) {
+        return Error() << "Unable to allocate x509 container";
+    }
+    X509_set_version(x509.get(), 2);
+    X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
+    X509_gmtime_adj(X509_get_notAfter(x509.get()), kCertLifetimeSeconds);
+    ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), subject.serialNumber);
+
+    bssl::UniquePtr<X509_ALGOR> algor(X509_ALGOR_new());
+    if (!algor ||
+        !X509_ALGOR_set0(algor.get(), OBJ_nid2obj(NID_sha256WithRSAEncryption), V_ASN1_NULL,
+                         NULL) ||
+        !X509_set1_signature_algo(x509.get(), algor.get())) {
+        return Error() << "Unable to set x509 signature algorithm";
+    }
+
+    if (!X509_set_pubkey(x509.get(), publicKey)) {
+        return Error() << "Unable to set x509 public key";
+    }
+
+    X509_NAME* subjectName = X509_get_subject_name(x509.get());
+    if (!subjectName) {
+        return Error() << "Unable to get x509 subject name";
+    }
+    addNameEntry(subjectName, "C", kIssuerCountry);
+    addNameEntry(subjectName, "O", kIssuerOrg);
+    addNameEntry(subjectName, "CN", subject.commonName);
+
+    if (selfSigned) {
+        if (!X509_set_issuer_name(x509.get(), subjectName)) {
+            return Error() << "Unable to set x509 issuer name";
+        }
+    } else {
+        X509_NAME* issuerName = X509_get_issuer_name(x509.get());
+        if (!issuerName) {
+            return Error() << "Unable to get x509 issuer name";
+        }
+        addNameEntry(issuerName, "C", kIssuerCountry);
+        addNameEntry(issuerName, "O", kIssuerOrg);
+        addNameEntry(issuerName, "CN", kRootSubject.commonName);
+    }
+
+    // Beware: context contains a pointer to issuerCert, so we need to keep it alive.
+    bssl::UniquePtr<X509> issuerCert;
+    X509V3_CTX context;
+
+    if (selfSigned) {
+        context = makeContext(x509.get(), x509.get());
+    } else {
+        auto certStatus = loadX509(*issuerCertPath);
+        if (!certStatus.ok()) {
+            return Error() << "Unable to load issuer cert: " << certStatus.error();
+        }
+        issuerCert = std::move(certStatus.value());
+        context = makeContext(issuerCert.get(), x509.get());
+    }
+
+    // If it's a self-signed cert we use it for signing certs, otherwise only for signing data.
+    const char* basicConstraints = selfSigned ? "CA:TRUE" : "CA:FALSE";
+    const char* keyUsage =
+        selfSigned ? "critical,keyCertSign,cRLSign,digitalSignature" : "critical,digitalSignature";
+
+    add_ext(&context, x509.get(), NID_basic_constraints, basicConstraints);
+    add_ext(&context, x509.get(), NID_key_usage, keyUsage);
+    add_ext(&context, x509.get(), NID_subject_key_identifier, "hash");
+    add_ext(&context, x509.get(), NID_authority_key_identifier, "keyid:always");
+
+    // Get the data to be signed
+    unsigned char* to_be_signed_buf(nullptr);
+    size_t to_be_signed_length = i2d_re_X509_tbs(x509.get(), &to_be_signed_buf);
+
+    auto signed_data = signFunction(
+        std::string(reinterpret_cast<const char*>(to_be_signed_buf), to_be_signed_length));
+    if (!signed_data.ok()) {
+        return signed_data.error();
+    }
+
+    if (!X509_set1_signature_value(x509.get(),
+                                   reinterpret_cast<const uint8_t*>(signed_data->data()),
+                                   signed_data->size())) {
+        return Error() << "Unable to set x509 signature";
+    }
+
+    auto f = fopen(path.c_str(), "wbe");
+    if (f == nullptr) {
+        return ErrnoError() << "Failed to open " << path;
+    }
+    i2d_X509_fp(f, x509.get());
+    if (fclose(f) != 0) {
+        return ErrnoError() << "Failed to close " << path;
+    }
+
+    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);
-
-    auto pubKeyData = publicKey.data();
-    EVP_PKEY* public_key = d2i_PUBKEY(nullptr, &pubKeyData, publicKey.size());
-    if (!X509_set_pubkey(x509.get(), public_key)) {
-        return Error() << "Unable to set x509 public key";
+    auto rsa_pkey = modulusToRsaPkey(publicKey);
+    if (!rsa_pkey.ok()) {
+        return rsa_pkey.error();
     }
 
-    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";
+    return createCertificate(kRootSubject, rsa_pkey.value().get(), signFunction, {}, path);
+}
+
+android::base::Result<void> createLeafCertificate(
+    const CertSubject& subject, const std::vector<uint8_t>& rsaPublicKey,
+    const std::function<android::base::Result<std::string>(const std::string&)>& signFunction,
+    const std::string& issuerCertPath, const std::string& path) {
+    auto rsa_pkey = rsaPublicKeyToRsaPkey(rsaPublicKey);
+    if (!rsa_pkey.ok()) {
+        return rsa_pkey.error();
     }
 
-    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(), "wb");
-    // TODO error checking
-    i2d_X509_fp(f, x509.get());
-    fclose(f);
-
-    return {};
+    return createCertificate(subject, rsa_pkey.value().get(), signFunction, issuerCertPath, path);
 }
 
 Result<std::vector<uint8_t>> extractPublicKey(EVP_PKEY* pkey) {
@@ -125,15 +309,14 @@
         return Error() << "Failed to extract public key from x509 cert";
     }
 
-    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
+    if (EVP_PKEY_id(pkey) != 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);
+    RSA* rsa = EVP_PKEY_get0_RSA(pkey);
+    auto num_bytes = BN_num_bytes(RSA_get0_n(rsa));
     std::vector<uint8_t> pubKey(num_bytes);
-    int res = BN_bn2bin(rsa->n, pubKey.data());
-    RSA_free(rsa);
+    int res = BN_bn2bin(RSA_get0_n(rsa), pubKey.data());
 
     if (!res) {
         return Error() << "Failed to convert public key to bytes";
@@ -142,25 +325,95 @@
     return pubKey;
 }
 
-Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::vector<uint8_t>& keyData) {
+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());
+    bssl::UniquePtr<EVP_PKEY> public_key(d2i_PUBKEY(nullptr, &keyDataBytes, keyData.size()));
 
-    return extractPublicKey(public_key);
+    return extractPublicKey(public_key.get());
+}
+
+Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::vector<uint8_t>& derCert) {
+    auto derCertBytes = derCert.data();
+    bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &derCertBytes, derCert.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(), "r");
-    if (!d2i_X509_fp(f, &cert)) {
-        return Error() << "Unable to decode x509 cert at " << path;
+    auto cert = loadX509(path);
+    if (!cert.ok()) {
+        return cert.error();
     }
-
-    fclose(f);
-    return extractPublicKey(X509_get_pubkey(cert));
+    return extractPublicKey(X509_get_pubkey(cert.value().get()));
 }
 
-Result<std::vector<uint8_t>> createPkcs7(const std::vector<uint8_t>& signed_digest) {
+Result<std::vector<uint8_t>> extractRsaPublicKey(EVP_PKEY* pkey) {
+    RSA* rsa = EVP_PKEY_get0_RSA(pkey);
+    if (rsa == nullptr) {
+        return Error() << "The public key is not an RSA key";
+    }
+
+    uint8_t* out = nullptr;
+    int size = i2d_RSAPublicKey(rsa, &out);
+    if (size < 0 || !out) {
+        return Error() << "Failed to convert to RSAPublicKey";
+    }
+
+    bssl::UniquePtr<uint8_t> buffer(out);
+    std::vector<uint8_t> result(out, out + size);
+    return result;
+}
+
+Result<CertInfo> verifyAndExtractCertInfoFromX509(const std::string& path,
+                                                  const std::vector<uint8_t>& publicKey) {
+    auto public_key = modulusToRsaPkey(publicKey);
+    if (!public_key.ok()) {
+        return public_key.error();
+    }
+
+    auto cert = loadX509(path);
+    if (!cert.ok()) {
+        return cert.error();
+    }
+    X509* x509 = cert.value().get();
+
+    // Make sure we signed it.
+    if (X509_verify(x509, public_key.value().get()) != 1) {
+        return Error() << "Failed to verify certificate.";
+    }
+
+    bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(x509));
+    auto subject_key = extractRsaPublicKey(pkey.get());
+    if (!subject_key.ok()) {
+        return subject_key.error();
+    }
+
+    // The pointers here are all owned by x509, and each function handles an
+    // error return from the previous call correctly.
+    X509_NAME* name = X509_get_subject_name(x509);
+    int index = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
+    X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, index);
+    ASN1_STRING* asn1cn = X509_NAME_ENTRY_get_data(entry);
+    unsigned char* utf8cn;
+    int length = ASN1_STRING_to_UTF8(&utf8cn, asn1cn);
+    if (length < 0) {
+        return Error() << "Failed to read subject CN";
+    }
+
+    bssl::UniquePtr<unsigned char> utf8owner(utf8cn);
+    std::string cn(reinterpret_cast<char*>(utf8cn), static_cast<size_t>(length));
+
+    CertInfo cert_info{std::move(cn), std::move(subject_key.value())};
+    return cert_info;
+}
+
+Result<std::vector<uint8_t>> createPkcs7(const std::vector<uint8_t>& signed_digest,
+                                         const CertSubject& signer) {
     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;
@@ -168,19 +421,20 @@
     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* issuer_name = X509_NAME_new();
+    if (!issuer_name) {
+        return Error() << "Unable to create 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);
+    X509_NAME_add_entry_by_txt(issuer_name, "C", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>(kIssuerCountry), -1, -1, 0);
+    X509_NAME_add_entry_by_txt(issuer_name, "O", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>(kIssuerOrg), -1, -1, 0);
+    X509_NAME_add_entry_by_txt(issuer_name, "CN", MBSTRING_ASC,
+                               reinterpret_cast<const unsigned char*>(kRootSubject.commonName), -1,
+                               -1, 0);
 
-    BN_set_word(serial, 1);
-    name_der_len = i2d_X509_NAME(name, &name_der);
+    BN_set_word(serial, signer.serialNumber);
+    name_der_len = i2d_X509_NAME(issuer_name, &name_der);
     CBB_init(&out, 1024);
 
     if (!CBB_add_asn1(&out, &outer_seq, CBS_ASN1_SEQUENCE) ||
diff --git a/ondevice-signing/CertUtils.h b/ondevice-signing/CertUtils.h
index d9172d0..fe703fa 100644
--- a/ondevice-signing/CertUtils.h
+++ b/ondevice-signing/CertUtils.h
@@ -16,14 +16,57 @@
 
 #pragma once
 
+#include <functional>
+#include <string>
+#include <vector>
+
 #include <android-base/result.h>
 
+// Information extracted from a certificate.
+struct CertInfo {
+    std::string subjectCn;
+    std::vector<uint8_t> subjectRsaPublicKey;
+};
+
+// Subjects of certificates we issue.
+struct CertSubject {
+    const char* commonName;
+    unsigned serialNumber;
+};
+
+// These are all the certificates we ever sign (the first one being our
+// self-signed cert).  We shouldn't really re-use serial numbers for different
+// certificates for the same subject but we do; only one should be in use at a
+// time though.
+inline const CertSubject kRootSubject{"ODS", 1};
+inline const CertSubject kCompOsSubject{"CompOs", 2};
+
 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<void> createLeafCertificate(
+    const CertSubject& subject, const std::vector<uint8_t>& publicKey,
+    const std::function<android::base::Result<std::string>(const std::string&)>& signFunction,
+    const std::string& issuerCertPath, const std::string& outPath);
+
+android::base::Result<std::vector<uint8_t>> createPkcs7(const std::vector<uint8_t>& signedData,
+                                                        const CertSubject& signer);
 
 android::base::Result<std::vector<uint8_t>>
-extractPublicKeyFromX509(const std::vector<uint8_t>& path);
+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<CertInfo>
+verifyAndExtractCertInfoFromX509(const std::string& path, const std::vector<uint8_t>& publicKey);
+
+android::base::Result<void> verifySignature(const std::string& message,
+                                            const std::string& signature,
+                                            const std::vector<uint8_t>& publicKey);
+
+android::base::Result<void> verifyRsaPublicKeySignature(const std::string& message,
+                                                        const std::string& signature,
+                                                        const std::vector<uint8_t>& rsaPublicKey);
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/ondevice-signing/KeyConstants.h
similarity index 70%
copy from keystore/binder/android/security/keymaster/OperationResult.aidl
copy to ondevice-signing/KeyConstants.h
index db689d4..ccc9251 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,8 @@
  * limitations under the License.
  */
 
-package android.security.keymaster;
+static constexpr int kRsaKeySize = 2048;
+static constexpr int kRsaKeyExponent = 65537;
 
-/* @hide */
-parcelable OperationResult cpp_header "keystore/OperationResult.h";
+static constexpr int kHmacKeySize = 256;
+static constexpr int kHmacMinMacLength = 256;
diff --git a/ondevice-signing/Keymaster.cpp b/ondevice-signing/Keymaster.cpp
deleted file mode 100644
index 6cfb565..0000000
--- a/ondevice-signing/Keymaster.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * 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::base::unique_fd;
-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
deleted file mode 100644
index 455289f..0000000
--- a/ondevice-signing/Keymaster.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2b748e4..0000000
--- a/ondevice-signing/KeymasterSigningKey.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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;
-
-KeymasterSigningKey::KeymasterSigningKey() {}
-
-Result<KeymasterSigningKey> KeymasterSigningKey::loadFromBlobAndVerify(const std::string& path) {
-    KeymasterSigningKey signingKey;
-
-    auto status = signingKey.initializeFromKeyblob(path);
-
-    if (!status.ok()) {
-        return status.error();
-    }
-
-    return std::move(signingKey);
-}
-
-Result<KeymasterSigningKey> KeymasterSigningKey::createNewKey() {
-    KeymasterSigningKey signingKey;
-
-    auto status = signingKey.createSigningKey();
-
-    if (!status.ok()) {
-        return status.error();
-    }
-
-    return std::move(signingKey);
-}
-
-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<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<std::vector<uint8_t>> KeymasterSigningKey::getPublicKey() const {
-    auto publicKeyX509 = mKeymaster->extractPublicKey(mVerifiedKeyBlob);
-    if (!publicKeyX509.ok()) {
-        return publicKeyX509.error();
-    }
-    return extractPublicKeyFromX509(publicKeyX509.value());
-}
-
-Result<void> KeymasterSigningKey::createX509Cert(const std::string& outPath) const {
-    auto publicKey = mKeymaster->extractPublicKey(mVerifiedKeyBlob);
-
-    if (!publicKey.ok()) {
-        return publicKey.error();
-    }
-
-    auto keymasterSignFunction = [&](const std::string& to_be_signed) {
-        return this->sign(to_be_signed);
-    };
-    createSelfSignedCertificate(*publicKey, keymasterSignFunction, outPath);
-    return {};
-}
-
-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
deleted file mode 100644
index 7631059..0000000
--- a/ondevice-signing/KeymasterSigningKey.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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"
-
-class KeymasterSigningKey {
-    using KmDevice = ::android::hardware::keymaster::V4_1::IKeymasterDevice;
-
-  public:
-    // Allow the key to be moved around
-    KeymasterSigningKey& operator=(KeymasterSigningKey&& other) = default;
-    KeymasterSigningKey(KeymasterSigningKey&& other) = default;
-
-    static android::base::Result<KeymasterSigningKey>
-    loadFromBlobAndVerify(const std::string& path);
-    static android::base::Result<KeymasterSigningKey> createNewKey();
-
-    /* Sign a message with an initialized signing key */
-    android::base::Result<std::string> sign(const std::string& message) const;
-    android::base::Result<void> saveKeyblob(const std::string& path) const;
-    android::base::Result<std::vector<uint8_t>> getPublicKey() const;
-    android::base::Result<void> createX509Cert(const std::string& path) const;
-
-  private:
-    KeymasterSigningKey();
-
-    android::base::Result<void> createSigningKey();
-    android::base::Result<void> initializeFromKeyblob(const std::string& path);
-
-    std::optional<Keymaster> mKeymaster;
-    std::vector<uint8_t> mVerifiedKeyBlob;
-
-    DISALLOW_COPY_AND_ASSIGN(KeymasterSigningKey);
-};
diff --git a/ondevice-signing/KeystoreHmacKey.cpp b/ondevice-signing/KeystoreHmacKey.cpp
new file mode 100644
index 0000000..09677d7
--- /dev/null
+++ b/ondevice-signing/KeystoreHmacKey.cpp
@@ -0,0 +1,269 @@
+/*
+ * 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 "KeystoreHmacKey.h"
+
+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::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;
+
+using android::base::unique_fd;
+
+// Keystore boot level that the odsign key uses
+static const int kOdsignBootLevel = 30;
+
+static KeyDescriptor getHmacKeyDescriptor() {
+    // 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-hmac");
+        descriptor.nspace = 101;  // odsign_key
+    });
+
+    return descriptor;
+}
+
+Result<void> KeystoreHmacKey::createKey() {
+    std::vector<KeyParameter> params;
+
+    KeyParameter algo;
+    algo.tag = Tag::ALGORITHM;
+    algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::HMAC);
+    params.push_back(algo);
+
+    KeyParameter key_size;
+    key_size.tag = Tag::KEY_SIZE;
+    key_size.value = KeyParameterValue::make<KeyParameterValue::integer>(kHmacKeySize);
+    params.push_back(key_size);
+
+    KeyParameter min_mac_length;
+    min_mac_length.tag = Tag::MIN_MAC_LENGTH;
+    min_mac_length.value = KeyParameterValue::make<KeyParameterValue::integer>(256);
+    params.push_back(min_mac_length);
+
+    KeyParameter digest;
+    digest.tag = Tag::DIGEST;
+    digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
+    params.push_back(digest);
+
+    KeyParameter purposeSign;
+    purposeSign.tag = Tag::PURPOSE;
+    purposeSign.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
+    params.push_back(purposeSign);
+
+    KeyParameter purposeVerify;
+    purposeVerify.tag = Tag::PURPOSE;
+    purposeVerify.value =
+        KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::VERIFY);
+    params.push_back(purposeVerify);
+
+    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(mDescriptor, {}, params, 0, {}, &metadata);
+    if (!status.isOk()) {
+        return Error() << "Failed to create new HMAC key: " << status;
+    }
+
+    return {};
+}
+
+Result<void> KeystoreHmacKey::initialize(sp<IKeystoreService> service,
+                                         sp<IKeystoreSecurityLevel> securityLevel) {
+    mService = std::move(service);
+    mSecurityLevel = std::move(securityLevel);
+
+    // See if we can fetch an existing key
+    KeyEntryResponse keyEntryResponse;
+    LOG(INFO) << "Trying to retrieve existing HMAC key...";
+    auto status = mService->getKeyEntry(mDescriptor, &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 HMAC key without MAX_BOOT_LEVEL tag";
+        }
+    }
+
+    if (!keyValid) {
+        LOG(INFO) << "Existing HMAC key not found or invalid, creating new key";
+        return createKey();
+    } else {
+        return {};
+    }
+}
+
+KeystoreHmacKey::KeystoreHmacKey() {
+    mDescriptor = getHmacKeyDescriptor();
+}
+
+static std::vector<KeyParameter> getVerifyOpParameters() {
+    std::vector<KeyParameter> opParameters;
+
+    KeyParameter algo;
+    algo.tag = Tag::ALGORITHM;
+    algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::HMAC);
+    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 purpose;
+    purpose.tag = Tag::PURPOSE;
+    purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::VERIFY);
+    opParameters.push_back(purpose);
+
+    return opParameters;
+}
+
+static std::vector<KeyParameter> getSignOpParameters() {
+    std::vector<KeyParameter> opParameters;
+
+    KeyParameter algo;
+    algo.tag = Tag::ALGORITHM;
+    algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::HMAC);
+    opParameters.push_back(algo);
+
+    KeyParameter mac_length;
+    mac_length.tag = Tag::MAC_LENGTH;
+    mac_length.value = KeyParameterValue::make<KeyParameterValue::integer>(256);
+    opParameters.push_back(mac_length);
+
+    KeyParameter digest;
+    digest.tag = Tag::DIGEST;
+    digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
+    opParameters.push_back(digest);
+
+    KeyParameter purpose;
+    purpose.tag = Tag::PURPOSE;
+    purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
+    opParameters.push_back(purpose);
+
+    return opParameters;
+}
+
+Result<std::string> KeystoreHmacKey::sign(const std::string& message) const {
+    CreateOperationResponse opResponse;
+    static auto params = getSignOpParameters();
+
+    auto status = mSecurityLevel->createOperation(mDescriptor, params, false, &opResponse);
+    if (!status.isOk()) {
+        return Error() << "Failed to create keystore signing operation: " << status;
+    }
+    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.";
+    }
+
+    return std::string{signature.value().begin(), signature.value().end()};
+}
+
+Result<void> KeystoreHmacKey::verify(const std::string& message,
+                                     const std::string& signature) const {
+    CreateOperationResponse opResponse;
+    static auto params = getVerifyOpParameters();
+
+    auto status = mSecurityLevel->createOperation(mDescriptor, params, false, &opResponse);
+    if (!status.isOk()) {
+        return Error() << "Failed to create keystore verification operation: " << status;
+    }
+    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>> out_signature;
+    std::vector<uint8_t> in_signature{signature.begin(), signature.end()};
+    status = operation->finish({}, in_signature, &out_signature);
+    if (!status.isOk()) {
+        return Error() << "Failed to call keystore finish operation.";
+    }
+
+    return {};
+}
+
+Result<void> KeystoreHmacKey::deleteKey() const {
+    auto status = mService->deleteKey(mDescriptor);
+    if (!status.isOk()) {
+        return Error() << "Failed to delete HMAC key: " << status;
+    }
+
+    return {};
+}
diff --git a/ondevice-signing/KeystoreHmacKey.h b/ondevice-signing/KeystoreHmacKey.h
new file mode 100644
index 0000000..782969a
--- /dev/null
+++ b/ondevice-signing/KeystoreHmacKey.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <optional>
+
+#include <android-base/macros.h>
+#include <android-base/result.h>
+
+#include <utils/StrongPointer.h>
+
+#include <android/system/keystore2/IKeystoreService.h>
+
+class KeystoreHmacKey {
+    using IKeystoreService = ::android::system::keystore2::IKeystoreService;
+    using IKeystoreSecurityLevel = ::android::system::keystore2::IKeystoreSecurityLevel;
+    using KeyDescriptor = ::android::system::keystore2::KeyDescriptor;
+
+  public:
+    KeystoreHmacKey();
+    android::base::Result<void> initialize(android::sp<IKeystoreService> service,
+                                           android::sp<IKeystoreSecurityLevel> securityLevel);
+    android::base::Result<std::string> sign(const std::string& message) const;
+    android::base::Result<void> verify(const std::string& message,
+                                       const std::string& signature) const;
+    android::base::Result<void> deleteKey() const;
+
+  private:
+    android::base::Result<void> createKey();
+    KeyDescriptor mDescriptor;
+    android::sp<IKeystoreService> mService;
+    android::sp<IKeystoreSecurityLevel> mSecurityLevel;
+};
diff --git a/ondevice-signing/KeystoreKey.cpp b/ondevice-signing/KeystoreKey.cpp
new file mode 100644
index 0000000..03bb6d5
--- /dev/null
+++ b/ondevice-signing/KeystoreKey.cpp
@@ -0,0 +1,322 @@
+/*
+ * 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::base::Error;
+using android::base::Result;
+
+// Keystore boot level that the odsign key uses
+static const int kOdsignBootLevel = 30;
+
+const std::string kPublicKeySignature = "/data/misc/odsign/publickey.signature";
+
+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() {
+    mDescriptor = getKeyDescriptor();
+}
+
+Result<std::vector<uint8_t>> KeystoreKey::createKey() {
+    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(mDescriptor, {}, params, 0, {}, &metadata);
+    if (!status.isOk()) {
+        return Error() << "Failed to create new key: " << status;
+    }
+
+    // Extract the public key from the certificate, HMAC it and store the signature
+    auto cert = metadata.certificate;
+    if (!cert) {
+        return Error() << "Key did not have a certificate.";
+    }
+    auto publicKey = extractPublicKeyFromX509(cert.value());
+    if (!publicKey.ok()) {
+        return publicKey.error();
+    }
+    std::string publicKeyString = {publicKey->begin(), publicKey->end()};
+    auto signature = mHmacKey.sign(publicKeyString);
+    if (!signature.ok()) {
+        return Error() << "Failed to sign public key.";
+    }
+
+    if (!android::base::WriteStringToFile(*signature, kPublicKeySignature)) {
+        return Error() << "Can't write public key signature.";
+    }
+
+    return *publicKey;
+}
+
+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::TRUSTED_ENVIRONMENT, &mSecurityLevel);
+    if (!status.isOk()) {
+        return false;
+    }
+
+    // Initialize the HMAC key we use to sign/verify information about this key
+    auto hmacStatus = mHmacKey.initialize(mService, mSecurityLevel);
+    if (!hmacStatus.ok()) {
+        LOG(ERROR) << hmacStatus.error().message();
+        return false;
+    }
+
+    auto key = getOrCreateKey();
+    if (!key.ok()) {
+        // Delete the HMAC, just in case signing failed, and we could recover by recreating it.
+        mHmacKey.deleteKey();
+        LOG(ERROR) << key.error().message();
+        return false;
+    }
+    mPublicKey = *key;
+    LOG(INFO) << "Initialized Keystore key.";
+    return true;
+}
+
+Result<std::vector<uint8_t>> KeystoreKey::verifyExistingKey() {
+    // See if we can fetch an existing key
+    KeyEntryResponse keyEntryResponse;
+    LOG(INFO) << "Trying to retrieve existing keystore key...";
+    auto status = mService->getKeyEntry(mDescriptor, &keyEntryResponse);
+
+    if (!status.isOk()) {
+        return Error() << "Failed to find keystore key...";
+    }
+
+    // On some earlier builds, we created this key on the Strongbox security level;
+    // we now use TEE keys instead (mostly for speed). It shouldn't matter since
+    // verified boot is protected by the TEE anyway. If the key happens to be on
+    // the wrong security level, delete it (this should happen just once).
+    if (keyEntryResponse.metadata.keySecurityLevel != SecurityLevel::TRUSTED_ENVIRONMENT) {
+        return Error() << "Found invalid keystore key with security level: "
+                       << android::hardware::security::keymint::toString(
+                              keyEntryResponse.metadata.keySecurityLevel);
+    }
+
+    // Make sure this is an early boot key
+    bool foundBootLevel = false;
+    for (const auto& auth : keyEntryResponse.metadata.authorizations) {
+        if (auth.keyParameter.tag == Tag::MAX_BOOT_LEVEL) {
+            if (auth.keyParameter.value.get<KeyParameterValue::integer>() == kOdsignBootLevel) {
+                foundBootLevel = true;
+                break;
+            }
+        }
+    }
+    if (!foundBootLevel) {
+        return Error() << "Found invalid keystore key without MAX_BOOT_LEVEL tag";
+    }
+
+    // If the key is still considered valid at this point, extract the public
+    // key from the certificate. Note that we cannot trust this public key,
+    // because it is a part of the keystore2 database, which can be modified by
+    // an attacker.  So instead, when creating the key we HMAC the public key
+    // with a key of the same boot level, and verify the signature here.
+    auto cert = keyEntryResponse.metadata.certificate;
+    if (!cert) {
+        return Error() << "Key did not have a certificate.";
+    }
+    auto publicKey = extractPublicKeyFromX509(cert.value());
+    if (!publicKey.ok()) {
+        return publicKey.error();
+    }
+    std::string publicKeyString = {publicKey->begin(), publicKey->end()};
+
+    std::string signature;
+    if (!android::base::ReadFileToString(kPublicKeySignature, &signature)) {
+        return Error() << "Can't find signature for public key.";
+    }
+
+    auto signatureValid = mHmacKey.verify(publicKeyString, signature);
+    if (!signatureValid.ok()) {
+        return Error() << "Signature of public key did not match.";
+    }
+    LOG(INFO) << "Verified public key signature.";
+
+    return *publicKey;
+}
+
+Result<std::vector<uint8_t>> KeystoreKey::getOrCreateKey() {
+    auto existingKey = verifyExistingKey();
+    if (!existingKey.ok()) {
+        LOG(INFO) << existingKey.error().message();
+        LOG(INFO) << "Existing keystore key not found or invalid, creating new key";
+        return createKey();
+    }
+
+    return *existingKey;
+}
+
+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(mDescriptor, opParameters, false, &opResponse);
+    if (!status.isOk()) {
+        return Error() << "Failed to create keystore signing operation: " << status;
+    }
+    auto operation = opResponse.iOperation;
+
+    std::optional<std::vector<uint8_t>> input{std::in_place, message.begin(), message.end()};
+    std::optional<std::vector<uint8_t>> signature;
+    status = operation->finish(input, {}, &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.";
+    }
+
+    return std::string{signature.value().begin(), signature.value().end()};
+}
+
+Result<std::vector<uint8_t>> KeystoreKey::getPublicKey() const {
+    return mPublicKey;
+}
diff --git a/ondevice-signing/KeystoreKey.h b/ondevice-signing/KeystoreKey.h
new file mode 100644
index 0000000..f2fbb70
--- /dev/null
+++ b/ondevice-signing/KeystoreKey.h
@@ -0,0 +1,56 @@
+/*
+ * 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 <utils/StrongPointer.h>
+
+#include <android/system/keystore2/IKeystoreService.h>
+
+#include "KeystoreHmacKey.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<std::vector<uint8_t>> verifyExistingKey();
+    android::base::Result<std::vector<uint8_t>> createKey();
+    android::base::Result<std::vector<uint8_t>> getOrCreateKey();
+
+    KeyDescriptor mDescriptor;
+    KeystoreHmacKey mHmacKey;
+    android::sp<IKeystoreService> mService;
+    android::sp<IKeystoreSecurityLevel> mSecurityLevel;
+    std::vector<uint8_t> mPublicKey;
+};
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/VerityUtils.cpp b/ondevice-signing/VerityUtils.cpp
index b4a6a54..2beb7eb 100644
--- a/ondevice-signing/VerityUtils.cpp
+++ b/ondevice-signing/VerityUtils.cpp
@@ -15,40 +15,49 @@
  */
 
 #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 <asm/byteorder.h>
 #include <libfsverity.h>
 #include <linux/fsverity.h>
 
 #include "CertUtils.h"
-#include "KeymasterSigningKey.h"
+#include "SigningKey.h"
+#include "compos_signature.pb.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;
 
-#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
+using compos::proto::Signature;
 
-struct fsverity_signed_digest {
-    char magic[8]; /* must be "FSVerity" */
-    __le16 digest_algorithm;
-    __le16 digest_size;
-    __u8 digest[];
-};
+static const char* kFsVerityInitPath = "/system/bin/fsverity_init";
+static const char* kSignatureExtension = ".signature";
+
+static bool isSignatureFile(const std::filesystem::path& path) {
+    return path.extension().native() == kSignatureExtension;
+}
+
+static std::string toHex(std::span<const 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;
@@ -56,11 +65,12 @@
     return 0;
 }
 
-static Result<std::vector<uint8_t>> createDigest(const std::string& path) {
+Result<std::vector<uint8_t>> createDigest(int fd) {
     struct stat filestat;
-    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
-
-    stat(path.c_str(), &filestat);
+    int ret = fstat(fd, &filestat);
+    if (ret < 0) {
+        return ErrnoError() << "Failed to fstat";
+    }
     struct libfsverity_merkle_tree_params params = {
         .version = 1,
         .hash_algorithm = FS_VERITY_HASH_ALG_SHA256,
@@ -69,24 +79,58 @@
     };
 
     struct libfsverity_digest* digest;
-    libfsverity_compute_digest(&fd, &read_callback, &params, &digest);
-
-    return std::vector<uint8_t>(&digest->digest[0], &digest->digest[32]);
+    ret = libfsverity_compute_digest(&fd, &read_callback, &params, &digest);
+    if (ret < 0) {
+        return ErrnoError() << "Failed to compute fs-verity digest";
+    }
+    int expected_digest_size = libfsverity_get_digest_size(FS_VERITY_HASH_ALG_SHA256);
+    if (digest->digest_size != expected_digest_size) {
+        return Error() << "Digest does not have expected size: " << expected_digest_size
+                       << " actual: " << digest->digest_size;
+    }
+    std::vector<uint8_t> digestVector(&digest->digest[0], &digest->digest[expected_digest_size]);
+    free(digest);
+    return digestVector;
 }
 
-static Result<std::vector<uint8_t>> signDigest(const KeymasterSigningKey& key,
+Result<std::vector<uint8_t>> createDigest(const std::string& path) {
+    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+    if (!fd.ok()) {
+        return ErrnoError() << "Unable to open";
+    }
+    return createDigest(fd.get());
+}
+
+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) {
-    fsverity_signed_digest* d;
-    size_t signed_digest_size = sizeof(*d) + digest.size();
-    std::unique_ptr<uint8_t[]> digest_buffer{new uint8_t[signed_digest_size]};
-    d = (fsverity_signed_digest*)digest_buffer.get();
+    auto d = makeUniqueWithTrailingData<fsverity_formatted_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());
+    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, signed_digest_size));
+    auto signed_digest = key.sign(std::string((char*)d.get(), sizeof(*d) + digest.size()));
     if (!signed_digest.ok()) {
         return signed_digest.error();
     }
@@ -94,10 +138,32 @@
     return std::vector<uint8_t>(signed_digest->begin(), signed_digest->end());
 }
 
-Result<void> enableFsVerity(const std::string& path, const KeymasterSigningKey& key) {
-    auto digest = createDigest(path);
+Result<void> enableFsVerity(int fd, std::span<uint8_t> pkcs7) {
+    struct fsverity_enable_arg arg = {.version = 1};
+
+    arg.sig_ptr = reinterpret_cast<uint64_t>(pkcs7.data());
+    arg.sig_size = pkcs7.size();
+    arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;
+    arg.block_size = 4096;
+
+    int ret = ioctl(fd, FS_IOC_ENABLE_VERITY, &arg);
+
+    if (ret != 0) {
+        return ErrnoError() << "Failed to call FS_IOC_ENABLE_VERITY";
+    }
+
+    return {};
+}
+
+Result<std::string> enableFsVerity(const std::string& path, const SigningKey& key) {
+    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+    if (!fd.ok()) {
+        return ErrnoError() << "Failed to open " << path;
+    }
+
+    auto digest = createDigest(fd.get());
     if (!digest.ok()) {
-        return digest.error();
+        return Error() << digest.error() << ": " << path;
     }
 
     auto signed_digest = signDigest(key, digest.value());
@@ -105,62 +171,73 @@
         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;
+    auto pkcs7_data = createPkcs7(signed_digest.value(), kRootSubject);
+    if (!pkcs7_data.ok()) {
+        return pkcs7_data.error();
     }
 
-    return {};
+    auto enabled = enableFsVerity(fd.get(), pkcs7_data.value());
+    if (!enabled.ok()) {
+        return Error() << enabled.error() << ": " << path;
+    }
+
+    // Return the root hash as a hex string
+    return toHex(digest.value());
 }
 
-Result<void> addFilesToVerityRecursive(const std::string& path, const KeymasterSigningKey& key) {
+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) {
+    for (auto end = std::filesystem::recursive_directory_iterator(); it != end; it.increment(ec)) {
         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.message();
     }
 
-    return {};
+    return digests;
 }
 
-Result<bool> isFileInVerity(const std::string& path) {
-    unsigned int flags;
+Result<std::string> isFileInVerity(int fd) {
+    auto d = makeUniqueWithTrailingData<fsverity_digest>(FS_VERITY_MAX_DIGEST_SIZE);
+    d->digest_size = FS_VERITY_MAX_DIGEST_SIZE;
+    auto ret = ioctl(fd, FS_IOC_MEASURE_VERITY, d.get());
+    if (ret < 0) {
+        if (errno == ENODATA) {
+            return Error() << "File is not in fs-verity";
+        } else {
+            return ErrnoError() << "Failed to FS_IOC_MEASURE_VERITY";
+        }
+    }
+    return toHex({&d->digest[0], &d->digest[d->digest_size]});
+}
 
+Result<std::string> isFileInVerity(const std::string& path) {
     unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
-    if (fd < 0) {
+    if (!fd.ok()) {
         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;
+    auto digest = isFileInVerity(fd);
+    if (!digest.ok()) {
+        return Error() << digest.error() << ": " << path;
     }
 
-    return (flags & FS_VERITY_FL);
+    return digest;
 }
 
-Result<void> verifyAllFilesInVerity(const std::string& path) {
+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);
@@ -168,17 +245,180 @@
 
     while (!ec && it != end) {
         if (it->is_regular_file()) {
-            // Verify
+            // Verify the file is in fs-verity
             auto result = isFileInVerity(it->path());
             if (!result.ok()) {
                 return result.error();
             }
-            if (!*result) {
-                return Error() << "File " << it->path() << " not in fs-verity";
-            }
-        }  // TODO reject other types besides dirs?
+            digests[it->path()] = *result;
+        } else if (it->is_directory()) {
+            // These are fine to ignore
+        } else if (it->is_symlink()) {
+            return Error() << "Rejecting artifacts, symlink at " << it->path();
+        } else {
+            return Error() << "Rejecting artifacts, unexpected file type for " << it->path();
+        }
         ++it;
     }
+    if (ec) {
+        return Error() << "Failed to iterate " << path << ": " << ec;
+    }
+
+    return digests;
+}
+
+Result<Signature> readSignature(const std::filesystem::path& signature_path) {
+    unique_fd fd(TEMP_FAILURE_RETRY(open(signature_path.c_str(), O_RDONLY | O_CLOEXEC)));
+    if (fd == -1) {
+        return ErrnoError();
+    }
+    Signature signature;
+    if (!signature.ParseFromFileDescriptor(fd.get())) {
+        return Error() << "Failed to parse";
+    }
+    return signature;
+}
+
+Result<std::map<std::string, std::string>>
+verifyAllFilesUsingCompOs(const std::string& directory_path,
+                          const std::vector<uint8_t>& compos_key) {
+    std::map<std::string, std::string> new_digests;
+    std::vector<std::filesystem::path> signature_files;
+
+    std::error_code ec;
+    auto it = std::filesystem::recursive_directory_iterator(directory_path, ec);
+    for (auto end = std::filesystem::recursive_directory_iterator(); it != end; it.increment(ec)) {
+        auto& path = it->path();
+        if (it->is_regular_file()) {
+            if (isSignatureFile(path)) {
+                continue;
+            }
+
+            unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+            if (!fd.ok()) {
+                return ErrnoError() << "Can't open " << path;
+            }
+
+            auto signature_path = path;
+            signature_path += kSignatureExtension;
+            auto signature = readSignature(signature_path);
+            if (!signature.ok()) {
+                return Error() << "Invalid signature " << signature_path << ": "
+                               << signature.error();
+            }
+            signature_files.push_back(signature_path);
+
+            // Note that these values are not yet trusted.
+            auto& raw_digest = signature->digest();
+            auto& raw_signature = signature->signature();
+
+            // Re-construct the fsverity_formatted_digest that was signed, so we
+            // can verify the signature.
+            std::vector<uint8_t> buffer(sizeof(fsverity_formatted_digest) + raw_digest.size());
+            auto signed_data = new (buffer.data()) fsverity_formatted_digest;
+            memcpy(signed_data->magic, "FSVerity", sizeof signed_data->magic);
+            signed_data->digest_algorithm = __cpu_to_le16(FS_VERITY_HASH_ALG_SHA256);
+            signed_data->digest_size = __cpu_to_le16(raw_digest.size());
+            memcpy(signed_data->digest, raw_digest.data(), raw_digest.size());
+
+            // Make sure the signature matches the CompOs public key, and not some other
+            // fs-verity trusted key.
+            std::string to_verify(reinterpret_cast<char*>(buffer.data()), buffer.size());
+
+            auto verified = verifyRsaPublicKeySignature(to_verify, raw_signature, compos_key);
+            if (!verified.ok()) {
+                return Error() << verified.error() << ": " << path;
+            }
+
+            std::span<const uint8_t> digest_bytes(
+                reinterpret_cast<const uint8_t*>(raw_digest.data()), raw_digest.size());
+            std::string compos_digest = toHex(digest_bytes);
+
+            auto verity_digest = isFileInVerity(fd);
+            if (verity_digest.ok()) {
+                // The file is already in fs-verity. We need to make sure it was signed
+                // by CompOs, so we just check that it has the digest we expect.
+                if (verity_digest.value() != compos_digest) {
+                    return Error() << "fs-verity digest does not match signature file: " << path;
+                }
+            } else {
+                // Not in fs-verity yet. But we have a valid signature of some
+                // digest. If it's not the correct digest for the file then
+                // enabling fs-verity will fail, so we don't need to check it
+                // explicitly ourselves. Otherwise we should be good.
+                std::vector<uint8_t> signature_bytes(raw_signature.begin(), raw_signature.end());
+                auto pkcs7 = createPkcs7(signature_bytes, kCompOsSubject);
+                if (!pkcs7.ok()) {
+                    return Error() << pkcs7.error() << ": " << path;
+                }
+
+                LOG(INFO) << "Adding " << path << " to fs-verity...";
+                auto enabled = enableFsVerity(fd, pkcs7.value());
+                if (!enabled.ok()) {
+                    return Error() << enabled.error() << ": " << path;
+                }
+            }
+
+            new_digests[path] = compos_digest;
+        } else if (it->is_directory()) {
+            // These are fine to ignore
+        } else if (it->is_symlink()) {
+            return Error() << "Rejecting artifacts, symlink at " << path;
+        } else {
+            return Error() << "Rejecting artifacts, unexpected file type for " << path;
+        }
+    }
+    if (ec) {
+        return Error() << "Failed to iterate " << directory_path << ": " << ec.message();
+    }
+
+    // Delete the signature files now that they have served their purpose.  (ART
+    // has no use for them, and their presence could cause verification to fail
+    // on subsequent boots.)
+    for (auto& signature_path : signature_files) {
+        std::filesystem::remove(signature_path, ec);
+        if (ec) {
+            return Error() << "Failed to delete " << signature_path << ": " << ec.message();
+        }
+    }
+
+    return new_digests;
+}
+
+Result<void> addCertToFsVerityKeyring(const std::string& path, const char* keyName) {
+    const char* const argv[] = {kFsVerityInitPath, "--load-extra-key", keyName};
+
+    int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
+    if (fd == -1) {
+        return ErrnoError() << "Failed to open " << path;
+    }
+    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], 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) != 0) {
+        return Error() << kFsVerityInitPath << " exited with " << WEXITSTATUS(status);
+    }
 
     return {};
 }
diff --git a/ondevice-signing/VerityUtils.h b/ondevice-signing/VerityUtils.h
index 1eca5a6..8d8e62c 100644
--- a/ondevice-signing/VerityUtils.h
+++ b/ondevice-signing/VerityUtils.h
@@ -18,8 +18,15 @@
 
 #include <android-base/result.h>
 
-#include "KeymasterSigningKey.h"
+#include "SigningKey.h"
 
-android::base::Result<void> verifyAllFilesInVerity(const std::string& path);
-android::base::Result<void> addFilesToVerityRecursive(const std::string& path,
-                                                      const KeymasterSigningKey& key);
+android::base::Result<void> addCertToFsVerityKeyring(const std::string& path, const char* keyName);
+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);
+
+android::base::Result<std::map<std::string, std::string>>
+verifyAllFilesUsingCompOs(const std::string& path, const std::vector<uint8_t>& compos_key);
diff --git a/ondevice-signing/odsign.rc b/ondevice-signing/odsign.rc
index 044bae7..de09fc0 100644
--- a/ondevice-signing/odsign.rc
+++ b/ondevice-signing/odsign.rc
@@ -2,5 +2,8 @@
     class core
     user root
     group system
-    oneshot
     disabled # does not start with the core class
+
+# Note that odsign is not oneshot, but stopped manually when it exits. This
+# ensures that if odsign crashes during a module update, apexd will detect
+# those crashes and roll back the update.
diff --git a/ondevice-signing/odsign_main.cpp b/ondevice-signing/odsign_main.cpp
index 3baba68..4a7baad 100644
--- a/ondevice-signing/odsign_main.cpp
+++ b/ondevice-signing/odsign_main.cpp
@@ -16,89 +16,143 @@
 
 #include <fcntl.h>
 #include <filesystem>
+#include <fstream>
 #include <iomanip>
 #include <iostream>
+#include <iterator>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/wait.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::GetProperty;
 using android::base::Result;
+using android::base::SetProperty;
 
-const std::string kSigningKeyBlob = "/data/misc/odsign/key.blob";
+using OdsignInfo = ::odsign::proto::OdsignInfo;
+
 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";
+constexpr const char* kOdrefreshPath = "/apex/com.android.art/bin/odrefresh";
+constexpr const char* kCompOsVerifyPath = "/apex/com.android.compos/bin/compos_verify_key";
+constexpr const char* kFsVerityProcPath = "/proc/sys/fs/verity";
+constexpr const char* kKvmDevicePath = "/dev/kvm";
 
-static const char* kFsVerityInitPath = "/system/bin/fsverity_init";
+constexpr bool kForceCompilation = false;
+constexpr bool kUseCompOs = true;
 
-static const bool kForceCompilation = false;
+const std::string kCompOsCert = "/data/misc/odsign/compos_key.cert";
 
-Result<void> addCertToFsVerityKeyring(const std::string& path) {
-    const char* const argv[] = {kFsVerityInitPath, "--load-extra-key", "fsv_ods"};
+const std::string kCompOsCurrentPublicKey =
+    "/data/misc/apexdata/com.android.compos/current/key.pubkey";
+const std::string kCompOsPendingPublicKey =
+    "/data/misc/apexdata/com.android.compos/pending/key.pubkey";
 
-    // NOLINTNEXTLINE(android-cloexec-open): Deliberately not O_CLOEXEC
-    int fd = open(path.c_str(), O_RDONLY);
-    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);
+const std::string kCompOsPendingArtifactsDir = "/data/misc/apexdata/com.android.art/compos-pending";
+
+constexpr const char* kOdsignVerificationDoneProp = "odsign.verification.done";
+constexpr const char* kOdsignKeyDoneProp = "odsign.key.done";
+
+constexpr const char* kOdsignVerificationStatusProp = "odsign.verification.success";
+constexpr const char* kOdsignVerificationStatusValid = "1";
+constexpr const char* kOdsignVerificationStatusError = "0";
+
+constexpr const char* kStopServiceProp = "ctl.stop";
+
+enum class CompOsInstance { kCurrent, kPending };
+
+static std::vector<uint8_t> readBytesFromFile(const std::string& path) {
+    std::string str;
+    android::base::ReadFileToString(path, &str);
+    return std::vector<uint8_t>(str.begin(), str.end());
+}
+
+static bool rename(const std::string& from, const std::string& to) {
+    std::error_code ec;
+    std::filesystem::rename(from, to, ec);
+    if (ec) {
+        LOG(ERROR) << "Can't rename " << from << " to " << to << ": " << ec.message();
+        return false;
+    }
+    return true;
+}
+
+static int removeDirectory(const std::string& directory) {
+    std::error_code ec;
+    auto num_removed = std::filesystem::remove_all(directory, ec);
+    if (ec) {
+        LOG(ERROR) << "Can't remove " << directory << ": " << ec.message();
+        return 0;
     } 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;
+        if (num_removed > 0) {
+            LOG(INFO) << "Removed " << num_removed << " entries from " << directory;
         }
+        return num_removed;
     }
-
-    return {};
 }
 
-Result<KeymasterSigningKey> loadAndVerifyExistingKey() {
-    if (access(kSigningKeyBlob.c_str(), F_OK) < 0) {
-        return ErrnoError() << "Key blob not found: " << kSigningKeyBlob;
-    }
-    return KeymasterSigningKey::loadFromBlobAndVerify(kSigningKeyBlob);
+static bool directoryHasContent(const std::string& directory) {
+    std::error_code ec;
+    return std::filesystem::is_directory(directory, ec) &&
+           !std::filesystem::is_empty(directory, ec);
 }
 
-Result<void> verifyExistingCert(const KeymasterSigningKey& key) {
+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);
+}
+
+art::odrefresh::ExitCode checkArtifacts() {
+    const char* const argv[] = {kOdrefreshPath, "--check"};
+    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();
+}
+
+bool compOsPresent() {
+    return access(kCompOsVerifyPath, X_OK) == 0 && access(kKvmDevicePath, F_OK) == 0;
+}
+
+bool isDebugBuild() {
+    std::string build_type = GetProperty("ro.build.type", "");
+    return build_type == "userdebug" || build_type == "eng";
+}
+
+Result<void> verifyExistingRootCert(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.";
+        return Error() << "Failed to retrieve signing public key: " << trustedPublicKey.error();
     }
 
     auto publicKeyFromExistingCert = extractPublicKeyFromX509(kSigningKeyCert);
@@ -110,114 +164,491 @@
                        << " does not match signing public key.";
     }
 
-    // At this point, we know the cert matches
+    // At this point, we know the cert is for our key; it's unimportant whether it's
+    // actually self-signed.
     return {};
 }
 
-Result<KeymasterSigningKey> createAndPersistKey(const std::string& path) {
-    auto key = KeymasterSigningKey::createNewKey();
+Result<void> createX509RootCert(const SigningKey& key, const std::string& outPath) {
+    auto publicKey = key.getPublicKey();
 
-    if (!key.ok()) {
-        return key.error();
+    if (!publicKey.ok()) {
+        return publicKey.error();
     }
 
-    auto result = key->saveKeyblob(path);
+    auto keySignFunction = [&](const std::string& to_be_signed) { return key.sign(to_be_signed); };
+    return createSelfSignedCertificate(*publicKey, keySignFunction, outPath);
+}
+
+Result<std::vector<uint8_t>> extractRsaPublicKeyFromLeafCert(const SigningKey& key,
+                                                             const std::string& certPath,
+                                                             const std::string& expectedCn) {
+    if (access(certPath.c_str(), F_OK) < 0) {
+        return ErrnoError() << "Certificate not found: " << certPath;
+    }
+    auto trustedPublicKey = key.getPublicKey();
+    if (!trustedPublicKey.ok()) {
+        return Error() << "Failed to retrieve signing public key: " << trustedPublicKey.error();
+    }
+
+    auto existingCertInfo = verifyAndExtractCertInfoFromX509(certPath, trustedPublicKey.value());
+    if (!existingCertInfo.ok()) {
+        return Error() << "Failed to verify certificate at " << certPath << ": "
+                       << existingCertInfo.error();
+    }
+
+    auto& actualCn = existingCertInfo.value().subjectCn;
+    if (actualCn != expectedCn) {
+        return Error() << "CN of existing certificate at " << certPath << " is " << actualCn
+                       << ", should be " << expectedCn;
+    }
+
+    return existingCertInfo.value().subjectRsaPublicKey;
+}
+
+// Attempt to start a CompOS VM for the specified instance to get it to
+// verify ita public key & key blob.
+bool startCompOsAndVerifyKey(CompOsInstance instance) {
+    bool isCurrent = instance == CompOsInstance::kCurrent;
+    const std::string& keyPath = isCurrent ? kCompOsCurrentPublicKey : kCompOsPendingPublicKey;
+    if (access(keyPath.c_str(), R_OK) != 0) {
+        return false;
+    }
+
+    const char* const argv[] = {kCompOsVerifyPath, "--instance", isCurrent ? "current" : "pending"};
+    int result =
+        logwrap_fork_execvp(arraysize(argv), argv, nullptr, false, LOG_ALOG, false, nullptr);
+    if (result == 0) {
+        return true;
+    }
+
+    LOG(ERROR) << kCompOsVerifyPath << " returned " << result;
+    return false;
+}
+
+Result<std::vector<uint8_t>> verifyCompOsKey(const SigningKey& signingKey) {
+    bool verified = false;
+
+    // If a pending key has been generated we don't know if it is the correct
+    // one for the pending CompOS VM, so we need to start it and ask it.
+    if (startCompOsAndVerifyKey(CompOsInstance::kPending)) {
+        verified = true;
+    }
+
+    if (!verified) {
+        // Alternatively if we signed a cert for the key on a previous boot, then we
+        // can use that straight away.
+        auto existing_key =
+            extractRsaPublicKeyFromLeafCert(signingKey, kCompOsCert, kCompOsSubject.commonName);
+        if (existing_key.ok()) {
+            LOG(INFO) << "Found and verified existing CompOs public key certificate: "
+                      << kCompOsCert;
+            return existing_key.value();
+        }
+    }
+
+    // Otherwise, if there is an existing key that we haven't signed yet, then we can sign
+    // it now if CompOS confirms it's OK.
+    if (!verified && startCompOsAndVerifyKey(CompOsInstance::kCurrent)) {
+        verified = true;
+    }
+
+    if (!verified) {
+        return Error() << "No valid CompOs key present.";
+    }
+
+    // If the pending key was verified it will have been promoted to current, so
+    // at this stage if there is a key it will be the current one.
+    auto publicKey = readBytesFromFile(kCompOsCurrentPublicKey);
+    if (publicKey.empty()) {
+        // This shouldn`t really happen.
+        return Error() << "Failed to read CompOs key.";
+    }
+
+    // One way or another we now have a valid public key. Persist a certificate so
+    // we can simplify the checks on subsequent boots.
+
+    auto signFunction = [&](const std::string& to_be_signed) {
+        return signingKey.sign(to_be_signed);
+    };
+    auto certStatus = createLeafCertificate(kCompOsSubject, publicKey, signFunction,
+                                            kSigningKeyCert, kCompOsCert);
+    if (!certStatus.ok()) {
+        return Error() << "Failed to create CompOs cert: " << certStatus.error();
+    }
+
+    LOG(INFO) << "Verified key, wrote new CompOs cert";
+
+    return publicKey;
+}
+
+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() << ": "
+                               << digest.error();
+            }
+            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 key;
+    return verifyDigests(*result, trusted_digests);
 }
 
-bool compileArtifacts(bool force) {
-    const char* const argv[] = {kOdrefreshPath, force ? "--force-compile" : "--compile"};
+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 logwrap_fork_execvp(arraysize(argv), argv, nullptr, false, LOG_ALOG, false, nullptr) ==
-           0;
+    return verifyDigests(*result, trusted_digests);
 }
 
-bool validateArtifacts() {
-    const char* const argv[] = {kOdrefreshPath, "--check"};
+Result<OdsignInfo> getOdsignInfo(const SigningKey& key) {
+    std::string persistedSignature;
+    OdsignInfo odsignInfo;
 
-    return logwrap_fork_execvp(arraysize(argv), argv, nullptr, false, LOG_ALOG, false, nullptr) ==
-           0;
+    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 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 signInfo.error();
+    }
+    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 integrityStatus.error();
+    }
+
+    return {};
+}
+
+Result<std::vector<uint8_t>> addCompOsCertToFsVerityKeyring(const SigningKey& signingKey) {
+    auto publicKey = verifyCompOsKey(signingKey);
+    if (!publicKey.ok()) {
+        return publicKey.error();
+    }
+
+    auto cert_add_result = addCertToFsVerityKeyring(kCompOsCert, "fsv_compos");
+    if (!cert_add_result.ok()) {
+        // Best efforts only - nothing we can do if deletion fails.
+        unlink(kCompOsCert.c_str());
+        return Error() << "Failed to add CompOs certificate to fs-verity keyring: "
+                       << cert_add_result.error();
+    }
+
+    return publicKey;
+}
+
+art::odrefresh::ExitCode checkCompOsPendingArtifacts(const std::vector<uint8_t>& compos_key,
+                                                     const SigningKey& signingKey,
+                                                     bool* digests_verified) {
+    if (!directoryHasContent(kCompOsPendingArtifactsDir)) {
+        return art::odrefresh::ExitCode::kCompilationRequired;
+    }
+
+    // CompOs has generated some artifacts that may, or may not, match the
+    // current state.  But if there are already valid artifacts present the
+    // CompOs ones are redundant.
+    art::odrefresh::ExitCode odrefresh_status = checkArtifacts();
+    if (odrefresh_status != art::odrefresh::ExitCode::kCompilationRequired) {
+        if (odrefresh_status == art::odrefresh::ExitCode::kOkay) {
+            LOG(INFO) << "Current artifacts are OK, deleting pending artifacts";
+            removeDirectory(kCompOsPendingArtifactsDir);
+        }
+        return odrefresh_status;
+    }
+
+    // No useful current artifacts, lets see if the CompOs ones are ok
+    LOG(INFO) << "Current artifacts are out of date, switching to pending artifacts";
+    removeDirectory(kArtArtifactsDir);
+    if (!rename(kCompOsPendingArtifactsDir, kArtArtifactsDir)) {
+        removeDirectory(kCompOsPendingArtifactsDir);
+        return art::odrefresh::ExitCode::kCompilationRequired;
+    }
+
+    // TODO: Make sure that we check here that the contents of the artifacts
+    // correspond to their filenames (and extensions) - the CompOs signatures
+    // can't guarantee that.
+    odrefresh_status = checkArtifacts();
+    if (odrefresh_status != art::odrefresh::ExitCode::kOkay) {
+        LOG(WARNING) << "Pending artifacts are not OK";
+        return odrefresh_status;
+    }
+
+    // The artifacts appear to be up to date - but we haven't
+    // verified that they are genuine yet.
+    Result<std::map<std::string, std::string>> digests =
+        verifyAllFilesUsingCompOs(kArtArtifactsDir, compos_key);
+
+    if (digests.ok()) {
+        auto persisted = persistDigests(digests.value(), signingKey);
+
+        // Having signed the digests (or failed to), we're done with the signing key.
+        SetProperty(kOdsignKeyDoneProp, "1");
+
+        if (persisted.ok()) {
+            *digests_verified = true;
+            LOG(INFO) << "Pending artifacts successfully verified.";
+            return art::odrefresh::ExitCode::kOkay;
+        } else {
+            LOG(WARNING) << persisted.error();
+        }
+    } else {
+        LOG(WARNING) << "Pending artifact verification failed: " << digests.error();
+    }
+
+    // We can't use the existing artifacts, so we will need to generate new
+    // ones.
+    removeDirectory(kArtArtifactsDir);
+    return art::odrefresh::ExitCode::kCompilationRequired;
 }
 
 int main(int /* argc */, char** /* argv */) {
-    auto removeArtifacts = []() {
-        std::error_code ec;
-        auto num_removed = std::filesystem::remove_all(kArtArtifactsDir, ec);
-        if (ec) {
-            // TODO can't remove artifacts, signal Zygote shouldn't use them
-            LOG(ERROR) << "Can't remove " << kArtArtifactsDir << ": " << ec.message();
-        } else {
-            LOG(INFO) << "Removed " << num_removed << " entries from " << kArtArtifactsDir;
-        }
+    auto errorScopeGuard = []() {
+        // In case we hit any error, remove the artifacts and tell Zygote not to use
+        // anything
+        removeDirectory(kArtArtifactsDir);
+        removeDirectory(kCompOsPendingArtifactsDir);
+        // 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(kOdsignVerificationStatusProp, kOdsignVerificationStatusError);
+        SetProperty(kOdsignVerificationDoneProp, "1");
+        // Tell init it shouldn't try to restart us - see odsign.rc
+        SetProperty(kStopServiceProp, "odsign");
     };
-    // Make sure we delete the artifacts in all early (error) exit paths
-    auto scope_guard = android::base::make_scope_guard(removeArtifacts);
+    auto scope_guard = android::base::make_scope_guard(errorScopeGuard);
 
-    auto key = loadAndVerifyExistingKey();
-    if (!key.ok()) {
-        LOG(WARNING) << key.error().message();
-
-        key = createAndPersistKey(kSigningKeyBlob);
-        if (!key.ok()) {
-            LOG(ERROR) << "Failed to create or persist new key: " << key.error().message();
-            return -1;
-        }
-    } else {
-        LOG(INFO) << "Found and verified existing key: " << kSigningKeyBlob;
+    if (!android::base::GetBoolProperty("ro.apex.updatable", false)) {
+        LOG(INFO) << "Device doesn't support updatable APEX, exiting.";
+        return 0;
     }
 
-    auto existing_cert = verifyExistingCert(key.value());
-    if (!existing_cert.ok()) {
-        LOG(WARNING) << existing_cert.error().message();
+    auto keystoreResult = KeystoreKey::getInstance();
+    if (!keystoreResult.ok()) {
+        LOG(ERROR) << "Could not create keystore key: " << keystoreResult.error();
+        return -1;
+    }
+    SigningKey* key = keystoreResult.value();
 
-        // Try to create a new cert
-        auto new_cert = key->createX509Cert(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
+    bool supportsFsVerity = access(kFsVerityProcPath, F_OK) == 0;
+    if (!supportsFsVerity) {
+        LOG(INFO) << "Device doesn't support fsverity. Falling back to full verification.";
+    }
+
+    bool useCompOs = kUseCompOs && supportsFsVerity && compOsPresent() && isDebugBuild();
+
+    if (supportsFsVerity) {
+        auto existing_cert = verifyExistingRootCert(*key);
+        if (!existing_cert.ok()) {
+            LOG(WARNING) << existing_cert.error();
+
+            // Try to create a new cert
+            auto new_cert = createX509RootCert(*key, kSigningKeyCert);
+            if (!new_cert.ok()) {
+                LOG(ERROR) << "Failed to create X509 certificate: " << new_cert.error();
+                // 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, "fsv_ods");
+        if (!cert_add_result.ok()) {
+            LOG(ERROR) << "Failed to add certificate to fs-verity keyring: "
+                       << cert_add_result.error();
             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();
+
+    art::odrefresh::ExitCode odrefresh_status = art::odrefresh::ExitCode::kCompilationRequired;
+    bool digests_verified = false;
+
+    if (useCompOs) {
+        auto compos_key = addCompOsCertToFsVerityKeyring(*key);
+        if (!compos_key.ok()) {
+            LOG(WARNING) << compos_key.error();
+        } else {
+            odrefresh_status =
+                checkCompOsPendingArtifacts(compos_key.value(), *key, &digests_verified);
+        }
+    }
+
+    if (odrefresh_status == art::odrefresh::ExitCode::kCompilationRequired) {
+        odrefresh_status = compileArtifacts(kForceCompilation);
+    }
+    if (odrefresh_status == art::odrefresh::ExitCode::kOkay) {
+        LOG(INFO) << "odrefresh said artifacts are VALID";
+        if (!digests_verified) {
+            // 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();
+                    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();
+            return -1;
+        }
+        auto persistStatus = persistDigests(*digests, *key);
+        if (!persistStatus.ok()) {
+            LOG(ERROR) << persistStatus.error();
+            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;
     }
 
-    auto verityStatus = verifyAllFilesInVerity(kArtArtifactsDir);
-    if (!verityStatus.ok()) {
-        LOG(WARNING) << verityStatus.error().message() << ", removing " << kArtArtifactsDir;
-        removeArtifacts();
-    }
-
-    bool artifactsValid = validateArtifacts();
-
-    if (!artifactsValid || kForceCompilation) {
-        removeArtifacts();
-
-        LOG(INFO) << "Starting compilation... ";
-        bool ret = compileArtifacts(kForceCompilation);
-        LOG(INFO) << "Compilation done, returned " << ret;
-
-        verityStatus = addFilesToVerityRecursive(kArtArtifactsDir, key.value());
-
-        if (!verityStatus.ok()) {
-            LOG(ERROR) << "Failed to add " << verityStatus.error().message();
-            return -1;
-        }
-    }
-
-    // TODO we want to make sure Zygote only picks up the artifacts if we deemed
-    // everything was ok here. We could use a sysprop, or some other mechanism?
     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(kOdsignVerificationStatusProp, kOdsignVerificationStatusValid);
+    SetProperty(kOdsignVerificationDoneProp, "1");
+
+    // Tell init it shouldn't try to restart us - see odsign.rc
+    SetProperty(kStopServiceProp, "odsign");
     return 0;
 }
diff --git a/ondevice-signing/proto/Android.bp b/ondevice-signing/proto/Android.bp
new file mode 100644
index 0000000..c042b8e
--- /dev/null
+++ b/ondevice-signing/proto/Android.bp
@@ -0,0 +1,43 @@
+/*
+ * 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_static {
+    name: "lib_odsign_proto",
+    host_supported: true,
+    proto: {
+        export_proto_headers: true,
+        type: "lite",
+    },
+    srcs: ["odsign_info.proto"],
+}
+
+cc_library_static {
+    name: "lib_compos_proto",
+    host_supported: true,
+    proto: {
+        export_proto_headers: true,
+        type: "lite",
+    },
+    srcs: ["compos_signature.proto"],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.compos",
+    ],
+}
diff --git a/ondevice-signing/proto/compos_signature.proto b/ondevice-signing/proto/compos_signature.proto
new file mode 100644
index 0000000..2f7d09f
--- /dev/null
+++ b/ondevice-signing/proto/compos_signature.proto
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package compos.proto;
+
+// Data provided by CompOS to allow validation of a file it generated.
+message Signature {
+    // The fs-verity digest (which is derived from the root hash of
+    // the Merkle tree) of the file contents.
+    bytes digest = 1;
+
+    // Signature of a fsverity_formatted_digest structure containing
+    // the digest, signed using CompOS's private key.
+    bytes signature = 2;
+}
diff --git a/keystore/binder/android/security/keymaster/OperationResult.aidl b/ondevice-signing/proto/odsign_info.proto
similarity index 73%
rename from keystore/binder/android/security/keymaster/OperationResult.aidl
rename 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
index d3f06fe..aac4878 100644
--- a/provisioner/Android.bp
+++ b/provisioner/Android.bp
@@ -43,11 +43,23 @@
     },
 }
 
-java_binary {
-    name: "provisioner_cli",
-    wrapper: "provisioner_cli",
-    srcs: ["src/com/android/commands/provisioner/**/*.java"],
+cc_binary {
+    name: "rkp_factory_extraction_tool",
+    vendor: true,
+    srcs: ["rkp_factory_extraction_tool.cpp"],
+    shared_libs: [
+        "android.hardware.security.keymint-V1-ndk",
+        "libbinder",
+        "libbinder_ndk",
+        "libcrypto",
+        "liblog",
+    ],
     static_libs: [
-        "android.security.provisioner-java",
+        "libbase",
+        "libcppbor_external",
+        "libcppcose_rkp",
+        "libgflags",
+        "libjsoncpp",
+        "libkeymint_remote_prov_support",
     ],
 }
diff --git a/provisioner/provisioner_cli b/provisioner/provisioner_cli
deleted file mode 100755
index 7b53d6e..0000000
--- a/provisioner/provisioner_cli
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/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..2e59dbd
--- /dev/null
+++ b/provisioner/rkp_factory_extraction_tool.cpp
@@ -0,0 +1,190 @@
+/*
+ * 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 <gflags/gflags.h>
+#include <keymaster/cppcose/cppcose.h>
+#include <openssl/base64.h>
+#include <remote_prov/remote_prov_utils.h>
+#include <sys/random.h>
+
+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 aidl::android::hardware::security::keymint::remote_prov::generateEekChain;
+using aidl::android::hardware::security::keymint::remote_prov::getProdEekChain;
+using aidl::android::hardware::security::keymint::remote_prov::jsonEncodeCsrWithBuild;
+
+using namespace cppbor;
+using namespace cppcose;
+
+DEFINE_bool(test_mode, false, "If enabled, a fake EEK key/cert are used.");
+
+DEFINE_string(output_format, "csr", "How to format the output. Defaults to 'csr'.");
+
+namespace {
+
+// Various supported --output_format values.
+constexpr std::string_view kBinaryCsrOutput = "csr";     // Just the raw csr as binary
+constexpr std::string_view kBuildPlusCsr = "build+csr";  // Text-encoded (JSON) build
+                                                         // fingerprint plus CSR.
+
+constexpr size_t kChallengeSize = 16;
+
+std::string toBase64(const std::vector<uint8_t>& buffer) {
+    size_t base64Length;
+    int rc = EVP_EncodedLength(&base64Length, buffer.size());
+    if (!rc) {
+        std::cerr << "Error getting base64 length. Size overflow?" << std::endl;
+        exit(-1);
+    }
+
+    std::string base64(base64Length, ' ');
+    rc = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(base64.data()), buffer.data(), buffer.size());
+    ++rc;  // Account for NUL, which BoringSSL does not for some reason.
+    if (rc != base64Length) {
+        std::cerr << "Error writing base64. Expected " << base64Length
+                  << " bytes to be written, but " << rc << " bytes were actually written."
+                  << std::endl;
+        exit(-1);
+    }
+    return base64;
+}
+
+std::vector<uint8_t> generateChallenge() {
+    std::vector<uint8_t> challenge(kChallengeSize);
+
+    ssize_t bytesRemaining = static_cast<ssize_t>(challenge.size());
+    uint8_t* writePtr = challenge.data();
+    while (bytesRemaining > 0) {
+        int bytesRead = getrandom(writePtr, bytesRemaining, /*flags=*/0);
+        if (bytesRead < 0 && errno != EINTR) {
+            std::cerr << errno << ": " << strerror(errno) << std::endl;
+            exit(-1);
+        }
+        bytesRemaining -= bytesRead;
+        writePtr += bytesRead;
+    }
+
+    return challenge;
+}
+
+Array composeCertificateRequest(const ProtectedData& protectedData,
+                                const DeviceInfo& verifiedDeviceInfo,
+                                const std::vector<uint8_t>& challenge,
+                                const std::vector<uint8_t>& keysToSignMac) {
+    Array macedKeysToSign = Array()
+                                .add(std::vector<uint8_t>(0))  // empty protected headers as bstr
+                                .add(Map())                    // empty unprotected headers
+                                .add(Null())                   // nil for the payload
+                                .add(keysToSignMac);           // MAC as returned from the HAL
+
+    Array deviceInfo =
+        Array().add(EncodedItem(verifiedDeviceInfo.deviceInfo)).add(Map());  // Empty device info
+
+    Array certificateRequest = Array()
+                                   .add(std::move(deviceInfo))
+                                   .add(challenge)
+                                   .add(EncodedItem(protectedData.protectedData))
+                                   .add(std::move(macedKeysToSign));
+    return certificateRequest;
+}
+
+std::vector<uint8_t> getEekChain() {
+    if (FLAGS_test_mode) {
+        const std::vector<uint8_t> kFakeEekId = {'f', 'a', 'k', 'e', 0};
+        auto eekOrErr = generateEekChain(3 /* chainlength */, kFakeEekId);
+        if (!eekOrErr) {
+            std::cerr << "Failed to generate test EEK somehow: " << eekOrErr.message() << std::endl;
+            exit(-1);
+        }
+        auto [eek, pubkey, privkey] = eekOrErr.moveValue();
+        std::cout << "EEK raw keypair:" << std::endl;
+        std::cout << "  pub:  " << toBase64(pubkey) << std::endl;
+        std::cout << "  priv: " << toBase64(privkey) << std::endl;
+        return eek;
+    }
+
+    return getProdEekChain();
+}
+
+void writeOutput(const Array& csr) {
+    if (FLAGS_output_format == kBinaryCsrOutput) {
+        auto bytes = csr.encode();
+        std::copy(bytes.begin(), bytes.end(), std::ostream_iterator<char>(std::cout));
+    } else if (FLAGS_output_format == kBuildPlusCsr) {
+        auto [json, error] = jsonEncodeCsrWithBuild(csr);
+        if (!error.empty()) {
+            std::cerr << "Error JSON encoding the output: " << error;
+            exit(1);
+        }
+        std::cout << json << std::endl;
+    } else {
+        std::cerr << "Unexpected output_format '" << FLAGS_output_format << "'" << std::endl;
+        std::cerr << "Valid formats:" << std::endl;
+        std::cerr << "  " << kBinaryCsrOutput << std::endl;
+        std::cerr << "  " << kBuildPlusCsr << std::endl;
+        exit(1);
+    }
+}
+
+// Callback for AServiceManager_forEachDeclaredInstance that writes out a CSR
+// for every IRemotelyProvisionedComponent.
+void getCsrForInstance(const char* name, void* /*context*/) {
+    const std::vector<uint8_t> challenge = generateChallenge();
+
+    auto fullName = std::string(IRemotelyProvisionedComponent::descriptor) + "/" + name;
+    AIBinder* rkpAiBinder = AServiceManager_getService(fullName.c_str());
+    ::ndk::SpAIBinder rkp_binder(rkpAiBinder);
+    auto rkp_service = IRemotelyProvisionedComponent::fromBinder(rkp_binder);
+    if (!rkp_service) {
+        std::cerr << "Unable to get binder object for '" << fullName << "', skipping.";
+        return;
+    }
+
+    std::vector<uint8_t> keysToSignMac;
+    std::vector<MacedPublicKey> emptyKeys;
+    DeviceInfo verifiedDeviceInfo;
+    ProtectedData protectedData;
+    ::ndk::ScopedAStatus status = rkp_service->generateCertificateRequest(
+        FLAGS_test_mode, emptyKeys, getEekChain(), challenge, &verifiedDeviceInfo, &protectedData,
+        &keysToSignMac);
+    if (!status.isOk()) {
+        std::cerr << "Bundle extraction failed for '" << fullName
+                  << "'. Error code: " << status.getServiceSpecificError() << "." << std::endl;
+        exit(-1);
+    }
+    auto request =
+        composeCertificateRequest(protectedData, verifiedDeviceInfo, challenge, keysToSignMac);
+    writeOutput(request);
+}
+
+}  // namespace
+
+int main(int argc, char** argv) {
+    gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags=*/true);
+
+    AServiceManager_forEachDeclaredInstance(IRemotelyProvisionedComponent::descriptor,
+                                            /*context=*/nullptr, getCsrForInstance);
+
+    return 0;
+}
diff --git a/provisioner/src/com/android/commands/provisioner/Cli.java b/provisioner/src/com/android/commands/provisioner/Cli.java
deleted file mode 100644
index 62afdac..0000000
--- a/provisioner/src/com/android/commands/provisioner/Cli.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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>]");
-    }
-}
